我很擅长使用object.create而不是经典的js方式来实现原型继承。
在Chrome中,至少我很惊讶地看到以下代码:
var baseObject = {
test : function(){
console.log('Child');
}
}
var newObject = Object.create(baseObject);
newObject.test = function(){
console.log('Parent');
this.__proto__.test();
}
console.log(newObject);
newObject.test();
生成此内容(模拟Web工具中的输出):
Object {test: function, test: function}
test: function (){
__proto__: Object
test: function (){
__proto__: Object
Parent
Child
所以你看到它不是设置原型而只是“__proto__”,我认为它在使用时不鼓励。您可以看到,在我的代码中,我能够正确地继承并调用父对象,但只能使用“__proto__”。使用“prototype”会导致错误(未定义)。
这里发生了什么?我认为object.create会设置“原型”,因为这是标准(或者我假设)。为什么要填充并让我使用“__proto __”
答案 0 :(得分:5)
不鼓励使用__proto__
设置原型继承,因为它不符合标准。这并不意味着您不能使用Object.create()
来创建具有特定原型对象的新对象。
默认情况下,对象没有.prototype
属性。你混淆了一个函数的.prototype
对象。
所以,如果我有这样的功能:
function Foo() {
}
该Foo
函数对象具有.prototype
属性,该属性引用一个对象,该对象将用作作为构造函数调用时创建的任何对象的__proto__
。
var f = new Foo();
所以现在f
是原型链中Foo.prototype
的对象。您可以使用Object.getPrototypeOf()
;
Object.getPrototypeOf(f) === Foo.prototype; // true
Object.create
给你的是能够设置相同的原型链,但不使用构造函数。所以这就等同了。
var f2 = Object.create(Foo.prototype);
现在我们有一个对象设置方式与原始f
对象相同。
Object.getPrototypeOf(f2) === Foo.prototype; // true
Object.getPrototypeOf(f2) === Object.getPrototypeOf(f); // true
所以这只是一种不同的方式来做最终相同的事情。对象与其原型链之间的关系是内部关系。非标准__proto__
只是暴露了这种关系。
答案 1 :(得分:0)
实例的__proto__
属性应与构造函数的 prototype
属性相同。
创建对象时,其
__proto__
属性设置为引用与其内部[[Prototype]]
相同的对象(即其构造函数的prototype
对象)。为__proto__
分配新值也会更改内部[[Prototype]]
属性的值,除非对象是不可扩展的。
答案 2 :(得分:0)
Object.create()
设置该特定对象实例的原型。 prototype
是构造函数的一个属性,它是使用new
运算符和该构造函数创建的每个实例的自动分配为[[Prototype]]的对象。
__proto__
是访问特定实例的[[Prototype]]的非标准方式。您也可以拨打Object.getPrototypeOf(this)以获取访问原型的标准方法。