gpt4 book ai didi

JavaScript 函数绑定(bind)(this 关键字)在赋值后丢失

转载 作者:可可西里 更新时间:2023-11-01 02:53:24 24 4
gpt4 key购买 nike

这是 JavaScript 中最神秘的特性之一,在将对象方法分配给其他变量后,绑定(bind)(this 关键字)丢失了

var john = {
name: 'John',
greet: function(person) {
alert("Hi " + person + ", my name is " + this.name);
}
};

john.greet("Mark"); // Hi Mark, my name is John

var fx = john.greet;
fx("Mark"); // Hi Mark, my name is

我的问题是:

1) 作业背后发生了什么? var fx = john.greet; 这是按值复制还是按引用复制? fx 和 john.greet 指向两个不同的函数,对吧?

2) 由于 fx 是一个全局方法,作用域链只包含全局对象。 Variable 对象中 this 属性的值是多少?

最佳答案

john.greet("Mark") 实际上调用了一个函数。当您执行 var fx = john.greet; 时,您将获得对该函数的引用。所以当你调用它时,this 没有绑定(bind)到 john。您实际上在做的是 window.fx("Mark"),因此 thiswindow 对象。当你说它是在全局范围内时,你是在正确的轨道上。在此特定实例中,全局对象是 window,因此 fx 实际上是 window.fx

当你有一个函数引用时,你应该使用 callapply如果你想设置 this 的值。尝试这样做:

fx.call(john, "Mark");

callapply 中的第一个参数是函数调用上下文中用于 this 的值。

编辑

有些人提到这里的真正问题可能是围绕对象文字与对象实例的混淆。您正在创建一个对象字面量,它的行为也有点像单例。您不能创建该对象的新实例。在这种情况下,john 是对该对象文字的引用。在这种情况下,函数 greet 中的 this 指的是对象文字本身。因此,当您调用 john.greet("Mark") 时,this 将绑定(bind)到 john

当您单独获取对 john.greet 的引用并将其分配给全局变量时,您实际上是在这样做:

var fx = function(person) {
alert("Hi " + person + ", my name is " + this.name);
}

在这种情况下,thiswindow,因为 fx 基本上是 window.fx(因为全局这里的对象是 window。假设这段代码被包装在 另一个 函数中,那么全局对象将引用该函数。

如果你想创建一个对象的多个实例,你可以这样做:

var Person = function(name) {
var self = this; //maintains a reference to the instance

this.name = name;
this.greet = function(name) {
alert("Hi " + name + ", my name is " + self.name);
}
}

var john = new Person("John");
john.greet("Mark"); // alerts "Hi Mark, my name is John"

var fx = john.greet;
fx("Mark"); // also alerts "Hi Mark, my name is John"

在这里,self 变量(它是函数的局部变量)维护对实际实例的引用,因为您在创建对象时将它绑定(bind)到 this .

在 Javascript 中有许多与 OOP 相关的最佳实践。你可以谷歌并找出(有很多链接)。我特别推荐阅读 Douglas Crockford 的文章。

关于JavaScript 函数绑定(bind)(this 关键字)在赋值后丢失,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/2701987/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com