7

このコードはエラーをスローします。

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

4

2 に答える 2

8

厳密モードのコードと非厳密モードのコードの相互作用が起こっていると思います。実際、Firefox 3.6.15 (厳密モードをサポートしていない) のコピーを掘り起こしたとき、質問に投稿したリンクを使用してエラーが発生しません (「true」が 2 回警告されます)。

あなたが示したコードは、明らかに非厳格モードのコードです。しかしhasOwnProperty、ブラウザの実装はどうですか? 厳密モードがサポートされているブラウザーでは、厳密であると思われます。

あなたが言う時

func();

...ブラウザが行うことは、func標準の識別子解決を使用して検索し、次のように呼び出します。

func.call(undefined);

がルース モード関数の場合func、 への呼び出し内でfuncthisグローバル オブジェクトです。ただし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: オブジェクト
于 2013-07-06T08:37:33.770 に答える