关于js中call、apply、bind方法的区别

本文介绍了JavaScript中call、apply及bind方法的功能及其差异,包括如何改变函数内部this的指向。此外,还展示了这些方法在实际开发中的应用场景,如求解数组最大最小值、转化伪数组为标准数组等。

call、apply、bind的作用

简单来讲,这三个函数存在的意义是 改变函数执行时的上下文, 说的再具体一点就是 改变函数运行时的this指向

例如

function Person(name){
   this.name = name;
}

Person.prototype = {
   constructor: Person,
   showName: function(){
      console.log(this.name);
   }
};
var person = new Person('duo');
person.showName();

上面的代码中person调用showName方法后会在浏览器的控制台输出duo

然后

ar animal = {
  name: 'cat'
}

上面代码中有一个对象字面量,他没有所谓的showName方法,但是我还是想用?怎么办?call、apply、bind可以帮我们干这件事。

// 1 call
person.showName.call(animal);
// 2 apply
person.showName.apply(animal);
// 3 bind
person.showName.bind(animal)();

很神奇,控制台输出了三次cat

我们拿别人的showName方法,并动态改变其上下文帮自己输出了信息,说到底就是实现了复用

call、apply、bind的区别

上面看起来三个函数的作用差不多,干的事几乎是一样的,那为什么要存在3个家伙呢,留一个不就可以。所以其实他们干的事从本质上讲都是一样的动态的改变this上下文,但是多少还是有一些差别的…


call、apply与bind的差别

call和apply改变了函数的this上下文后便执行该函数,
bind则是返回改变了上下文后的一个函数


call、apply的区别

他们俩之间的差别在于参数的区别,call和apply的第一个参数都是要改变上下文的对象,而call从第二个参数开始以参数列表的形式展现,apply则是把除了改变上下文对象的参数放在一个数组里面作为它的第二个参数。

fn.call(obj, arg1, arg2, arg3...);
fn.apply(obj, [arg1, arg2, arg3...]);

应用

知道了怎么使用和他们之间的区别,接下来我们来了解一下通过call、apply、bind的常见应用场景。

  • 求数组中的最大和最小值
var arr = [34,5,3,6,54,6,-67,5,7,6,-8,687];

Math.max.apply(Math, arr);
Math.max.call(Math, 34,5,3,6,54,6,-67,5,7,6,-8,687);

Math.min.apply(Math, arr);
Math.min.call(Math, 34,5,3,6,54,6,-67,5,7,6,-8,687);
  • 将伪数组转化为数组

js中的伪数组(例如通过 document.getElementsByTagName 获取的元素)具有length属性,并且可以通过0、1、2…下标来访问其中的元素,但是没有Array中的push、pop等方法。我们可以利用call、apply来将其转化为真正的数组这样便可以方便地使用数组方法了。

var arrayLike = {
  0: 'zhangsan',
  1: 'lisi',
  2: 'wangwu',
  length: 3
}

上面就是一个普通的对象字面量,怎么把它变成一个数组呢?最简单的方法就是

var arr = Array.prototype.slice.call(arrayLike);

上面arr便是一个包含arrayLike元素的真正的数组啦( 注意数据结构必须是以数字为下标而且一定要有length属性 )

  • 数组追加

在js中要往数组中添加元素,可以直接用push方法

var arr1 = [1,2,3];
var arr2 = [4,5,6];

[].push.apply(arr1, arr2);

// arr1 [1, 2, 3, 4, 5, 6]
// arr2 [4,5,6]
  • 判断变量类型

对于对象型的数据类型,我们可以借助call来得知他的具体类型,例如数组


function isArray(obj){
  return Object.prototype.toString.call(obj) == '[object Array]';
}
isArray([]) // true
isArray('duo') // false
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值