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 的副本(不支持严格模式)时,使用我发布到您的问题的链接并没有收到错误消息(它两次提醒“真”)。

您显示的代码显然是非严格模式代码。但是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);

如您所见,除了strictFunctionwindow. 然后我们从松散的代码中调用该函数两次。结果是这样的:

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:对象
于 2013-07-06T08:37:33.770 回答
1

问题是上下文之一。也就是说,本质上,this函数内部的值是什么时候被调用的。

调用hasOwnProperty('window')没有上下文。这和这样做是一样的:

hasOwnProperty.call(undefined, 'window');

this.hasOwnProperty('window')与这样做相同:

hasOwnProperty.call(this, 'window');

第二行代码将具有您期望的输出 ( true),但第一行显然行不通。

于 2013-07-06T08:22:48.090 回答