原型函数内的函数中的“this”

IT技术 javascript
2021-03-09 06:17:28

我基本上有一个对象,通过它的原型扩展了一个函数。在那个函数内部,存在另一个函数,但是this在这个嵌套函数中使用时,它似乎不是指对象,而是指函数。

例如,

var sampleObject = function() {
 this.foo = 123;
}

sampleObject.prototype.getFoo = function() {
 var nested = function() {
  return this.foo;
 }
 return nested();
}

var test = new sampleObject();

window.alert(test.getFoo()); // undefined

Thethis.foo不是指 123 值,而是未定义,因为 this 指的是嵌套函数,其中 nofoo存在。如何从嵌套函数访问 123 值?

6个回答
sampleObject.prototype.getFoo = function() {
 var me = this;
 var nested = function() {
  return me.foo;
 }
 return nested;
}

通过将 的值保存this在局部变量中,您可以使其明确成为该函数和所有嵌套函数作用域的词法上下文的一部分。因此,在调用“nested”时,该内部函数将有自己的作用域(它自己的this值),但它仍然可以引用封闭作用域中的变量“me”。

但这不好,因为通过使用函数引用,我们失去了this对原型设计如此重要的东西,所以var me = this;在你的例子中将指向window对象
2021-04-17 06:17:28
如果我这样做会发生什么: var foo = new sampleObject(); $(window).on('scroll', foo.getFoo );
2021-04-20 06:17:28
@vsync 应该没问题-如果您遇到类似问题,我建议您使用导致困难的代码示例打开一个全新的问题。
2021-04-27 06:17:28
请注意,在上面的示例中,嵌套函数是一个闭包,即使在返回之后,我也会绑定到该函数。me 将在嵌套的闭包范围内。嵌套将正常工作,因为它包含我的一部分,并且它引用了 sampleObject 实例
2021-05-03 06:17:28
@vsync 啊好吧抱歉我读错了你的问题。是的,在这种情况下,您需要将调用包装在匿名函数中,或者使用其他方法.bind()为您完成。
2021-05-06 06:17:28

在您的示例中,“this”指的是 window 对象,因为您在调用嵌套函数时没有指定另一个上下文,并且因为 window.foo 未定义而得到 undefind。

您可以通过 3 种方式解决此问题。

1 - 使用变量存储外部 this - 最常用的方法

sampleObject.prototype.getFoo = function() {
 var _this = this;
 var nested = function() {
  return _this.foo;
 }
 return nested();
}

2 - 使用绑定方法将外部“this”绑定到内部

sampleObject.prototype.getFoo = function() {
 var nested = function() {
  return this.foo;
 }.bind(this);
 return nested();
}

3 - 使用可以将上下文传递给函数的调用方法

SampleObject.prototype.getFoo = function() {
 var nested = function() {
  return this.foo;
 };
 return nested.call(this);
}

常见的解决方法是使用闭包

sampleObject.prototype.getFoo = function() {
  var _this = this; 
  var nested = function() {
    return _this.foo;
   }
   return nested();
}

一些库添加了自动执行此操作的方法

我更喜欢非自动化的方式,因为它不是那么复杂,谢谢
2021-04-26 06:17:28
在这种情况下您可能更喜欢它,但自动化方式对于事件处理程序来说非常好。
2021-05-09 06:17:28

tl;博士

使用箭头函数它们从 ECMAScript 6 开始可用:

var sampleObject = function() {
  this.foo = 123;
}

sampleObject.prototype.getFoo = function() {
  var nested = () => { // Changed this line.
    return this.foo;
  }
  return nested();
}

var test = new sampleObject();

window.alert(test.getFoo());

解释

这是箭头函数的主要优点之一。您的情况在以下部分中进行了描述:没有绑定this参考文献指出:

在箭头函数之前,每个新函数都定义了自己的this值 [...] 箭头函数不会创建自己的this上下文,因此this具有来自封闭上下文的原始含义。

除了将其声明为var _this = this,我还看到代码正在执行var that = thisvar self = this

了解变量的作用域很重要,因为它可能会产生意想不到的结果。

对我来说,that通常是原型函数中的变量,例如foo.prototype.add = function(that) {return this + that},所以我更喜欢selfme
2021-05-11 06:17:28
如果你正在做一个大项目,想出一个约定。即始终使用 var that = this; 或自我或什么
2021-05-13 06:17:28