this 的值。我就不在这里贴出整篇文章了,推荐读者详细地阅读整篇文章,因为我认为要想成为 java script 的高级开发者,和这三种方法打交道是不可避免的。为了解决上面例子提到的那种问题,我们可以使用 bind 方法:
我们把下面这行:
改正为下面这样,把 clickHandler 和 user 绑定起来:
另一个 this 常常被误解的情景是当我们使用闭包的时候。一个非常值得注意的地方是,闭包不能直接通过使用 this 来访问外层函数的 this 变量,因为 this 变量只有当前函数本身可以访问,而其内层函数是访问不到的。举个例子:
在匿名函数内部的 this 不能获得外层函数 this 的值,所以当没有使用严格模式的时候,它就被绑定在了全局 window 对象上了。
在内层函数中维持 this 的值的方法:
为了解决传入 forEach 的匿名函数中 this 值不正确的问题,我们使用一个常用的解决办法,即当我们进入 forEach 的时候,提前把 this 的值存到另一个变量中去。
值得注意的是,许多 java script 开发者喜欢把 this 存在一个叫做 that 的变量中(就像下面的代码那样)。我觉得用 that 来命名使用的时候十分不方便,所以尽量使用一个合适的名词来描述 this 所指向的对象,所以我在上述代码中使用了 var theUserObj = this。
当我们把一个使用了 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 的值。
我希望你对 java script 中的 this 关键字已经理解了。现在你有了必需的工具(bind, apply, call 方法,和把 this 赋给一个变量)来帮你解决在各种情形下关于 this 的问题了。
正如我们在上文中看到的,this 在有些情况下可能会变得很难以处理,比如原始的上下文(就是 this 定义的地方)发生改变的时候,尤其是在回调函数中,或者被另一个对象调用的时候,再或者是当方法借用的时候。但是只要记住 this 永远具有那个调用 this 函数 的对象的值,就不会出错。
享受生活,享受代码。