为什么在这里一般调用hasOwnProperty?

rea*_*728 5 javascript oop object

Speel Javascript中提到了以下功能: Axel Rauschmayer 为程序员提供的深入指南:

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;
}
Run Code Online (Sandbox Code Playgroud)

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

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

Sco*_*cus 7

通常,开发人员将使用call内置类型来确保他们获得方法的正确本机行为而不是某些被覆盖的行为.

这是一个我们真的不应该使用的保护措施,但因为对象在JavaScript中是如此具有可塑性,它保证我们得到我们想要的行为.

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

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

   this.hasOwnProperty = 42;
}
Run Code Online (Sandbox Code Playgroud)

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

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

你会得到这个:

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"));
Run Code Online (Sandbox Code Playgroud)

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

// 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) 
Run Code Online (Sandbox Code Playgroud)

它强制hasOwnProperty要查找本机的原型链Object,同时:

obj.hasOwnProperty(propKey)
Run Code Online (Sandbox Code Playgroud)

依赖于可用的属性并在对象的特定实例上更正(obj).

其他流行的例子是Array类型:

// 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
Run Code Online (Sandbox Code Playgroud)

  • @Sadiq它当然可以这样,但一旦你了解它,它是非常灵活和强大的. (3认同)