new的过程,以及__proto__与prototype的关系

说起new,要先说原型链。
机制就是指对象的一个内部链接引用另外一个对象。
如果在第一个对象上没有找到需要的属性或者方法的引用,引擎就会继续在[[prototype]]关联的对象上继续查找,同理,如果后者中也没有找到需要的引用就会继续查找他的[[prototype]].以此类推,这一系列对象的链接被称为“原型链”。
来看看我们再熟悉不过的代码,通过new运算符从构造器中得到一个对象。

function Person(name) {
    this.name = name;
}
Person.prototype.getName = function() {
    return this.name;
}
var a = new Person("liwen");
console.log(a.name); //liwen

下面,通过这段代码来理解new运算的过程

function Person(name) {
   this.name = name;
}
Person.prototype.getName = function() {
   return this.name;
}
var objectFactory = function() {
   //从Object.prototype上克隆一个空的对象,因为JavaScript中所有对象的根对象是Object.prototype。
   var obj = new Object();
   //取得外部传入的构造器,此例子是person
   var Constructor = [].shift.call(arguments);        
   obj.__proto__ = Constructor.prototype;//指向正确的原型(即Person.prototype),默认是Object.prototype
   //借用外部传入的构造器给OBJ设置属性
   var ret = Constructor.apply(obj, arguments);
   //确保构造器总会返回一个对象
   return typeof ret === 'object' ? ret : obj;
}
var a = objectFactory(Person, "liwen");  //等于 var a = new Person("liwen")
console.log(a.name)//liwen

上面实现的objectFactory函数和new 产生一样的结果。
代码中,使用了obj.__proto__ = Constructor.prototype;来改变obj原型的指向。

每个对象都会在其内部初始化一个属性__proto__。又回到了开头的那句话,当我们访问一个对象的属性时。如果没有找到,就通过这个内部链接__proto__引用另外一个对象继续找。
如果没有找到,引擎就会继续在__proto__关联的对象上通过他的__proto__继续查找,一直到根对象object为止,这一系列对象的链接被称为“原型链”。
__proto__就是用来记录链接的内部私有属性。这是原型链的本质,而prototype是一个开发接口

而new的步骤,也是创建一个obj,并把obj的__proto__指向要继承对象的原型(Constructor.prototype即Person.prototype)。并返回obj,实现了new。

欢迎分享本文,转载请保留出处:前端ABC » new的过程,以及__proto__与prototype的关系

分享到:更多 ()

发表评论 0