JS中new运算符详解

JS中new运算符和原型链继承

  看下面的这些东西之前,先好好看看高程的第六章面向对象部分!里面提到了很多基本概念,比如:

  1. 只要创建了一个新函数,就会根据一组特定的规则为该函数创建一个prototype属性,这个属性指向函数的原型对象。

  2. 对原型所做的修改,能够立即在所有实例中得到反映。

  因为new运算符会返回一个指向构造器函数原型的对象,所以通常情况下this就指向返回的这个对象。

  其中new运算符创建对象的过程,实际上就是:

  1. 先克隆Object.prototype对象,得到一个空对象,并把它的prototype属性指向构造器函数的原型对象
  2. 将构造函数的作用域赋给新对象(因此this就指向了这个新对象)
  3. 执行构造函数中的代码
  4. 返回新对象

  在Chrome和Firefox等向外暴露了对象proto属性的浏览器下,我们可以通过下面这段代码理解new运算的过程:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
function Person(name){
this.name=name;
};

Person.prototype.getName=function(){
return this.name;
};
var objectFactory=function(){
var obj=new Object(), //1. 先克隆Object.prototype对象,得到一个空对象
Constructor=[].shift.call(arguments); //把第一个参数赋给Constructor变量
obj.__proto__=Constructor.prototype; //1.指向正确的原型
var ret=Constructor.apply(obj,arguments); //2. 将构造函数的作用域赋给新对象+3. 执行构造函数中的代码
return typeof ret === "object" ? ret : obj; //4. 返回新对象
};

var a=objectFactory(Person,"sven");

console.log(a.name);//sven
console.log(a.getName());//sven
console.log(Object.getPrototypeOf(a) === Person.prototype);//true

  然后我们就能理解构造器模式是如何创建对象的了:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
function Point(x=10,y=6){
this.x=x;
this.y=y;
}
Point.prototype.z=20;
Point.prototype.getX=function(){
alert(this.x);//不要忘了这里的this也是动态绑定的
}

var p=new Point();//此时Point函数里的this动态绑定到p对象上,都是给p加的x,y属性

p.getX(); //10 this绑定到p上,相当于alert(p.x)
alert(p.__proto__.x); //undefined
p.__proto__.getX() //undefiend this绑定到p的原型对象上也就是构造器原型对象上,当然没有x啦
alert(p.z); //20 虽然p对象本身没有z属性,但如果对象无法响应某个请求,它会把这个请求委托给它的构造器的原型

相关理解图示:原型继承示意图

文章目录
  1. 1. JS中new运算符和原型链继承
,