call apply bind

Posted y丶卿

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了call apply bind相关的知识,希望对你有一定的参考价值。

为什么要使用call,apply,bind

  先看一个普通的对象:

var obj = {};
obj.name = "多啦A梦";
obj.say = function(){
    console.log("大雄你好我是"+this.name);
}
obj.say();//大雄你好我是多啦A梦

  我们对上面的函数做一些调整:

var obj = {};
obj.name = "多啦A梦";
obj.say = function(){
    console.log("大雄你好我是"+this.name);
}
var fn = obj.say;
fn();//大雄你好我是

   这个时候不会再输出“大雄你好我是多啦A梦”因为在第二个例子中this已经不是obj而变成了window而window中并没有name属性。

   为了能够达到我们预期的效果我们,我们可以使用call,apply或者bind,来实现我们的目的:

var obj = {};
obj.name = "多啦A梦";
obj.say = function(){
    console.log("大雄你好我是"+this.name);
}
var fn = obj.say;
fn.call(obj);//大雄你好我是多啦A梦

  在我们平时的开发中,可能我们会无意或者有意的改变函数运行时this的指向,为了能达到我们预期的效果我们可以使用call,apply,bind来改变函数运行时this的指向,让函数运行是的this指向第一个参数,这三个函数都可以改变函数运行时this的指向,当时他们也有一些不同,call和apply会立即执行函数,bind则是创建一个新的函数,更改新函数的this的指向。

call,apply

  首先call和apply在我们平时的开发中有两个妙用

  Array.prototype.slice.call(obj)//obj是一个类数组,通过他这个函数可以把参数的类数组转换成一个真正的数组

  Object.prototype.toString.call(arg)//arg可以是任意一个类型的值,这个函数最精确的判断出参数的类型

  call,apply在使用时会修正函数运行时this的指向,并且会立即执行函数。在只接受一个参数时两个函数的使用方式是一样的,使用方式如下:

//call使用
var obj = {};
obj.name = "多啦A梦";
obj.say = function(){
    console.log("大雄你好我是"+this.name);
}
var fn = obj.say;
fn.call(obj);
//apply使用
var obj = {};
obj.name = "多啦A梦";
obj.say = function(){
    console.log("大雄你好我是"+this.name);
}
var fn = obj.say;
fn.apply(obj);

  call和apply这两个函数在使用时也是有一些不同的,这个我们稍后再介绍。

bind

  bind函数的作用是创建一个新的函数,修改新函数运行时this的指向。

var obj = {};
obj.name = "多啦A梦";
obj.say = function(){
    console.log("大雄你好我是"+this.name);
}
var fn = obj.say.bind(obj);
fn();

  如果函数中需要参数则把参数放在bind的第二个参数或者后面

var skin= "蓝皮肤";
var eye = "大眼睛";
var obj = {};
obj.name = "多啦A梦";
obj.say = function(skin,eye){
    console.log("大雄你好我是"+skin+eye+"的"+this.name);
}
var fn = obj.say.bind(obj,skin,eye);
fn();

call

  call基本的使用方法我们已经知道,当call函数需要使用多个参数是和bind函数时一样的,第一个参数必须是this的指向,需要原函数需要参数,则在使用call时把参数挨个放在第一个参数的后面

var skin= "蓝皮肤";
var eye = "大眼睛";
var obj = {};
obj.name = "多啦A梦";
obj.say = function(skin,eye){
    console.log("大雄你好我是"+skin+eye+"的"+this.name);
}
var fn = obj.say;
fn.call(obj,skin,eye);

apply

  apply函数最多可以接收两个参数,第一个参数表示this的指向,第二个参数必须是一个数组或者类数组,数组的每一个元素表示原函数需要使用的参数

var skin= "蓝皮肤";
var eye = "大眼睛";
var obj = {};
obj.name = "多啦A梦";
obj.say = function(skin,eye){
    console.log("大雄你好我是"+skin+eye+"的"+this.name);
}
var fn = obj.say;
fn.apply(obj,[skin,eye]);

  apply在我们对一些函数做简便封装是会非常有用,比如我们简化console.log函数的操作我们可以这样:

function print(arg){
    console.log(arg);
}
print("hello");
//console.log是可以接收多个参数的所以为了更加符合console.log函数的特性我们可以稍加改造
function print(){
    console.log.apply(this,arguments);
}
print("hello",1,true);

 

以上是关于call apply bind的主要内容,如果未能解决你的问题,请参考以下文章

call,apply,bind的区别

call apply bind

手撕JavaScript call apply bind 函数

bind() call() apply()总结

超容易理解的call()apply()bind()的区别

javascript学习系列(20):数组中的bind,apply,call