javascript - 为什么这里一般调用 hasOwnProperty?

标签 javascript oop object

Axel Rauschmayer 在 Speaking Javascript: An In-Depth Guide for Programmers 中提到了以下函数:

function getDefiningObject(obj, propKey) {
    obj = Object(obj); // make sure it’s an object
    while (obj && !{}.hasOwnProperty.call(obj, propKey)) {
        obj = Object.getPrototypeOf(obj);
        // obj is null if we have reached the end
    }
    return obj;
}

正如作者所说,它的目的是“[迭代]对象 obj 的属性链[并返回]第一个具有自己属性的对象,键为 propKey,如果没有这样的对象,则为 null

我理解这里的整体推理,但我不明白为什么要完成 {}.hasOwnProperty.call(obj, propKey) 而不仅仅是 obj.hasOwnProperty( propKey)。有什么想法吗?

最佳答案

通常,开发人员会对内置类型使用call,以确保他们获得方法的正确 native 行为,而不是某些重写行为。

这是一种我们确实不应该使用的保护措施,但由于对象在 JavaScript 中具有很强的可塑性,它可以保证我们获得我们想要的行为。

想象一下,如果有人(有意或无意地)创建了这样一个对象:

function SuperObject(){
   this.foo = function(){
     // Something here
   };

   this.hasOwnProperty = 42;
}

然后,你出现了(没有看到对象的实现)并写道:

var mySuperObject = new SuperObject();
console.log("Does 'mySuperObject' instance have its own 'foo' property? " +
            mySuperObject.hasOwnProperty("foo"));

你会得到这个:

function SuperObject(){
  this.foo = function(){
    // Something here
  };
    
  this.hasOwnProperty = 42;
}


var mySuperObject = new SuperObject();

// Safe way:
console.log("Does 'mySuperObject' instance have its own 'foo' property? " +
             {}.hasOwnProperty.call(mySuperObject, "foo"));

// Unsafe way (fails):
console.log("Does 'mySuperObject' instance have its own 'foo' property? " +
             mySuperObject.hasOwnProperty("foo"));

所以,我们得到的代码是这样的:

// This creates a new "fresh" (and unaltered) object with "object literal"
// syntax that you know doesn't override "hasOwnProperty"
{}.hasOwnProperty.call(obj, propKey)

// This performs the same task, but uses the native prototype object
// of the built-in Object type that we also know hasn't been altered:
Object.prototype.hasOwnProperty.call(obj, propKey) 

它强制在原生 Object 的原型(prototype)链上查找 hasOwnProperty,同时:

obj.hasOwnProperty(propKey)

依赖于该属性在对象 (obj) 的特定实例上可用且正确。

其他流行的例子是数组类型:

// These work the same as the Object examples above, but just 
// do it for the Array type:
[].forEach.call(); // Array literal syntax
Array.prototype.forEach.call(); // Explicit array syntax

关于javascript - 为什么这里一般调用 hasOwnProperty?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/41471310/

相关文章:

javascript - 数组比较失败

php - 获取实例的静态属性

java - 如何为只有参数化构造函数的类创建对象?

java - 音乐 "database"有 3 个类别;如何在SongDatabase类中存储信息

java - 在java中添加对象到数组列表

javascript - 事件处理程序是在 MVC 应用程序的 View 中还是 Controller 中?

javascript - jQuery 在悬停时交换图像,然后在悬停时将其替换为原始图像

java - 我应该仅仅因为添加了一个变量就扩展一个类吗?

oop - 小说/书籍面向对象的设计方法

javascript - 在 Ajax 调用中设置自定义 Content-Type 响应 header ?