我认为正在发生的事情是我们有严格模式代码和非严格模式代码的交互。事实上,当我挖出 Firefox 3.6.15 的副本(不支持严格模式)时,使用我发布到您的问题的链接并没有收到错误消息(它两次提醒“真”)。
您显示的代码显然是非严格模式代码。但是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:这个 === 窗口?错误的
strictFunction: typeof this: undefined
strictFunction:这个 === 窗口?错误的
strictFunction: typeof this: undefined
相反,如果我们用一个松散的函数来做,结果是:
松散函数:这个 === 窗口?真的
松散函数:typeof this:对象
松散函数:这个 === 窗口?真的
松散函数:typeof this:对象
完整示例:Live Copy | 直播源
<!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 引擎):
直接调用:
strictFunction:这个 === 窗口?错误的
strictFunction: typeof this: undefined
松散函数:这个 === 窗口?真的
松散函数:typeof this:对象
--
使用 .call(undefined) 调用:
strictFunction:这个 === 窗口?错误的
strictFunction: typeof this: undefined
松散函数:这个 === 窗口?真的
松散函数:typeof this:对象
--
使用 .call(window) 调用:
strictFunction:这个 === 窗口?真的
strictFunction: typeof this: object
松散函数:这个 === 窗口?真的
松散函数:typeof this:对象