JavaScript中的this关键字

简介:

在JavaScript中,this通常绑定到函数被调用的对象上,这种默认绑定在多数情况下是正常的,但是在某些情况下,this的这种绑定会丢失,比如,将函数作为参数传递给另外一个函数,这种默认的绑定就丢失了,例如:

var myObj = {
   name: 'A nice demo!',
   fx: function() {
      alert(this.name);
   }
};

function runFx(fx) {
   fx();
}

window.name = 'I am a nice window';

myObj.fx();  // 在这里,将会提示 A nice demo!

runFx(myObj.fx); // 在这里,得到的提示将会是 I am a nice window

为什么会出现这种情况呢?因为在第二次调用中,myObj.fx作为参数传递给了runFx,在函数runFx中执行时fx丢失了对myObj的默认绑定,而绑定到了runFx的默认绑定window上,所以第二次调用时得到的提示为I am a nice window,而这个往往不是我们需要的结果。

在Ajax横行的今天,要编写复杂的客户端组件,不可避免的要将函数名作为参数传递,Prototype注意到了这个问题,MS ASP.Net Ajax也注意到了这个问题,不知道你注意了没有?

Prototype提供的解决方案是bind方法,在Prototype的官方文档给出的描述是:Provides aguaranteed-binding equivalent of the original function, possibly with pre-filled arguments. 上面的例子如果使用Prototype的话,可以修改如下:

var myObj = {
   name: 'A nice demo!',
   fx: function() {
      alert(this.name);
   }
};

function runFx(fx) {
   fx();
}

window.name = 'I am a nice window';

myObj.fx();  // 在这里,将会提示 A nice demo!

var fx2 = myObj.fx.bind(myObj) // 先做一个绑定,
runFx(fx2); // 在这里,得到的提示将会是 A nide demo !这个往往是我们需要的结果

MS Ajax提供的解决方案是Function.createDelegate函数,createDelegate方法是个静态方法,可以直接调用。如果使用MS Ajax库的话,可以将上面的例子修改为:

var myObj = {
   name: 'A nice demo!',
   fx: function() {
      alert(this.name);
   }
};

function runFx(fx) {
   fx();
}

window.name = 'I am a nice window';

myObj.fx();  // 在这里,将会提示 A nice demo!

var fx2 = Function.createDelegate(myObj, myObj.fx) // 按照微软的说法,先做一个委托,
runFx(fx2); // 在这里,得到的提示将会是 A nide demo !这个往往是我们需要的结果

这看起来只是一个小问题,但是如果不注意的话却会造成很大的问题。引用Prototype中的原话:As discussed on the general Function page,binding can be a pretty tricky thing sometimes.

张志敏所有文章遵循创作共用版权协议,要求署名、非商业 、保持一致。在满足创作共用版权协议的基础上可以转载,但请以超链接形式注明出处。

本博客已经迁移到 GitHub , 围观地址: http://beginor.github.io/

本文转自张志敏博客园博客,原文链接:http://www.cnblogs.com/beginor/archive/2007/03/12/672511.html如需转载请自行联系原作者
相关文章
|
1月前
|
JavaScript 前端开发
javascript中的this
javascript中的this
|
3月前
|
JavaScript 前端开发
错综复杂的this:理清你的JavaScript代码中的指向问题
错综复杂的this:理清你的JavaScript代码中的指向问题
|
1月前
|
JavaScript
JS中改变this指向的六种方法
JS中改变this指向的六种方法
|
24天前
|
JavaScript 前端开发 开发者
js开发:请解释什么是ES6的let和const关键字,以及它们与var关键字的区别。
ES6引入`let`和`const`替代`var`声明变量。`let`有块级作用域,存在暂时性死区,不进行变量提升,可重新赋值。`const`用于常量,值不可变但引用类型内容可变,同样有块级作用域和暂时性死区。与`var`主要区别在于作用域、变量提升和可变性。这些改进提高了代码的可预测性和安全性。
24 2
|
25天前
|
JavaScript 前端开发
js开发:请解释this关键字在JavaScript中的用法。
JavaScript中的`this`关键字根据执行上下文指向不同对象:全局作用域中指向全局对象(如`window`),普通函数中默认指向全局对象,但作为对象方法时指向该对象。在构造函数中,`this`指向新实例。箭头函数不绑定`this`,而是继承上下文的`this`值。可通过`call`、`apply`、`bind`方法显式改变`this`指向。
8 2
|
1月前
|
JavaScript
JS中call()、apply()、bind()改变this指向的原理
JS中call()、apply()、bind()改变this指向的原理
|
1月前
|
JavaScript 前端开发 算法
JavaScript 关键字 debugger 的作用和使用场景介绍
JavaScript 关键字 debugger 的作用和使用场景介绍
29 0
|
1月前
|
JavaScript 前端开发 编译器
编程笔记 html5&css&js 077 Javascript 关键字
编程笔记 html5&css&js 077 Javascript 关键字
|
2月前
|
JavaScript 前端开发
JavaScript中this的指向问题
JavaScript中this的指向问题
|
3月前
|
前端开发 JavaScript
揭开`this`的神秘面纱:探索 JavaScript 中的上下文密钥(下)
揭开`this`的神秘面纱:探索 JavaScript 中的上下文密钥(下)