为什么要使用Object.prototype.hasOwnProperty.call(MyObj中,

2019-06-17 18:45发布

如果我理解正确的话,在Javascript中每个对象从对象的原型,这意味着在Javascript中每个对象都有通过其原型链访问hasOwnProperty功能继承。

在阅读require.js的源代码,我偶然发现了这个功能:

function hasProp(obj, prop) {
    return hasOwn.call(obj, prop);
}

hasOwn是到参考Object.prototype.hasOwnProperty 。 有没有写这个功能的任何实际差别

function hasProp(obj, prop) {
    return obj.hasOwnProperty(prop);
}

而且,由于我们是在它,为什么我们在所有定义这个功能呢? 难道仅仅是一个快捷方式的问题,以及为(轻微)的性能提升属性访问本地缓存,还是我失去了在那里hasOwnProperty可能会在不具有这种方法的对象可以使用任何情况下?

Answer 1:

是否有任何实际的区别[我的例子之间]

用户可能具有与创建的JavaScript对象Object.create(null) ,这将有一个null [[Prototype]]链,因此不会有hasOwnProperty()可用就可以了。 使用你的第二个形式,将无法为此工作。

这也是一个更安全的参考Object.prototype.hasOwnProperty()也短)。

你能想象有人可以这样做......

var someObject = {
    hasOwnProperty: function(lol) {
        return true;
    }
};

这将使一个hasProp(someObject)失败就没有被实施喜欢你的第二个例子(它会直接找对象上的方法,并调用那个,而不是委托给Object.prototype.hasOwnProperty )。

但它不太可能会有人已经覆盖了Object.prototype.hasOwnProperty参考。

而且,由于我们是在它,为什么我们在所有定义这个功能呢?

往上看。

难道仅仅是一个快捷键和(轻微)的性能提升的属性访问本地缓存的问题...

它可以使人们更快从理论上讲,作为[[Prototype]]链并不一定要遵守,但我怀疑这是可以忽略不计,而不是执行就是为什么它的原因。

......还是我失去了其中任何情况下hasOwnProperty可能会在不具有这种方法的对象中使用?

hasOwnProperty()存在于Object.prototype ,但可以覆盖。 每一个本地JavaScript对象(但主机对象不保证遵循这个, 看到RobG的深入解释 )具有Object.prototype的上链的最后一个对象之前null (当然除了通过返回的对象Object.create(null) )。



Answer 2:

如果我理解正确的话,在Javascript中每个对象从对象的原型继承

这似乎是鸡蛋里挑骨头,但JavaScript的 (对ECMAScript实现的通称)和ECMAScript(用于JavaScript实现的语言)之间的差异。 它是ECMAScript中定义的继承方案,而不是JavaScript,因此只有本地的ECMAScript对象需要实现继承方案。

正在运行的JavaScript程序至少包括内置的ECMAScript对象(对象,函数,数等),可能有一些本地对象(如函数)。 它也可能有一些主机对象(如在浏览器中DOM对象,或者在其它宿主环境中的其他对象)。

同时内置和原生对象必须实现在ECMA-262中定义的继承方案,主机对象没有。 因此,在JavaScript环境并不是所有的对象都必须Object.prototype中继承。 例如,在IE宿主对象实现仿佛视为本地对象(因此,为什么在try..catch用于初始化MS的XMLHttpRequest对象)ActiveX对象将抛出错误。 如果传递给Array方法有些DOM对象(如怪癖模式在IE的NodeLists)将抛出错误,DOM在IE 8对象,下不具有的ECMAScript般的继承方案,等等。

因此,不应该被认为在JavaScript环境中的所有对象从Object.prototype中继承。

这意味着在Javascript每个对象具有访问hasOwnProperty函数通过其原型链

这是不适合的特殊模式(和IE 8和下总是)至少在IE某些宿主对象真。

鉴于上述情况,这是值得深思为什么一个对象可能有其自身的hasOwnProperty方法,并呼吁其他一些hasOwnProperty方法,而不是不先试,如果这是一个好主意或没有的可取性。

编辑

我怀疑使用的原因Object.prototype.hasOwnProperty.call是,在某些浏览器,主机对象没有hasOwnProperty方法,使用电话和内置的方法是一种替代。 但是,这样做一般似乎并不像上面提到的原因是一个好主意。

当主机对象而言, 运算符可以用来测试性能一般,如

var o = document.getElementsByTagName('foo');

// false in most browsers, throws an error in IE 6, and probably 7 and 8
o.hasOwnProperty('bar');

// false in all browsers
('bar' in o);

// false (in all browsers? Do some throw errors?)
Object.prototype.hasOwnProperty.call(o, 'bar');

的替代方案(在IE6和其他测试):

function ownProp(o, prop) {

  if ('hasOwnProperty' in o) {
    return o.hasOwnProperty(prop);

  } else {
    return Object.prototype.hasOwnProperty.call(o, prop);
  }
}

你只专门致电内置hasOwnProperty该对象没有它(继承或其他方式)的方式。

然而,如果一个对象没有hasOwnProperty方法,这很可能只是为适合使用运营商为对象可能不具有继承方案和所有属性的对象(这只是一个假设,虽然),例如操作者是测试针对属性DOM对象支持的一个常见(看似成功)的方式。



Answer 3:

JavaScript不保护财产的名称hasOwnProperty

如果可能性是存在的一个对象可能有一个属性这个名字,就需要使用外部hasOwnProperty得到正确的结果:

您可以复制下面的代码片段并贴到您的浏览器控制台,以获得更好的理解

var foo = {
  hasOwnProperty: function() {
    return false;
  },
  bar: 'I belong to foo'
};

始终返回false

foo.hasOwnProperty('bar'); // false

使用另一个对象的hasOwnProperty,并按照调用到foo

({}).hasOwnProperty.call(foo, 'bar'); // true

它也可以使用hasOwnProperty酒店需要从对象原型用于此目的

Object.prototype.hasOwnProperty.call(foo, 'bar'); // true


Answer 4:

在现有的答案都给出的信息是即期。 然而,使用:

('propertyName' in obj)

被提到几次。 应当指出的是, hasOwnProperty只有在属性直接包含在被测试对象的实现将返回true。

in运营商将检查下来,通过原型链了。

这意味着,传递给在实例属性将返回true hasOwnProperty这里为原型的属性将返回false。

使用in操作实例和原型属性将返回true。



文章来源: Why use Object.prototype.hasOwnProperty.call(myObj, prop) instead of myObj.hasOwnProperty(prop)?