厳密モードのコードと非厳密モードのコードの相互作用が起こっていると思います。実際、Firefox 3.6.15 (厳密モードをサポートしていない) のコピーを掘り起こしたとき、質問に投稿したリンクを使用してエラーが発生しません (「true」が 2 回警告されます)。
あなたが示したコードは、明らかに非厳格モードのコードです。しかし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
関数 on を定義するビットを除いて、これは緩いコードwindow
です。次に、ルーズ コードからその関数を 2 回呼び出します。結果は次のとおりです。
strictFunction: この === ウィンドウ? 間違い
strictFunction: typeof this: 未定義
strictFunction: この === ウィンドウ? 間違い
strictFunction: typeof this: 未定義
対照的に、緩やかな関数でそれを行うと、結果は次のようになります。
LooseFunction: この === ウィンドウ? 真実
LooseFunction: typeof this: オブジェクト
LooseFunction: この === ウィンドウ? 真実
LooseFunction: typeof this: オブジェクト
完全な例:ライブコピー| ライブソース
<!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>
出力 (strict モードをサポートする JavaScript エンジンを使用):
直通電話:
strictFunction: この === ウィンドウ? 間違い
strictFunction: typeof this: 未定義
LooseFunction: この === ウィンドウ? 真実
LooseFunction: typeof this: オブジェクト
--
.call(未定義) で呼び出す:
strictFunction: この === ウィンドウ? 間違い
strictFunction: typeof this: 未定義
LooseFunction: この === ウィンドウ? 真実
LooseFunction: typeof this: オブジェクト
--
.call(window) で呼び出す:
strictFunction: この === ウィンドウ? 真実
strictFunction: typeof this: オブジェクト
LooseFunction: この === ウィンドウ? 真実
LooseFunction: typeof this: オブジェクト