var fu = function(one,two){
log(this,one,two);
};
var r={}, g={}, b={}, y={};
r.method = fn;
1.r.method(g,b);
2.fn(g,b);
3.fn.call(r,g,b);
4.r.method.call(y,g,b);
5.setTimeout(fn,1000);
6.setTimeout(r.method,1000);
7.setTimeout(function(){
r.method(g,b);
},1000);
以上7种情况中:
1.通过点符号(.),我们以对象属性的方式调用了该属性所对应的函数,由此也传入了第三个参数,点符号左边的值在这个函数调用中,被自动命名为this
2.当你没有点符号来为关键词this传入一个具体的绑定时,JavaScript会默认将this绑定为全局对象,这与函数在没有足够输入输入参数的情况下比调用时,JavaScript将undefined绑定到定位参数上是相似的,如果我们没有在括号间传入输入参数,one和two就会被绑定到undefined。类似的,当没有点符号,this将会被绑定到默认的全局对象。
###点符号是我们为关键词this传入绑定的机制方法,因此,没有点符号,参数this就会被绑定为某些默认的值
3.通过使用函数的内置方法.call,我们可以重写默认的全局对象绑定,以及点符号左侧的规则,我们可以传入任何我们想要的值,并将其绑定到关键词this上。在使用方法.call时,我们在参数列表的开头传入了一个额外的值,这个值就会被绑定到参数this上,所以当我们使用函数的属性.call去访问函数时this绑定到了r上。
4.同3,此时this绑定到了y上。
5.在setTimeout中调用回调函数,this中绑定到了global上(全局对象)。
6.尽管这里使用了点符号来传入r对象,因为判断this绑定的位置不是函数定义中,也不是在函数所处的对象中,而是在这个函数被调用的地方,由于我们在红色对象中进行了属性查找,我们常常会认为“查找”这个动作可能和函数中的关键词this有关,但其实在此时它们是不相关的,因为只有在调用的时刻才会影响参数this的绑定。因此this绑定了global上。
###例子6中,失去绑定的问题很普遍,这是因为任何一个像setTimeout一样将另一个函数作为回调函数的函数在调用函数时,都有可能与你的预期发生偏差。回调函数本很就被设计为由它们被传入的系统调用,因此,你基本无法控制传入的参数最终所绑定的内容,正因如此,你需要对所有的参数绑定都保持谨慎,包括参数this。每当你将一个函数作为输入参数传入另一函数时,尽管在传入函数时,你看到有对象在点符号的左边,但这个对象并不会被传入成为参数this的绑定。
7.这种写法可以很好的避免6中的情况,此时this绑定到了r上。
总结:关键词this使得我们可以仅创建一个函数对象就可以将其作为方法用在一些其它的对象上,每次我们调用该方法时,它可以访问任意使用它的对象,这对于节省内存非常有用,而这都是因为我们能够访问参数this才得以实现。