this绑定规则-显示绑定

125 阅读2分钟

前言:

隐式绑定有一个前提条件:

  • 必须在调用的对象内部有一个对函数的引用(比如一个属性);
  • 如果没有这样的引用,在进行调用时,会报找不到该函数的错误;
  • 正是通过这个引用,间接的将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的绑定对象

image.png

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 接受参数数组

image.png

**call和apply在执行函数时,是可以明确绑定this的,这个绑定规则称之为显示绑定

二、bind

function foo() {
    console.log(this)
}

// 默认绑定和显示绑定冲突:优先级(显示绑定)
var newFoo = foo.bind("aaa")

newFoo()
newFoo()
newFoo()
newFoo()

这里的this以后都是显示的绑定的对象

  • 后续所有 newFoo() 调用都会输出相同的 this 值
  • 被注释掉的 foo.call("aaa") 也展示了显示绑定,但每次都需要单独调用