JS中this的绑定规则和其他细节

本文详细介绍了JavaScript中this的四种绑定规则:默认绑定、隐式绑定、显示绑定(call/apply/bind)和new绑定,以及它们的优先级。通过示例代码解释了每种绑定规则的使用场景和特点,并特别提到了this的其他特殊绑定情况,如箭头函数的this绑定。此外,还讨论了this在不同环境(浏览器、Node.js)下的表现。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

目录

一、this在全局作用域下被使用

二、this的四个绑定规则

1.默认绑定(独立函数调用)

2. 隐式绑定(通过某个对象调用)

3.显示绑定(call/apply/bind)

4.new绑定

三、四个规则的优先级

四、this的其他特殊绑定


一、this在全局作用域下被使用

先看以下代码:

// 在浏览器运行
// 在node环境下运行
console.log(this)

1.两种情况:

  • 在浏览器中:this指向window
  • 在Node环境中:this指向一个空对象{}

 node环境下的执行顺序:node会将这个文件当成一个module,然后加载这个模块,然后进行编译,再将这些代码放到一个函数中,然后执行这个函数,再用call绑定一个空对象,所以node环境下的this是一个空对象

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

// 1.直接调用这个函数
foo()

// 2.创建一个对象, 对象中的函数指向foo
var obj = {
  name: 'why',
  foo: foo
}

obj.foo()

// 3.apply调用
foo.apply("abc")

2.总结:

  • 函数在调用时,JavaScript会默认给this绑定一个值;
  • this的绑定和定义的位置没有关系;
  • this的绑定和调用方式以及调用的位置有关系;
  • this是在运行时被绑定的;

二、this的四个绑定规则

1.默认绑定(独立函数调用)

默认绑定相当于独立函数的调用,我们可以理解成函数没有被绑定到某个对象上进行调用

代码示例:

// 1.例子一
function foo() {
  console.log(this)
}

foo()  // 输出window


// 2.例子二
var obj = {
  name: "why",
  foo: function() {
    console.log(this)
  }
}

var bar = obj.foo
bar() // window

2. 隐式绑定(通过某个对象调用)

是通过某个对象进行调用的 ,也就是它的调用位置中,是通过某个对象发起的函数调用 。

代码示例:

// 1.例子一:
var obj = {
  name: "why",
  foo: foo
}

obj.foo() // obj对象

// 2.例子二:
var obj1 = {
  name: "obj1",
  foo: function() {
    console.log(this)
  }
}

var obj2 = {
  name: "obj2",
  bar: obj1.foo
}

obj2.bar()

3.显示绑定(call/apply/bind)

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

显示调用:我们不希望在 对象内部 包含这个函数的引用,同时又希望在这个对象上进行强制调用,使用call和 apply方法 ,call/apply是可以指定this的绑定对象

代码示例:(apply/call)

function sum(num1, num2, num3) {
  console.log(num1 + num2 + num3, this)
}

sum.call("call", 20, 30, 40)
sum.apply("apply", [20, 30, 40])

代码示例:(bind,如果我们希望一个函数总是显示的绑定到一个对象上,那么就使用bind)

解析:foo.bind('aaa'), this绑定了字符串aaa,然后返回一个函数,调用这个函数,这个函数的this都是指向字符串aaa

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

var newFoo = foo.bind("aaa")

newFoo()
newFoo()
newFoo()

注意:默认绑定和显示绑定bind冲突:优先级(显示绑定) ,如上图

4.new绑定

JavaScript中的函数可以当做一个类的构造函数来使用,也就是使用new关键字

​使用new关键字来调用函数是,会执行如下的操作:

​(1) 创建一个全新的对象;

​(2) 这个新对象会被执行prototype连接;

​(3) 这个新对象会绑定到函数调用的this上(this的绑定在这个步骤完成);

​(4) 如果函数没有返回其他对象,表达式会返回这个新对象;

代码示例:

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

var p1 = new Person("why", 18)
console.log(p1.name, p1.age)

var p2 = new Person("kobe", 30)
console.log(p2.name, p2.age)

三、四个规则的优先级

1.默认规则的优先级最低

2.显示绑定优先级高于隐式绑定

obj.foo.apply('abc')
obj.foo.call('abc')

3.new绑定优先级高于隐式绑定

var obj = {
  name: "obj",
  foo: function() {
    console.log(this)
  }
}

var f = new obj.foo()

4.new绑定优先级高于bind

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

var bar = foo.bind("aaa")

var obj = new bar()

四、this的其他特殊绑定

1. 如果在显示绑定中,我们传入一个null或者undefined,那么这个显示绑定会被忽略,使用默认规则

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

foo.apply(null)
foo.apply(undefined)

var bar = foo.bind(null)
bar()

2.创建一个函数的 间接引用,这种情况使用默认绑定规则 ,因为赋值(obj2.foo = obj1.foo)的结果是foo函数

var obj1 = {
  name: "obj1",
  foo: function() {
    console.log(this)
  }
}

var obj2 = {
  name: "obj2"
};

(obj2.bar = obj1.foo)()

3.箭头函数的this绑定

箭头函数并不绑定this对象,那么this引用就会从上层作用于中找到对应的this

var name = "why"

var foo = () => {
  console.log(this)
}

foo()
var obj = {foo: foo}
obj.foo()
foo.call("abc")

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值