call、apply、bind三者是Function对象自带的方法
作用:
改变this指向
返回值:
call、apply 是返回一个立即执行函数
bind返回一个函数,也便于稍后调用
使用方法:
call与apply两者作用完全相同,不同的是接收参数的方式不太一样。call是将参数按顺序传递进去,
而apply将是把参数放在数组里。
bind()方法会创建一个新的函数,称之为绑定函数。当调用这个绑定函数的时候,绑定函数会以创建它时
传入bind()方法的第一个参数作为this,传入bind()方法的第二个以及以后的参数加上绑定函数运行时
本身的参数按照顺序作为原函数的参数来调用原函数。
call(this 要指向的对象(想指定的上下文),参数1,参数2,参数3,参数4,......,参数n)
apply(this 要指向的对象(想指定的上下文),[参数1,参数2,参数3,参数4,......,参数n])
适用场景:
JavaScript 中,某个函数的参数数量是不固定的,因此要说适用条件的话,当你的参数是明确知道数量时用 call 。
而不确定的时候用 apply,然后把参数 push 进数组传递进去。当参数数量不确定时,函数内部也可以通过 arguments 这个数组来遍历所有的参数。
常见实例:
(一)call
(1):数组之间追加
1 var array1 = [12,'foo',{name:'Joe'},-2458]; 2 var array2 = ['Doe' , 555 , 100]; 3 Array.prototype.push.call(array1, array2); 4 console.log(array1) // [12,'foo',{name:'Joe'},-2458,['Doe' , 555 , 100]] 5 console.log(array1.length) //5
1 var array1 = [12,'foo',{name:'Joe'},-2458]; 2 var array2 = ['Doe' , 555 , 100]; 3 Array.prototype.push.call(array1, ...array2); 4 console.log(array1) //[12,'foo',{name:'Joe'},-2458,'Doe' , 555 , 100] 5 console.log(array1.length) //7
(2):获取数组中的最大值和最小值
1 var numbers = [5, 458 , 120 , -215 ]; 2 var maxInNumbers = Math.max.call(Math,5, 458 , 120 , -215); //458
(二)apply
(1):数组之间追加
1 var array1 = [12,'foo',{name:'Joe'},-2458]; 2 var array2 = ['Doe' , 555 , 100]; 3 Array.prototype.push.apply(array1, array2); 4 console.log(array1) //[12,'foo',{name:'Joe'},-2458,'Doe' , 555 , 100] 5 console.log(array1.length) //7
(2):获取数组中的最大值和最小值
1 var numbers = [5, 458 , 120 , -215 ]; 2 var maxInNumbers = Math.max.apply(Math, numbers), //458
(三)bind
1 var bar = function(){ 2 console.log(this.x); 3 } 4 var foo = { 5 x:3 6 } 7 bar(); // undefined 8 var func = bar.bind(foo); 9 10 console.log(func) //ƒ (){ console.log(this.x);} 返回的是函数体 11 func(); // 3
推荐写法:
1 var bar = function(){ 2 console.log(this.x); 3 } 4 var foo = { 5 x:3 6 } 7 bar(); // undefined 8 var func = bar.bind(foo)(); 9 10 console.log(func) //3
call、apply、bind三者使用比较:::
1 var obj = { 2 x: 81, 3 }; 4 5 var foo = { 6 getX: function() { 7 return this.x; 8 } 9 } 10 console.log(foo.getX.bind(obj)()); //81 11 console.log(foo.getX.call(obj)); //81 12 console.log(foo.getX.apply(obj)); //81
(四)验证对象的数据类型:(前提是toString()方法没有被重写过)
1 Object.prototype.toString.call(obj)
(五)补充:伪数组
Javascript中存在一种名为伪数组的对象结构。比较特别的是 arguments 对象,还有像调用 getElementsByTagName , document.childNodes 之类的,它们返回NodeList对象都属于伪数组。不能应用 Array下的 push , pop 等方法。我们能通过 Array.prototype.slice.call 转换为真正的数组的带有 length 属性的对象,这样 domNodes 就可以应用 Array 下的所有方法了。
1 function log(){ 2 console.log(arguments) //Arguments(5) [1, 2, 3, 4, 5, callee: ƒ, Symbol(Symbol.iterator): ƒ] 3 var args = Array.prototype.slice.call(arguments) 4 console.log(arguments) //Arguments(5) [1, 2, 3, 4, 5, callee: ƒ, Symbol(Symbol.iterator): ƒ] 5 args.unshift('(app)') 6 console.log.apply(console,args) //(app) 1 2 3 4 5 7 } 8 log(1,2,3,4,5)
参考:
https://www.cnblogs.com/zhg277245485/p/6559475.html
http://www.admin10000.com/document/6711.html