前言:
隐式绑定有一个前提条件:
- 必须在调用的对象内部有一个对函数的引用(比如一个属性);
- 如果没有这样的引用,在进行调用时,会报找不到该函数的错误;
- 正是通过这个引用,间接的将this绑定到了这个对象上;
如果我们不希望在 对象内部 包含这个函数的引用,同时又希望在这个对象上进行强制调用,该怎么做呢?
-
JavaScript所有的函数都可以使用call和apply方法(这个和Prototype有关)。
-
它们两个的区别这里不再展开;
-
其实非常简单,第一个参数是相同的,后面的参数,apply为数组,call为参数列表;
-
-
这两个函数的一个参数都要求是一个对象,这个对象的作用是什么呢?就是给this准备的。
-
在调用这个函数时,会将this绑定到这个传入的对象上。
一、apply和call
function foo() {
console.log("函数被调用了")
}
// foo直接调用和call/apply调用的不同在于this绑定的不同
//foo直接调用指向的是全局对象(window)
foo()
foo.call()
foo.apply()
-
foo():直接调用函数 -
foo.call():使用call方法调用 -
foo.apply():使用apply方法调用 -
三种调用方式都会执行函数体,打印 "函数被调用了"
- 当
call和apply不传参数时,相当于直接调用函数
- 当
重要区别:
- 直接调用
foo()时,this指向全局对象(非严格模式)或undefined(严格模式) foo.call()和foo.apply()可以显式指定this绑定对象(虽然这里没传参数)
function foo() {
console.log("函数被调用了")
}
var obj = {
name: "obj"
}
foo.call(obj)
foo.apply(obj)
foo.capply("aaaa")
call和apply可以指定this的绑定对象
call和apply的区别
传参的方式不同:
function sum(num1, num2, num3) {
console.log(num1 + num2 + num3, this)
}
sum.call("call", 20, 30, 40)
sum.apply("apply", [20, 30, 40])
call接受参数列表apply接受参数数组
**call和apply在执行函数时,是可以明确绑定this的,这个绑定规则称之为显示绑定
二、bind
function foo() {
console.log(this)
}
// 默认绑定和显示绑定冲突:优先级(显示绑定)
var newFoo = foo.bind("aaa")
newFoo()
newFoo()
newFoo()
newFoo()
这里的this以后都是显示的绑定的对象
- 后续所有
newFoo()调用都会输出相同的this值 - 被注释掉的
foo.call("aaa")也展示了显示绑定,但每次都需要单独调用