javascript - JS 绑定(bind)函数和函数调用运算符的性质

标签 javascript oop

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 没有绑定(bind)到对象。

我无法完全理解 obj['toString']() 是如何执行的。我总是这样看,(obj['toString'])() -> (function obj)()。事实证明,函数调用运算符会回顾上下文。我希望运算符不知道操作数的来源。

谁能正确解释这种行为?

最佳答案

Turns out that function invocation operator looks back on what is the context. I would expect operator to not know where operands come from.

事实上,它确实知道。

在 EcmaScript 规范中,这由 property accessor operators 描述(以及一些类似的操作)返回一个“Reference object”,它包含了这个信息:属性被访问的上下文。任何“正常”操作通常只会获取引用的值 - 包括 assignment operators ,这确实会解除您案例中的引用。

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

  1. Let ref be the result of evaluating MemberExpression. which may return a Reference
  2. Let func be GetValue(ref). which fetches the actual function object - you see this operation a lot in the spec
  3. fetch arguments, do some type assertions
  4. If Type(ref) is Reference, then
    • If IsPropertyReference(ref) is true, then
      Let thisValue be GetBase(ref). <- here the method context is fetched
    • Else, the base of ref is an Environment Record
      which basically describes variables inside a with statement
  5. Else, Type(ref) is not Reference.
    Let thisValue be undefined.

关于javascript - JS 绑定(bind)函数和函数调用运算符的性质,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/25609927/

相关文章:

java - Java中逻辑复杂的EnumSet

javascript - 2048 : Strange behaviour of reduceRight in map with lodash/fp

javascript - 适用于 Javascript 的 Chrome 开发者环境

javascript - jQuery slider 值位于 slider 上方

javascript - .appendChild(tr) 创建没有数据的 tr

Java:将公共(public)类方法公开给同一项目的所有包,但对其他项目私有(private)

java - 保存对象供以后使用

javascript - 如何增加 knockout.js 可观察值?

PHP 在同一类的实例之间共享 protected 属性

c++ - 为工厂方法使用堆栈分配而不是堆分配