JS中的call、apply、bind基础知识

799 阅读2分钟

javascript提供了call、apply、bind这三个方法,来切换或固定this的指向。

一、Function.prototype.call()

var obj = {}
var f = function () {
    return this
}
console.log(f() === window) // true
console.log(f.call(obj) === obj) // true

call方法的参数,应该是一个对象,如果参数为空、null、undefined,则默认传入全局对象

var obj = {
    n: 100
}
var n = 200
function f() {
    console.log(this.n)
}
f.call() // 200
f.call(obj) // 100
f.call(null) // 200
f.call(undefined) // 200
f.call(window) // 200

如果call方法参数是一个原始值,那么这个原始值会自动转化成对应的包装对象,然后传入call方法

var f = function () {    
    console.log(this)
}
f.call('abc') // String {"abc"}
f.call(2) // Number {2}
f.call(true) // Boolean {true}

call方法可以接受多个参数,第一个参数就是this要指向的对象,后面的参数则是函数调用时所需的参数

func(thisValue, arg1, arg2, ...)

function add(x, y) {    
    console.log(x + y)
}
add.call(this, 1, 2) // 3

二、Function.property.apply()

apply方法和call方法类似,唯一区别就是,apply方法接受一个数组作为函数执行时的参数

func.apply(thisValue, [arg1, arg2, ...])

function f(x, y) {
    console.log(x + y)
}
f.apply(this, [1, 2]) // 3

apply某些应用:

利用apply找出数组最大值

var a = [10, 2, 4, 15, 9]
var maxNum = Math.max.apply(null, a)
console.log(maxNum) // 15

利用apply将数组中的空元素转为undefined

var arr = ['a', , 'b']
console.log(Array.apply(null, arr)) // ["a", undefined, "b"]

三、Function.prototype.bind()

bind()方法用于将函数体内的this绑定到某对象,然后返回一个新函数

var counter = {
    num: 0,
    add: function () {
        this.num++
    }
}
var func = counter.add.bind(counter)
func()
console.log(counter.num) // 1

var obj = {
    num: 100
}
var func2 = counter.add.bind(obj)
func2()
console.log(counter.num) // 101

四、总结

call、apply、bind都有着改变this指向的作用,第一个参数都是目标对象

call和apply直接调用,bind返回一个新函数,手动执行才能调用

call和bind的参数以散列形式,apply的参数以数组形式