call,apply,bind

在JavaScript中,callapplybindFunction对象自带的三个方法,都是为了改变函数体内部 this 的指向。html

           apply 、 call 、bind 三者第一个参数都是 this 要指向的对象,也就是想指定的上下文;数组

           apply 、 call 、bind 三者均可以利用后续参数传参;app

                        bind 是返回对应 函数,便于稍后调用;apply 、call 则是当即调用 。dom

例子:函数

1.ui

function fruits() {}
 
    fruits.prototype = {
          color: 'red',
          say: function() {
          console.log('My color is' + this.color); 
              }
         }
 
  var apple = new fruits;
 apple.say();   // 此时方法里面的this 指的是fruits
 // 结果: My color is red

可是若是咱们有一个对象 banana= {color : 'yellow'} ,咱们不想从新定义 say 方法,那么咱们能够经过 call 或 apply 用 apple 的 say 方法:this

banana = {
color: 'yellow'
}
apple.say.call(banana); //此时的this的指向已经同过call()方法改变了,指向的是banana,this.color就是banana.color='yellow';
//结果是My color is yellow  
apple.say.apply(banana);//同理,此时的this的指向已经同过apply()方法改变了,指向的是banana,this.color就是banana.color ='yellow';
//My color is yellow
// 若是传入的是 null:

apple.say.apply(null); // null是window下的,此时,this 就指向了window ,可是window下并无clolr这个属性,所以this.clolr就是window.color=undefined;
//My color is undefined

2.对于 apply、call 两者而言,做用彻底同样,只是接受 参数 的方式不太同样。call 是把参数按顺序传递进去,而 apply 则是把参数放在数组 里。spa

var array1 = [12,'foo',{name:'Joe'},-2458];
var array2 = ['Doe' , 555 , 100];
Array.prototype.push.call(array1, array2);
// 这里用 call 第二个参数不会把 array2 当成一个数组,而是一个元素
//等价于array1.push(‘‘'Doe' , 555 , 100’’);
//array1.length=5;
 
Array.prototype.push.apply(array1, array2); // 这里用 apply 第二个参数是一个数组
 
// 等价于:  array1.push('Doe' , 555 , 100);
//array1.length=7;

3.类(伪)数组使用数组方法

var divElements = document.getElementsByTagName('div'); //虽然 divElements 有length属性,可是他是一个伪数组,不能使用数组里面的方法
Array.isArray(divElements);// false
 
var domNodes = Array.prototype.slice.call(document.getElementsByTagName('div'));
// 将数组对象Array里的this指向伪数组document.getElementsByTagName('div'), 
//slice() 方法可从已有的数组中返回选定的元素,不传参数是,返回整个数组 
Array.isArray(domNodes);// true

4. 验证一个对象的类型能够用:

Object.prototype.toString.call(obj) 

5.bind() 方法,MDN 的解释是:bind() 方法会建立一个 新函数,称为绑定函数,当调用这个绑定函数时,prototype

绑定函数会以建立它时传入 bind() 方法的第一个参数 做为 this,传入 bind() 方法的 第二个以及之后的参code

数加上绑定函数运行时自己的参数按照顺序做为原函数的参数来调用原函数。

var bar = function(){
    console.log(this.x);
}
var foo = {
    x:3
}
bar(); // undefined
var func = bar.bind(foo); //此时this已经指向了foo,可是用bind()方法并不会当即执行,而是建立一个新函数,若是要直接调用的话 能够 bar.bind(foo)()


func(); // 3

6.在 Javascript 中,屡次 bind() 是无效的。更深层次的缘由, bind() 的实现,至关于使用函数在内部包了一个 call / apply ,第二次 bind() 至关于再包住第一次 bind() ,故第二次之后的 bind 是没法生效的。

var bar = function(){
  console.log(this.x);
}
var foo = {
  x:3
}
var sed = {
  x:4
}
var func = bar.bind(foo).bind(sed);
func(); //3
  
var fiv = {
  x:5
}
var func = bar.bind(foo).bind(sed).bind(fiv);
func(); //3

7.apply、call、bind 三者相比较,之间又有什么异同呢?什么时候使用 apply、call,什么时候使用 bind 呢。简单的一个例子:

var obj = {
  x: 81,
};
  
var foo = {
  getX: function() {
    return this.x;
  }
}
console.log(foo.getX.bind(obj)());  //81
console.log(foo.getX.call(obj));    //81
console.log(foo.getX.apply(obj));   //81

参考:

相关文章
相关标签/搜索