码迷,mamicode.com
首页 > 编程语言 > 详细

Effective JavaScript Item 20 使用call方法来绑定this变量

时间:2014-09-16 10:45:50      阅读:187      评论:0      收藏:0      [点我收藏+]

标签:读书笔记   编程实践   javascript   

本系列作为Effective JavaScript的读书笔记。


通常而言,一个函数中this的指向和该函数的调用类型相关,比如当函数直接作为函数被调用时,this一般指向的是全局对象(StrictMode时指向undefined);当函数作为方法被调用时(x.method()这种形式)this指向的是x;当函数作为构造方法被调用时,this指向的是一个新创建的对象。

 

但是在一些场合,需要指定this的指向,比如下面的代码需要将this指向一个对象obj,一个简单的办法如下:


obj.temporary = f; // what if obj.temporary already existed?
var result = obj.temporary(arg1, arg2, arg3);
delete obj.temporary; // what if obj.temporary already existed?

但是上述代码假设obj上没有属性叫做temporary,在实际代码中,作出这样的假设显然是不太好的。而且,在某些场合,对象也许会被设置成为不能扩展,也就是不能为它们添加新的属性。而且对不由你创建的对象添加属性也不是一个好的行为,在Item 42中会详细讨论这一点。

 

幸运的是,function提供了内置的call方法来处理这一问题:


f.call(obj, arg1, arg2, arg3);

call方法的第一个参数设置的就是this的指向。

 

使用call方法来调用方法的好处之一:

即使某个对象并没有该方法,也可以通过设置this的指向完成对于该方法的调用,比如:


var hasOwnProperty = {}.hasOwnProperty;
dict.foo = 1;
delete dict.hasOwnProperty;
hasOwnProperty.call(dict, "foo"); // true
hasOwnProperty.call(dict, "hasOwnProperty"); // false

上述代码首先通过一个空对象取到了hasOwnProperty方法,然后使用call方法来判断某个dictionary对象上是否存在某个key

 

call方法在定义高阶函数的时候也有用处。在使用高阶函数时一个常见的需求就是提供this的指向,比如:


var table = {
	entries: [],
	addEntry: function(key, value) {
		this.entries.push({ key: key, value: value });
	},
	forEach: function(f, thisArg) {
		var entries = this.entries;
		for (var i = 0, n = entries.length; i < n; i++) {
			var entry = entries[i];
			f.call(thisArg, entry.key, entry.value, i);
		}
	}
};

上述forEach方法定义了两个参数:

f:一个回调函数

thisArgthis的具体指向

 

一个例子是将table1中的所有键值对全部拷贝到table2中:


table1.forEach(table2.addEntry, table2);

注意到以上的代码在执行回调函数的时候,传入了除this指向外的另外三个参数,分别是keyvalue以及index,然后在addEntry方法中并没有定义index参数,这种行为在JavaScript中是合法的,多余的参数会被自动忽略掉,当然如果需要访问并未定义的参数,也可以通过arguments这一变量进行获取。

 

总结:

  1. 使用call方法来在调用函数的时候确定this的指向
  2. 使用call方法来调用对象上并不存在的方法
  3. 使用call方法来定义高阶函数,让调用者可以指定回调函数中this的指向

Effective JavaScript Item 20 使用call方法来绑定this变量

标签:读书笔记   编程实践   javascript   

原文地址:http://blog.csdn.net/dm_vincent/article/details/39313317

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!