call,apply和bind

115 阅读2分钟

代码示例:

let person = {
    name: 'emma',
    sayhi(){
        console.log(this.name)
    }
}
person.sayhi()

结果为

image.png

  1. call的用法 call是指定一个this和一个或多个参数调用函数,用法如下方代码所示:
let person = {
    name: 'emma',
    sayhi(){
        console.log(this.name)
    }
}
person.sayhi.call({name:'jack'})

结果为 image.png 可以看出call方法第一个参数需要指定this,但是若该函数或方法没有返回值,则第一个参数为undefined或null,代码示例如下

function f1(a,b){
    return a+b
}
f1.call(undefined,1,2)
  1. apply用法 同call的用法类似,只不过,第二个参数需要传递的为一个数组,代码示例如下
function f1(a,b){
    return a+b
}
f1.apply(undefined,[1,2])
  1. bind的用法 bind也可以制定this,但是和call和apply直接在函数后使用不同的是,bind绑定this后会返回一个函数(闭包),代码示例
this.x = 3
let f1={
    x: 1,
    value(){
        return this.x
    }
}
let result = f1.value
console.log(result())
let result2 = result.bind(f1)
console.log(result2())

image.png 这是一条来自后期的备注:要注意,apply和call是改变了this以后立即执行的,而bind则是返回了改变上下文的一个函数

function test(a,b,c,d) { 
  var arg = Array.prototype.slice.call(arguments,1); 
  console.log(arg); 
} 
test("a","b","c","d"); //b,c,d

此外Array.prototype.slice.call()能把伪数组对象转化成数组,伪数组(例如通过document.getElementsByTagName获取的元素、含有length属性的对象)具有length属性,并且可以通过0、1、2…下标来访问其中的元素,但是没有Array中的push、pop等方法。就可以利用call,apply来转化成真正的数组,就可以使用数组的方法了 转换成数组的方式

var args = Array.prototype.slice.call(arguments);
var args = [].slice.call(arguments);

// ES2015
const args = Array.from(arguments);
const args = [...arguments];

由结果可以看出result返回3是因为它是从全局作用域调用x,但是result2使用bind绑定了this为f1所以调用的为f1中的x所以为1