【问题标题】:Why is the "this" value different? [duplicate]为什么“this”值不同? [复制]
【发布时间】:2018-09-27 21:51:18
【问题描述】:

这是一个例子,o.foo(); 是 3 而(p.foo = o.foo)(); 是 2?

function foo() {
    console.log( this.a );
}

var a = 2;
var o = { a: 3, foo: foo };
var p = { a: 4 };

o.foo(); // 3
(p.foo = o.foo)(); // 2”

如果我做这样的事情,那么我会得到4,这就是我想要的。这两个例子有何不同?

p.foo = o.foo;
p.foo();  // 4

【问题讨论】:

  • 你的意思是o.foo()返回{a: 3, foo: ƒ}
  • @UladKasach 抱歉 console.log( this.a ); 编辑了我的代码
  • 那是因为你使用了自调用函数。看看here
  • @AlexandreMiziara - 你确定这是一个 IIFE 吗?如果是,那如何解释结果?
  • 当你做 p.foo = o.foo.您正在尝试分配两个不相等的对象(一个具有比另一个更多的属性)。然后在最后你调用 () 来命令函数立即调用。自然会导致一些问题

标签: javascript this


【解决方案1】:

在此处的函数调用之前执行该赋值操作:

(p.foo = o.foo)();

导致对p 的对象引用丢失。如果你改为写

p.foo = o.foo;
p.foo();

你会得到 4。事实上,你会得到 2,因为函数中 this 的值将是 window

因为带括号的子表达式是一个赋值结果,所以没有与表达式结果直接关联的对象查找——赋值表达式的值只是没有上下文对象的函数引用。因此,运行时在调用函数时没有可用于this 的值,因此this 默认绑定到window(或任何上下文中的全局对象)。

【讨论】:

  • 等等,我认为这个解释是错误的......
  • "( ) 创建了一个子表达式“层”,导致对象关联被删除。" - 不过,它一定比这更复杂。 (o.foo)(); 工作正常。
  • @OliverCharlesworth 是的,这就是我意识到的,因为模糊的记忆让我认为我肯定会在模糊(但不完全)这样的情况下使用括号;见编辑。
  • 我觉得这很奇怪。为什么丢失的是 p 而不是 o? o 不是 r_value 操作数吗?
  • @Callat 查看编辑;最后一段的原始解释是我在想清楚之前打字。
【解决方案2】:

实际上您的代码是错误的,因为您的 sn-p 没有运行,您应该执行以下操作:console.log( this.a );

现在,让我们看看它是如何工作的。

function foo() {
    console.log( this.a );
}

这将在调用者范围内调用this,所以让我们调查一下我们的结果。

所以,您是在全局设置a=2,然后在对象o.a = 3p.a=4 中设置

所以:

调用o.foo 它将返回3,因为它指向o

调用p.foo 它将返回4,因为它指向p

但是

调用(p.foo = o.foo)(); 会返回2,因为它没有指向任何对象,所以它会占用你的作用域(即全局作用域),然后它会返回2

如果你选择:

p.foo = o.foo
p.foo() //4

它会成功返回4,因为它指向p

【讨论】:

  • 已经把我的代码改成console.log( this.a );谢谢=)
  • @AlexeyTseitlin 是的,我在写完答案后注意到了,希望对您有所帮助
【解决方案3】:

这个:

(p.foo = o.foo)();

和这样做差不多:

d = (p.foo = o.foo);
d();

基本上它的意思是赋值的返回是全局上下文中的函数本身。其中a 为 2。

【讨论】:

    猜你喜欢
    • 2014-03-25
    • 1970-01-01
    • 2017-07-08
    • 1970-01-01
    • 2015-08-10
    • 2013-09-28
    • 2013-08-09
    • 1970-01-01
    • 2016-07-24
    相关资源
    最近更新 更多