测试代码:
var a = 1; var obj = { a = 2; } function test(a){ alert(a); alert(this.a); }
1.test(3);
结果:3,1
函数中this指向window对象
2.test.call(thisObj,param1,param2....);
thisObj:test函数中this的指向
param1,param2...:传给test函数的参数
3.test.call(null,3)或者test.call(undefined,3);
结果为:1,3;
当thisObj是undefined或者null时,test中的this指向window
4.test.call(1,3);或者test.call("a",3)或者test.call(false,3)或者test.call([12],3)或者test.call(function(){},3)或者test.call(/ao/g,3);时
结果为:3,undefined
此时this的值为1,"a",flase,[12],function(){},/ao/g;里面没有a属性
5.test.call(obj,3);
结果为:3,2
6.test.apply(thisObj,[param1,param2...]);
除了给test传参数以数组形式,其他和test.call一样
7.test.bind(thisObj,param1,pamra2...);
bind()返回新的函数,这个函数是test的复制,但是里面的this指向thisObj
源码:
Function.prototype.bind = function(scope){ var fn = this; return function(){ fn.apply(scope); } }
案例:
1.
var x = 100; var foo = { x:200 } var bar = function(a,b){ console.log(this.x,a,b); } bar(1,2); var nBar = bar.bind(foo,4,5); nBar();
bar(1,2)打印出:100,1,2;this指向widdow;
nBar()打印出:200,4,5;this指向foo,而且nBar在创建时,将4,5保存到nBar的参数列表中
2.
var x = 100; var foo = { x:200 } var bar = function(a,b){ console.log(this.x,a,b); console.log(arguments); } bar(1,2); var nBar = bar.bind(foo,4,5); nBar(6,7);
nBar执行时:arguments里面保存了4,5,6,7
3.
var myDiv = document.getElementById("myDiv"); var logger = { x: 0, updateCount: function(){ this.x++; console.log(this.x); } } myDiv.addEventListener("click",logger.updateCount);
结果为:NaN
因为在监听器的处理函数中,this指向当前触发事件的对象,在这里是myDiv,为了使得在回调函数中的this指向logger,用logger.updateCount.bind(logger);
var myDiv = document.getElementById("myDiv"); var logger = { x: 0, updateCount: function(){ this.x++; console.log(this.x); } } myDiv.addEventListener("click",logger.updateCount.bind(logger));
4.
function list(){ Array.prototype.slice.call(arguments); } var list1 = new list(1,2,3); //[1,2,3] //创建一个自带默认参数的函数 var myList = list.bind(undefined,37); var list3 = myList(1,2,3); //37,1,2,3;