此代码抛出错误。
try {
alert(hasOwnProperty('window'));
} catch(e) {
alert(e); // Type Error : can't convert undefined to object
}
但此代码不会引发错误。
try {
alert(this.hasOwnProperty('window')); // true (if on browser)
} catch(e) {
// through catch block
alert(e);
}
据我所知,如果func(arg)
是全局对象,则this.func(arg)
等于this
。为什么会发生这样的事情?
答案 0 :(得分:8)
我认为正在发生的事情是我们有严格模式代码和非严格模式代码的交互。事实上,当我挖出一个Firefox 3.6.15(不支持严格模式)的副本时,我没有使用我发布到你的问题的链接得到错误(它警告“真实”两次)。 / p>
您显示的代码显然是非严格的模式代码。但是hasOwnProperty
浏览器的实现怎么样?我怀疑它是严格的,在支持严格模式的浏览器上。
当你说
时func();
...浏览器的作用是使用标准标识符解析查找func
,然后像执行此操作一样调用它:
func.call(undefined);
如果func
是松散模式函数,那么在func
的调用中,this
是全局对象。 但,如果func
是严格模式功能,则通话中的this
为undefined
。
与此形成鲜明对比:
this.func();
...它再次查找func
(这次通过使用原型链的属性解析),然后有效地执行此操作:
this.func.call(this);
在严格或宽松模式下,这意味着函数中的this
将为this
。 (当然,在全球范围内,this
是全局对象。)
以下是使用我们可以看到的代码而非hasOwnProperty
:
(function() {
"use strict";
window.strictFunction = function() {
display("strictFunction: this === window? " +
(this === window));
display("strictFunction: typeof this: " +
typeof this);
};
})();
strictFunction();
strictFunction.call(undefined);
正如您所看到的,除了在strictFunction
上定义window
函数的位之外,这是松散的代码。然后我们从松散的代码中调用该函数两次。结果如下:
strictFunction: this === window? false strictFunction: typeof this: undefined strictFunction: this === window? false strictFunction: typeof this: undefined
相反,如果我们使用松散函数执行此操作,结果是:
looseFunction: this === window? true looseFunction: typeof this: object looseFunction: this === window? true looseFunction: typeof this: object
完整示例:Live Copy | Live Source
<!DOCTYPE html>
<html>
<head>
<meta charset=utf-8 />
<title>Fun With Strict Interactions</title>
<style>
body {
font-family: sans-serif;
}
p {
margin: 0;
}
</style>
</head>
<body>
<script>
(function() {
"use strict";
window.strictFunction = function() {
display("strictFunction: this === window? " +
(this === window));
display("strictFunction: typeof this: " +
typeof this);
};
})();
(function() {
window.looseFunction = function() {
display("looseFunction: this === window? " +
(this === window));
display("looseFunction: typeof this: " +
typeof this);
};
})();
display("Direct call:");
strictFunction();
looseFunction();
display("<hr>Call with <code>.call(undefined)</code>:");
strictFunction.call(undefined);
looseFunction.call(undefined);
display("<hr>Call with <code>.call(window)</code>:");
strictFunction.call(window);
looseFunction.call(window);
function display(msg) {
var p = document.createElement('p');
p.innerHTML = String(msg);
document.body.appendChild(p);
}
</script>
</body>
</html>
输出(使用支持严格模式的JavaScript引擎):
Direct call: strictFunction: this === window? false strictFunction: typeof this: undefined looseFunction: this === window? true looseFunction: typeof this: object -- Call with .call(undefined): strictFunction: this === window? false strictFunction: typeof this: undefined looseFunction: this === window? true looseFunction: typeof this: object -- Call with .call(window): strictFunction: this === window? true strictFunction: typeof this: object looseFunction: this === window? true looseFunction: typeof this: object
答案 1 :(得分:1)
问题是 context 之一。也就是说,本质上,函数内部的this
值是什么时候被调用。
调用hasOwnProperty('window')
没有上下文。这与此相同:
hasOwnProperty.call(undefined, 'window');
this.hasOwnProperty('window')
与此相同:
hasOwnProperty.call(this, 'window');
第二行代码将具有您期望的输出(true
),但第一行显然不起作用。