gpt4 book ai didi

javascript - 当通过 Object.setPrototypeOf() 添加函数原型(prototype)的属性时,对象为空

转载 作者:行者123 更新时间:2023-12-02 12:42:37 24 4
gpt4 key购买 nike

让我们考虑以下代码,

let f = function () {
this.a = 1;
this.b = 2;
}

let o = new f();
f.prototype.c = 3;
console.log(Object.getPrototypeOf(o));

打印

[object Object] { c: 3 }

但是如果我使用 setPrototypeOf 而不是 f.prototype.c,则该对象为空。

let f = function () {
this.a = 1;
this.b = 2;
}

let o = new f();
Object.setPrototypeOf(f, {c: 3});
console.log(Object.getPrototypeOf(o));

打印

[object Object] { ... }

但是如果我使用

let f = function () {
this.a = 1;
this.b = 2;
}

let o = new f();
Object.setPrototypeOf(f, {c: 3});
console.log(Object.getPrototypeOf(f));

打印

[object Object] { c: 3 }

简而言之,问题是,当使用 Object.setPrototypeOf(o) 时,Object 打印为空,当使用 Object.setPrototypeOf(f) 时,对象会打印添加的属性。当使用 f.prototype.c = 3 设置原型(prototype)时,两个对象都可以访问它原型(prototype)和函数原型(prototype)。

最佳答案

当你Object.setPrototypeOf(f, ... )时,链实际上是3长:

o 的原型(prototype)是 ff 的原型(prototype)是 {c:3}

所以你的例子并不等同:

1)在第一个示例中,您将属性 c 直接添加到 f 实例将使用的原型(prototype)中,因此 o 的原型(prototype)包含 c 因为 fo 的构造函数。

在最后两个示例中,您将 c 添加到 f 的原型(prototype)中,因此创建了原型(prototype) f。请记住,函数也只是对象,并且您正在设置用作构造函数的函数的原型(prototype)。因此,o 的原型(prototype)包含 f 的原型(prototype),而 f 的原型(prototype)又包含 c

2)在第二个示例中,您 getPrototypeOf() o。在第三个中,您 getPrototypeOf() f。因此,只有第三个示例再次显示 c

3)如果您检查 chrome 中的元素,您会看到第二个示例的构造函数是 f,因为您询问 o 的原型(prototype)。

在第三个示例中,您将看到构造函数是 Object,因为您询问 f 的原型(prototype),该原型(prototype)已设置为对象 { c} 并跳过从 of 的原型(prototype)。

PS:我知道这可能是一个令人困惑的解释。

PPS:如果你想要继承,请坚持 child.prototype = Object.create(parent.prototype ); child.constructor = child; 或 ES6 class class child extendsparent 当它可以被使用时,对我个人来说造成的困惑最少。

var first = function first() {
this.value = 'first function';
};
// before .prototype.extra, first inherist from Function.
console.log( 'constructor of first before:', first.constructor );
first.prototype.extra = 'implemented with .prototype.extra';
// after .prototype.extra, first still inherits from Function, we did not change anything to first itself.
console.log( 'constructor of first after:', first.constructor );
// When first is used as a prototype, the instances will get "extra".
// Aka, everything that inherist from first.
var first_instance = new first();
console.log( 'extra on instance of first:', first_instance.extra );
// f itself does NOT have the extra property, only instances of first do.
console.log( 'extra on first itself:', first.extra );
console.log( '------' );
var second = function second() {
this.value = 'second function';
};
// before setPrototypeOf, second inherist from Function, like above.
console.log( 'constructor of second before:', second.constructor );
Object.setPrototypeOf( second, { extra: 'implemented with .setPrototypeOf()' });
// after setPrototypeOf, second inherist from Object, we broke the default inheritance chain.
console.log( 'constructor of second after:', second.constructor );
// BY doing this, we effectively turned second into an object.
// It no longer is a function, so we cannot use function methods like .call() or .apply()
console.log( 'second is object, not function: function.apply', second.apply );
console.log( 'second is object, not function: object.hasOwnProperty', second.hasOwnProperty );
// When second is used as a prototype, the instances will not get "extra".
var second_instance = new second();
console.log( 'extra on instance of second:', second_instance.extra );
// second itself Does have the extra property, sine we assigned it on the prototype used by second. not when second is used as the prototype.
console.log( 'extra on second itself:', second.extra );

关于javascript - 当通过 Object.setPrototypeOf() 添加函数原型(prototype)的属性时,对象为空,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/59878947/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com