前端复习课 --- call、apply、bind

180 阅读3分钟

前端复习课 --- call、apply、bind

对于前端工程师来说面试基本必须提的一类问题,就是关于call,apply,bind的功能和区别了,今天我们就来复习一下它们各自的作用和它们到底有什么不同吧

1、call & apply

call和apply 功能相同,都可以理解为是用某个对象来调用某个方法,两个函数的第一个实参就是要用来调用函数的母对象,也就是调用函数的上下文,如果要在调用的方法中获取这个对象,可以用this获取,它们的基本原理可以理解为 将一个函数存储为母对象的方法,然后通过母对象调用,最后删除该方法,大致如下:

o.fn = fun; //挂载临时方法
o.fn();	//调用临时方法
delete o.fn;	// 删除临时方法

在严格模式下,第一个传入call和apply的第一个实参都会变成函数中this指向,非严格模式下,null和undefined会被全局对象代替,原始值被相应的包装对象代替。

那它们之间有什么不同捏? 那就是接受参数的不同,call 的接受参数的方式如下:

function.call(thisArg, arg1, arg2, ...)

而apply的 参数是放在一个数组或者类数组之中,会自动转换成后面的参数相当于解构了,如下:

function.apply(thisArg, [argsArray])

当我们不想为每个对象做一些同样的操作的时候比如在实例化一个对象的时候:

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

//当我们想创建一个类的时候,想要实现另一个函数的功能的时候,通过call去调用,达到一个方法复用的效果
function man(name, age){
  Person.call(this, name, age);
}
var m = new man('chang', 26);
console.log(m) //man {name: "chang", age: 26}

可以使用apply实现一些内置函数需要循环处理数组的编写方式,比如我们要去求一组数组中的最大值,我们会这么做:

var numbers = [1,4,2,6,4,8,9,45,34];
console.log(Math.max(numbers[0]),numbers[1],......) //这种就不说了 费时费力
//循环一下?
var maxNumber = -Infinity;
for(var i = 0; i< numbers.length; i++){
  maxNumber = numbers[i] > maxNumber ? numbers[i] : maxNumber
}
console.log(maxNumber)  // 确实可以搞出来,就是要写一些代码还要循环, 那我们用apply实现一下呢

var maxNumberByapply = Math.max.apply(null, numbers); // 额 这就完事了
console.log(maxNumberByapply); // 45

2、bind

bind方法是ES5中新增方法,它的主要作用就是将一个函数绑定到某个对象上去,通过bind方法传入一个对象o作为参数,返回一个新的函数,当调用这个新的函数时会当作时传入对象o的方法来调用,并且参数也会传递到原始函数中。例如:

function func (secondName) {
  return 'My Name is ' + this.firstName + secondName;
}
var o = {firstName : 'chen'};
var newFunc = func.bind(o);
var myname = newFunc('haha');   
console.log(myname) // 'My Name is chen haha'

bind 有一种应用就是函数的 “柯里化” ,什么是柯里化呢? 就把接受多个参数的函数变换成接受一个单一参数(最初函数的第一个参数)的函数,并且返回接受余下的参数而且返回结果的新函数的技术。 也可以说就是将一个参数固化然后返回新的函数,再传入新的参数,再返回 ....依此类推 , 对于柯里化之后我们单独再进行讲解,我们这里用bind简单解释其原理,实现一个累加计算:

function sum(b, c) { return this.a + b + c };
var f = sum.bind({a:5},10);
console.log(f(15)) // 30

以上就是今天的复习内容,这些函数还有还多种用法,可以在我们的开发的时候提供方便。