call,apply,bind初识

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

原文地址:https://www.cnblogs.com/zero18/p/10983822.html