this指向是一个比较头疼的问题,so……
this
this 即不指向函数自身,也不指向函数的词法作用域。在函数中this到底取何值,是在函数真正被调用执行的时候确定的,函数定义的时候确定不了。
this的取值大概有4种情况:
- 构造函数:
如果通过new的形式将函数赋值给一个变量,那么函数内部的this指向的是new出的对象;
如果是直接调用定义的函数没有new,那么this指向的就是window; - 作为对象的一个属性:
直接调用对象的属性,this指向的是当前对象;
作为一个给对象的赋值变量,this指向的是window; - 使用call && apply 调用;
this指向方法绑定的对象; - 全局或普通函数调用
this指向永远都是window。有一种情况下要注意:函数内定义的函数是普通函数,指向window。
隐式绑定是指在没有访问到当前this的时候,函数执行会默认绑定到window上;显式绑定式指以call/apply/bind的形式将this绑定在需求上;
绑定方法
-
call && apply
call 和 apply 都是接受2个变量:
第一个变量是绑定 this 的指向对象(将目标的this注入到当前调用绑定方法的需求方中),如果第一个参数是 null,undefined 的时候,this指向的是 window;
两个绑定不同之处是第二个变量:当函数需要传递多个变量时, apply 可以接受一个数组作为参数输入, call 则是接受一系列的单独变量。 -
bind
和call很相似,第一个参数是this的指向,从第二个参数开始是接收的参数列表。区别在于bind方法返回值是函数以及bind接收的参数列表的使用。
bind返回对应函数, 便于稍后调用; apply, call则是立即调用。
函数柯里化
把接受多个参数的函数变换成接受一个单一参数(最初函数的第一个参数)的函数,并且返回接受余下的参数且返回结果的新函数的技术。
//比如 plus 方法
// 不用柯里化
function plus(m,n){
return m+n;
}
// 使用柯里化
function plus(m){
return function(n){
return m+n;
}
}
绑定的手动实现方法
低版本的浏览器中没有实现绑定的方法:
if (!Function.prototype.bind) {
Function.prototype.bind = function () {
var self = this, // 保存原函数
context = [].shift.call(arguments), // 保存需要绑定的this上下文
args = [].slice.call(arguments); // 剩余的参数转为数组
return function () { // 返回一个新函数
self.apply(context, [].concat.call(args, [].slice.call(arguments)));
}
}
}
参考文章:
http://zhidian.wuute.com/html5dev/doku.php/46/16/66?&#概述
https://github.com/mqyqingfeng/Blog/issues/3
http://www.cnblogs.com/wangfupeng1988/p/3988422.html