【问题标题】:Nature of JS bound functions and function invocation operatorJS绑定函数和函数调用运算符的性质
【发布时间】:2014-09-01 16:31:32
【问题描述】:
var obj = {};

var r1 = (obj['toString'])();
var m1 = obj['toString'];
var r2 = m1();

var r3 = (obj.toString)();
var m2 = obj.toString;
var r4 = m2();

r1r3 预期包含正确的结果:"[object Object]",而 r2r4 包含 "[object Undefined]",表明 m1m2 未绑定到对象。

我无法完全理解obj['toString']() 是如何执行的。我总是这样看,(obj['toString'])() -> (function obj)()。结果是函数调用运算符回顾了上下文是什么。我希望操作员不知道操作数来自哪里。

谁能正确解释这种行为?

【问题讨论】:

  • r2r4 是使用具有 this 等于执行 ({}).toString.call(undefined); 的函数生成的
  • @PaulS。是的,我试图指出这一点,但问题是为什么。

标签: javascript oop


【解决方案1】:

原来,函数调用运算符回顾了上下文是什么。我希望操作员不知道操作数来自哪里。

事实上,它确实知道。

在 EcmaScript 规范中,property accessor operators(和一些类似的操作)对此进行了描述,以返回一个“Reference object”,该信息恰好包含以下信息:访问属性的上下文。任何“正常”操作通常只会获取引用的值 - 包括 assignment operators,它会在您的情况下溶解引用。

call operator 使用它来使方法调用变得特殊:

  1. ref 成为评估MemberExpression 的结果。 可能会返回 Reference
  2. funcGetValue(ref)它获取实际的函数对象 - 你在规范中看到了很多这个操作
  3. 获取参数,做一些类型断言
  4. 如果类型(ref)是Reference,那么
    • 如果 IsPropertyReference(ref) 为真,则
      thisValue 成为GetBase(ref)。
    • 否则,ref 的基础是环境记录
      它基本上描述了 with 语句中的变量
  5. 否则,类型(ref) 不是Reference
    thisValue 成为undefined

【讨论】:

  • 所以如果没有就地调用,这个 Reference 对象会被隐式转换为函数对象?
  • 是的,这发生在赋值运算符中。例如,它不会发生在分组运算符(括号)中。
【解决方案2】:

这其实是grouping operator(...)的“特殊”行为:

1。返回计算表达式的结果。这可能是引用类型。

注意 此算法不适用于计算表达式的结果GetValue。这样做的主要动机是,deletetypeof 等运算符可以应用于带括号的表达式。

因此,此运算符特别不调用GetValue,因此不返回函数对象本身,而是返回整个引用,因此期望引用的操作仍然有效。


引用基本上是一个带有可选“基值”的值的封装,该基值是访问属性时的对象。

【讨论】:

    【解决方案3】:

    “this”的含义在 JavaScript 中似乎总是会引起混淆,尤其是在回调等场景中。

    稍微修改一下你的例子,因为你使用的是 toString() 并且我们看不到它的实现,所以我引入了一个可以看到依赖于上下文的函数,这就是 this。编码员期望访问对象属性 x,但当函数未绑定时,他感到惊讶。

    window.x = "some global value";
    var obj = { 
        wibble : function() { console.log("wibble " + this.x); }, 
        x : 7
    };
    
    obj.wibble();
    var f = obj.wibble;
    f();
    

    这会导致:

    wibble 7 
    wibble some global value
    

    也就是说,当我们以 obj.wibble() 或实际上是 obj["wibble"] 的形式显式指定上下文时,this 的行为与大多数开发人员所期望的一样。

    但是,当我们调用“naked”函数时,我们实际上得到了一个默认上下文,在我的示例中,我碰巧在那个上下文中有一个 x 的值,因此得到了那个值,这恰好是一个字符串。

    【讨论】:

    • 我不认为这个问题专门针对this,而是为什么/何时丢失了对象和函数之间的“连接”。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2011-02-23
    • 1970-01-01
    • 2015-11-02
    • 1970-01-01
    • 2011-10-11
    • 2011-06-09
    • 2019-07-14
    相关资源
    最近更新 更多