t 进阶:Apply, Call 和 Bind 方法详解 来详细解释这三种方法的用法,包括如何使用它们在各种容易出错情景下正确地设置 this 的值。我就不在这里贴出整篇文章了,推荐读者详细地阅读整篇文章,因为我认为要想成为 java script 的高级开发者,和这三种方法打交道是不可避免的。
为了解决上面例子提到的那种问题,我们可以使用 bind 方法:
我们把下面这行:
改正为下面这样,把 clickHandler 和 user 绑定起来:
查看 JSBin 上的在线示例
另一个 this 常常被误解的情景是当我们使用闭包的时候。一个非常值得注意的地方是,闭包不能直接通过使用 this 来访问外层函数的 this 变量,因为 this 变量只有当前函数本身可以访问,而其内层函数是访问不到的。举个例子:
在匿名函数内部的 this 不能获得外层函数 this 的值,所以当没有使用严格模式的时候,它就被绑定在了全局 window 对象上了。
在内层函数中维持 this 的值的方法:
为了解决传入 forEach 的匿名函数中 this 值不正确的问题,我们使用一个常用的解决办法,即当我们进入 forEach 的时候,提前把 this 的值存到另一个变量中去。
值得注意的是,许多 java script 开发者喜欢把 this 存在一个叫做 that 的变量中(就像下面的代码那样)。我觉得用 that 来命名使用的时候十分不方便,所以尽量使用一个合适的名词来描述 this 所指向的对象,所以我在上述代码中使用了 var theUserObj = this。
查看 JSBin 上的在线示例
当我们把一个使用了 this 的方法赋给一个变量的时候,this 的值很可能出乎我们的意料,指向了其他的对象。我们来看一个例子:
当把含有 this 的方法赋值给一个变量时维持 this 的值的方法
我们可以使用 bind 方法来显式地设置 this 的值来解决这个问题:
在 java script 开发中,借用方法(borrow methods)是一个很常见的用法,作为一个 java script 开发者,我们肯定会在实践中不断地遇到这个问题。而且每次我们也乐于使用这种节约时间的方法。如果你想了解更多关于方法借用的问题,请阅读我的这篇详细解析的文章,java script 进阶:Apply, Call 和 Bind 方法详解。
让我们来看看当处于借用方法这样的上下文的时候,this 的相关表现:
在 avg 方法中的 this 不会指向 gameController 对象,而会指向 appController 对象,因为它是被 appController 对象所调用的。
解决当借用方法时 this 指向出错的问题
要解决这个问题,我们只要确保在 appController.avg() 中的 this 指向 gameController 就可以了。我们可以使用 apply() 方法来实现:
gameController 对象借用了 appController 的 avg() 方法。在 appController.avg() 中的 this 的值会被设置成 gameController 对象,因为我们把 gameController 作为第一个参数传入了 apply() 方法中。传入 apply() 方法的第一个参数会被显式地设置为 this 的值。
查看 JSBin 上的在线示例
我希望你对 java script 中的 this 关键字已经理解了。现在你有了必需的工具(bind, apply, call 方法,和把 this 赋给一个变量)来帮你解决在各种情形下关于 this 的问题了。
正如我们在上文中看到的,this 在有些情况下可能会变得很难以处理,比如原始的上下文(就是 this 定义的地方)发生改变的时候,尤其是在回调函数中,或者被另一个对象调用的时候,再或者是当方法借用的时候。但是只要记住 this 永远具有那个调用 this 函数 的对象的值,就不会出错。
享受生活,享受代码。
原文链接