javascript – __proto__和原型差异

前端之家收集整理的这篇文章主要介绍了javascript – __proto__和原型差异前端之家小编觉得挺不错的,现在分享给大家,也给大家做个参考。
参见英文答案 > __proto__ VS. prototype in JavaScript25个
据我所知,函数应该从其原型对象继承属性,可以使用.prototype或__proto__属性访问它们.
//my prototype Object
var myObj = {
    a: 1,b: 2
};

var myFunc = function () {};

// setting function's `prototype` property
myFunc.prototype = myObj;
alert(myFunc.a);
//returns undefined (Why???) I was expecting 1

但当我尝试以下,

//setting function __proto__ property
myFunc.__proto__ = myObj;
//returns 1
alert(myFunc.a);

那么为什么当我设置myFunc .__ proto__而不是我设置myFunc.prototype时它会起作用?

我确实参考了__proto__ VS. prototype in JavaScript,但无法弄清楚.

解决方法

__proto__

您实际上可以使用__proto__访问对象的内部[[Prototype]]属性.您可以将[[Prototype]]视为继承层次结构中当前对象的实际父级.

原型

当在(构造函数)函数对象上设置时,这是一个特殊属性,用于为从构造函数创建的实例建立继承链.例如,

function Foo() {}
Foo.prototype = {a: 1};

现在,当您创建Foo类型的新对象时,新创建的对象的内部[[Prototype]]属性将引用Foo.prototype对象.你可以这样确认一下

console.assert((new Foo()).__proto__ === Foo.prototype);

在你的情况下,

myFunc.prototype = myObj;

您正在函数对象上创建一个prototype属性,这只有在使用此函数创建新对象时才会使用(构造函数).您可能希望将其视为新对象的模板.因此,当你执行myFunc.a时,JS引擎会尝试在原型链中找到myFunc及其父项,并且它找不到它,这就是它返回undefined的原因.

但是,当你这样做的时候

myFunc.__proto__ = myObj;

您正在将原型链中的myFunc的父级设置为myObj.因此,JS引擎首先尝试在myFunc对象中找到一个,而它不在那里.所以,它试图在它的直接父母中找到它,这是myObj.这就是为什么它在这种情况下返回1.

注意:您可以使用以下函数更好地理解原型链

function printPrototypeChain(object) {
    while (object !== null) {
        console.log(object);
        object = Object.getPrototypeOf(object);
    }
}

现在,让我们在将对象设置为函数对象的prototype属性时打印原型链.

function myFunc() {}
myFunc.prototype = {
    a: 1,b: 2
};
printPrototypeChain(myFunc);

输出将是

[Function: myFunc]
[Function: Empty]
{}

这些对象都没有定义,因此返回undefined.但是,在这种情况下,

function myFunc() {}
myFunc.__proto__ = {
    a: 1,b: 2
};
printPrototypeChain(myFunc);

原型链变成这样

[Function: myFunc]
{ a: 1,b: 2 }
{}

和a在myFunc的直接父母中找到.因此,返回相应的值1.

注意:不要在实际代码中使用__proto__,因为它仅为了向后兼容性而保留在最新版本的JavaScript规范中.了解更多信息here.请改用Object.getPrototypeOfObject.setPrototypeOf.

猜你在找的JavaScript相关文章