Object.getPrototypeOf(x)和x.constructor.prototype之间的区别

Difference between Object.getPrototypeOf(x) and x.constructor.prototype?

本文关键字:之间 prototype 区别 constructor getPrototypeOf Object      更新时间:2023-09-26

对于我测试过的x的大多数值,以下值评估为true:

Object.getPrototypeOf(x) === x.constructor.prototype

但也有一些例外:如果x是字符串,则上面表达式的LHS会失败,并出现类似的错误

TypeError: "abc" is not an object

尽管例如"abc".constructor.prototype评估为String.prototype。如果x是一个数字或布尔值,则会得到类似的结果。

怎么回事?前面显示的身份是否有更多例外?

更重要的是,以上表明x.constructor.prototypeObject.getPrototypeOf(x)更健壮。

有什么好的理由只使用x.constructor.prototype而完全忘记Object.getPrototypeOf(x)吗?

字符串(和其他基元)的行为可能有点奇怪。

基本上,当您尝试访问基元的属性时,它会使用其Object等价物以即时方式装箱,然后返回该对象的属性。

因此,在这种情况下,当您尝试访问"abc".constructor时,实际发生的情况与new String("abc").constructor(当然会返回String对象)相同。

另一方面,Object.getPrototypeOf不进行这种装箱,而是在传递任何非对象的信息时返回错误。

正如您所建议的,x.constructor.prototype似乎是一种更可靠的确定某个东西的构造函数的方法,因为它确实处理了这种"装箱"情况。也就是说,就我个人而言,我想不出任何真正的情况下可能需要这样的东西,因为。。。嗯,通常情况下,你已经知道什么是类型的东西了。这也是我认为大多数时候使用===没有任何实际意义的原因。

Object.getPrototypeOf不受旧浏览器的支持,因为x.constructor.prototype是更跨浏览器的解决方案。

然而,如果可用,则使用Object.getPrototypeOf更可靠,因为x.constructor可以这样更改:x.constructor='my new value';

我建议你创建这个polyfill函数:

if (!Object.getPrototypeOf) {
    Object.getPrototypeOf = function(o) { return o.__proto__ || o.constructor.prototype; };
}