tim*_*mkg 85 javascript prototypal-inheritance hasownproperty requirejs
如果我理解正确,Javascript中的每个对象都继承自Object原型,这意味着Javascript中的每个对象都可以通过其原型链访问hasOwnProperty函数.
在阅读require.js的源代码时,我偶然发现了这个函数:
function hasProp(obj, prop) {
return hasOwn.call(obj, prop);
}
Run Code Online (Sandbox Code Playgroud)
hasOwn是一个参考Object.prototype.hasOwnProperty.写这个函数是否有任何实际的区别
function hasProp(obj, prop) {
return obj.hasOwnProperty(prop);
}
Run Code Online (Sandbox Code Playgroud)
既然我们在这,我们为什么要定义这个功能呢?这只是一个快捷方式和本地缓存属性访问(轻微)性能提升的问题,还是我错过了任何可能在没有此方法的对象上使用hasOwnProperty的情况?
ale*_*lex 96
[我的例子之间]有什么实际区别吗?
用户可能创建了一个JavaScript对象Object.create(null),该对象将具有null [[Prototype]]链,因此将无法hasOwnProperty()使用它.因此,使用您的第二个表单将无法正常工作.
它也是一个更安全的参考Object.prototype.hasOwnProperty()(也更短).
你可以想象有人可能已经做过......
var someObject = {
hasOwnProperty: function(lol) {
return true;
}
};
Run Code Online (Sandbox Code Playgroud)
如果hasProp(someObject)它像你的第二个例子一样被实现,那么它会失败(它会直接在对象上找到该方法并调用它,而不是被委托给它Object.prototype.hasOwnProperty).
但是,不太可能有人会覆盖Object.prototype.hasOwnProperty参考文献.
既然我们在这,我们为什么要定义这个功能呢?
往上看.
这只是一个快捷方式和本地缓存属性访问的问题(轻微)性能提升......
理论上它可能会更快,因为[[Prototype]]不必遵循链条,但我怀疑这可以忽略不计,而不是实现原因的原因.
...或者我错过了任何
hasOwnProperty可能用于没有此方法的对象的情况 ?
hasOwnProperty()存在Object.prototype,但可以被覆盖.每个本机JavaScript对象(但主机对象不保证遵循此目的,请参阅RobG的深入解释)Object.prototype之前的链上的最后一个对象null(当然除了返回的对象Object.create(null)).
Rob*_*obG 13
如果我理解正确,Javascript中的每个对象都继承自Object原型
它可能看起来像分裂头发,但javascript(ECMAScript实现的通用术语)和ECMAScript(用于javascript实现的语言)之间存在差异.ECMAScript定义了一个继承方案,而不是javascript,因此只有本机ECMAScript对象需要实现该继承方案.
运行的javascript程序至少包含内置的ECMAScript对象(对象,函数,数字等)以及可能的一些本机对象(例如函数).它也可能有一些主机对象(例如浏览器中的DOM对象或其他主机环境中的其他对象).
虽然内置和本机对象必须实现ECMA-262中定义的继承方案,但主机对象却不能.因此,并非javascript环境中的所有对象都必须从Object.prototype继承.例如,IE实现为ActiveX对象的主机对象如果被视为本机对象,则会抛出错误(因此,为什么try..catch用于初始化MS XMLHttpRequest对象).如果传递给Array方法,一些DOM对象(如在quirks模式下的IE中的NodeLists)将抛出错误,IE 8及更低版本中的DOM对象没有类似ECMAScript的继承方案,依此类推.
因此,不应假设javascript环境中的所有对象都继承自Object.prototype.
这意味着Javascript中的每个对象都可以通过其原型链访问hasOwnProperty函数
对于IE中的某些主机对象,在怪癖模式(至少是IE 8及更低版本)中并非如此.
鉴于上述情况,值得思考为什么一个对象可能有自己的hasOwnProperty方法以及调用其他hasOwnProperty方法的可取性而不先测试是否是一个好主意.
我怀疑使用的原因Object.prototype.hasOwnProperty.call是在某些浏览器中,宿主对象没有hasOwnProperty方法,使用call和内置方法是另一种选择.然而,由于上述原因,这样做通常不是一个好主意.
在涉及主体对象的情况下,in运算符通常可用于测试属性,例如
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');
Run Code Online (Sandbox Code Playgroud)
另一种选择(在IE6等测试中):
function ownProp(o, prop) {
if ('hasOwnProperty' in o) {
return o.hasOwnProperty(prop);
} else {
return Object.prototype.hasOwnProperty.call(o, prop);
}
}
Run Code Online (Sandbox Code Playgroud)
这样你只需要专门调用内置的hasOwnProperty对象没有它(继承或其他).
但是,如果一个对象没有hasOwnProperty方法,那么它可能就像使用in运算符一样合适,因为对象可能没有继承方案,并且所有属性都在对象上(尽管这只是一个假设),例如in operator是一种常见的(并且看似成功的)测试DOM对象属性支持的方法.
JavaScript不保护属性名称hasOwnProperty
如果存在对象可能具有此名称的属性的可能性,则必须使用外部hasOwnProperty来获得正确的结果:
您可以将以下代码段复制粘贴到浏览器控制台,以便更好地理解
var foo = {
hasOwnProperty: function() {
return false;
},
bar: 'I belong to foo'
};
Run Code Online (Sandbox Code Playgroud)
始终返回false
foo.hasOwnProperty('bar'); // false
Run Code Online (Sandbox Code Playgroud)
使用另一个对象的hasOwnProperty,并调用它这个集为foo
({}).hasOwnProperty.call(foo, 'bar'); // true
Run Code Online (Sandbox Code Playgroud)
为此,还可以使用Object原型中的hasOwnProperty属性
Object.prototype.hasOwnProperty.call(foo, 'bar'); // true
Run Code Online (Sandbox Code Playgroud)