为什么使用 Object.Prototype.hasOwnProperty.call (myObj,prop)而不是 myObjec.hasOwnProperty (prop) ?

如果我理解正确的话,JavaScript 中的每个对象都继承自 Object 原型,这意味着 JavaScript 中的每个对象都可以通过其原型链访问 hasOwnProperty 函数。

在阅读 需要的源代码时,我偶然发现了这个函数:

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

hasOwn是对 Object.prototype.hasOwnProperty的引用。将这个函数写成

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

既然我们已经知道了,为什么还要定义这个函数呢?这仅仅是一个快捷方式和本地缓存属性访问以获得(轻微的)性能提升的问题吗? 还是我忽略了 hasOwnProperty 可能用于没有这种方法的对象的任何情况?

63687 次浏览

[我的例子之间]有什么实际的区别吗?

用户可能有一个用 Object.create(null)创建的 JavaScript 对象,它将有一个 null [[Prototype]]链,因此不会有 hasOwnProperty()可用。由于这个原因,使用第二种形式将不起作用。

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

你可以想象有人可能..。

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

如果像您的第二个示例那样实现 hasProp(someObject),这将导致 hasProp(someObject)失败(它将直接在对象上找到该方法并调用该方法,而不是委托给 Object.prototype.hasOwnProperty)。

但是不太可能有人覆盖了 Object.prototype.hasOwnProperty引用。

既然我们已经知道了,为什么还要定义这个函数呢?

看上面。

是吗 只是一个快捷方式和本地缓存的属性访问的问题 (轻微)性能提升..。

它在理论上可能使它成为 更快,因为不必遵循 [[Prototype]]链,但我怀疑这可以忽略不计,而 没有实现的原因就是它的原因。

还是我错过了什么案子 hasOwnProperty可以用在没有这种方法的对象上吗?

hasOwnProperty()存在于 Object.prototype上,但是可以被重写。每个本地 JavaScript 对象(但是主机对象不能保证遵循这个规则,请看 RobG 的详细解释)都将 Object.prototype作为 null之前链中的最后一个对象(当然除了 Object.create(null)返回的对象)。

如果我理解正确的话,JavaScript 中的每个对象都继承自 Object 原型

这可能看起来像是吹毛求疵,但是在 JavaScript(ECMAScript 实现的通用术语)和 ECMAScript(JavaScript 实现使用的语言)之间是有区别的。定义继承模式的是 ECMAScript,而不是 JavaScript,因此只有本地 ECMAScript 对象需要实现该继承模式。

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

虽然内置对象和本机对象必须实现 ECMA-262中定义的继承方案,但宿主对象不必。因此,并非 JavaScript 环境 必须的中的所有对象都继承自 对象,原型。例如,作为 Internet Explorer 实现的主机对象如果被视为本机对象,就会抛出错误(这就是为什么使用 试着... 接住来初始化微软的 XMLHttpRequest对象)。一些 DOM 对象(比如处于 Internet Explorer 模式的 NodeList)如果传递给 Array 方法,将会抛出错误,处于 Internet Explorer 8或更低位置的 DOM 对象没有类似 ECMAScript 的继承方案,等等。

因此,不应该假定 JavaScript 环境中的所有对象都继承自 Object.model。

这意味着 JavaScript 中的每个对象都可以通过其原型链访问 hasOwnProperty 函数

对于某些处于 Internet Explorer 模式的主机对象来说,情况并非如此(并且总是处于 Internet Explorer 8或者更低的模式)。

鉴于上述情况,值得思考的是,为什么一个对象可能有自己的 HasOwnProperty方法,以及在不首先测试是否是一个好主意的情况下调用其他 HasOwnProperty方法的可取性。

我怀疑使用 Object.prototype.hasOwnProperty.call的原因是,在某些浏览器中,主机对象没有使用 HasOwnProperty方法,而使用 打电话和内置方法是另一种选择。然而,由于上面提到的原因,通常这样做似乎不是一个好主意。

对于主机对象,通常可以使用 进去操作符来测试属性,例如。

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


// false in most browsers, throws an error in Internet Explorer 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');

另一种选择(在 Internet Explorer 6和其他测试中测试) :

function ownProp(o, prop) {


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


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

这样,您只需在对象没有内置 HasOwnProperty(继承或其他方式)的地方专门调用内置 HasOwnProperty

然而,如果一个对象没有 hasOwnProperty方法,那么使用 进去操作符可能就像对象可能没有继承方案并且所有属性都在对象上一样合适(这只是一个假设) ,例如,进去操作符是一种常见的(而且似乎成功的)测试 DOM 对象对属性支持的方法。

前两个答案(按日期)所提供的资料均准确无误,但使用:

('propertyName' in obj)

被提到过几次。应该注意的是,只有当属性直接包含在被测试的对象上时,hasOwnProperty实现才会返回 true。

in操作员也将通过原型链进行下行检查。

这意味着当传递给 hasOwnProperty时,实例属性将返回 true,而原型属性将返回 false。

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

JavaScript 不保护属性名 HasOwnProperty

如果存在一个对象可能具有这个名称的属性的可能性,那么有必要使用外部 hasOwnProperty 来获得正确的结果:

您可以将下面的代码片段复制粘贴到浏览器控制台,以便更好地理解

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

总是返回假

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

使用另一个 Object 的 hasOwnProperty 并在 这个设置为 foo 的情况下调用它

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

也可以为此目的使用来自 反对原型的 hasOwnProperty 属性

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

更简单的方法是:

let foo = Object.create(null);
if (foo.bar != null) {
console.log('object foo contains bar property in any value and
type, except type undefined and null');
// bar property can exist in object foo or any object of the prototype chain
}

除了这里的其他答案,请注意,您可以使用新的方法 Object.hasOwn(在大多数浏览器中支持,并且很快将在其他浏览器中支持)而不是 Object.hasOwnProperty.call,因为它允许您编写更简洁、更短的代码。

更多关于 Object.hasOwn-https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Object/hasOwn的资料

浏览器兼容性 -https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Object/hasOwn#browser_compatibility