apply、call 有什么作用,什么区别?
两者都可以特殊化设置传入函数执行上下文(个人理解就是所处环境的变化,就是传入对象直接替代window的环境),这样设置this值的作用。
区别:
两者的参数设置不一样,在call
中第一个参数是设置this
的值,而如果该函数如含有若干个参数,就以参数列表的形式去写入,如:
1 2 3 4 5 6 7 8 9 10
| var obj = { name : "Kevin", fn : function(name,age){ this.name = name; this.age = age; console.log(this); } } var fn2 = obj.fn; fn2.call(obj,"baiji",12);
|
如果理解了上述环境,那apply
就更好理解了,apply
同样的第一个参数是设置this
的值,但想将参数传入的写法则是以一个参数数组的方式写入。
1 2 3 4 5 6 7 8 9 10
| var obj = { name : "Kevin", fn : function(name,age){ this.name = name; this.age = age; console.log(this); } } var fn2 = obj.fn; fn2.apply(obj,["baiji",12]);
|
代码
1. 以下代码输出什么?
1 2 3 4 5 6 7 8
| var john = { firstName: "John" } function func() { alert(this.firstName + ": hi!") } john.sayHi = func // Func 绑定到了john.sayHi上 john.sayHi() // 弹出"John: hi!",因为这时候this指向jhon
|
2. 下面代码输出什么,为什么?
1 2 3 4
| func() // 弹出object window,等同于window.func(); function func() { alert(this) }
|
3. 下面代码输出什么?
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16
| function fn0(){ function fn(){ console.log(this); } fn(); } fn0(); //window 还是window调用了fn0()函数 document.addEventListener('click', function(e){ console.log(this); // document DOM中谁绑定,this就是谁 setTimeout(function(){ console.log(this); // window,定时器会排队列的最后,最后还是window调用这个定时器 }, 200); }, false);
|
4. 下面代码输出什么,why?
1 2 3 4 5 6 7 8
| var john = { firstName: "John" } function func() { alert( this.firstName ) } func.call(john) // alert("Jhon")
|
因为就想开头的解释到,call
的第一个参数就是设置this的指向。
5. 代码输出?
1 2 3 4 5 6 7 8 9 10
| var john = { firstName: "John", surname: "Smith" } function func(a, b) { alert( this[a] + ' ' + this[b] ) } func.call(john, 'firstName', 'surname') // alert( "Jhon Smith"); 执行上下环境在john中
|
6. 以下代码有什么问题,如何修改?
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28
| var module= { bind: function(){ $btn.on('click', function(){ console.log(this) //this指 $btn this.showMsg(); // 由于$btn 没有showMsg属性,会报错 }) }, showMsg: function(){ console.log('饥人谷'); } } // 修改 var module= { bind: function(){ var temp = this; $btn.on('click', function(){ console.log(temp) temp.showMsg(); }) }, showMsg: function(){ console.log('饥人谷'); } }
|