Object.create与new区别
function A() { this.name = 'abc'; } A.prototype.a = 'a'; A.prototype.showName = function () { return this.name; } var a1 = new A(); var a2 = Object.create(A.prototype);
从这个例子可以看出,a2只继承了A原型的属性和方法,
a1 是构造函数 A 的实例,继承了构造函数 A 的属性 name及其原型属性和方法。
所以Object.create()与new的区别在于Object.create只继承原型属性和方法,继承不了构造函数的属性和方法。而通过new操作符创建的实例,既可以继承原型的属性和方法,又可以继承构造函数的属性和方法。
Object.create()原理
Object.create = function (o) { var F = function () {}; F.prototype = o; return new F(); };
new原理
- 创建一个空对象obj;
- 将该空对象的原型设置为构造函数的原型,即obj.proto = func.prototype;
- 以该对象为上下文执行构造函数,即func.call(obj);
- 返回该对象,即return obj。
var newFunc = function ( func ){ var obj = Object.creat(func.prototype); var ret = func.call(obj); if(typeof ret === 'object') { return ret; } else { return obj; } }
从两者的具体实现可以看出:Object.create没有执行步骤三,所以继承不了构造函数的属性和方法。
继承
a1.__proto__ == a2.__proto__; // true a1.__proto__ == A.prototype; // true a2.__proto__ == A.prototype; // true a1.__proto__.__proto__ == Object.prototype; // true a1.__proto__.__proto__.__proto__ == null; // true
比较组合继承与寄生组合继承
组合继承
在子类构造函数中调用父类构造函数,并把父类实例化对象赋给子类原型。
function Parent(name, age) { this.name = name; this.age = age; } Parent.prototype.showName = function () { return this.name; } function Child(name, age) { Parent.call(this, name, age); // 这里调用一次父类构造函数 } Child.prototype = new Parent(); // 这里也会调用父类构造函数 Child.prototype.constructor = Child;
这种方式在构造函数继承时执行了一遍父类构造函数,又在实现子类原型继承时调用了一遍父类的构造函数。因此父类构造函数调用了两遍,所以这不是最优化的继承方式。
寄生组合继承
function Parent(name, age) { this.name = name; this.age = age; } Parent.prototype.showName = function () { return this.name; } function Child(name, age) { Parent.call(this, name, age); // 这里调用一次父类构造函数 } Child.prototype = Object.create(Parent.prototype); // 这里避免了调用父类构造函数 Child.prototype.constructor = Child;
到此这篇关于浅谈js中Object.create()与new的具体实现与区别的文章就介绍到这了,更多相关Object.create()与new区别内容请搜索阿兔在线工具以前的文章或继续浏览下面的相关文章希望大家以后多多支持阿兔在线工具!