js-this指向谁?

this是在运行时进行绑定的,并不是在编写时绑定,它的上下文取决于函数调用时。this的绑定与函数声明的位置无关,只取决于函数的调用方式。

this的四种调用模式:

  1. 普通函数调用模式
  2. 对象方法调用模式
  3. 构造器调用模式
  4. call()、apply()、bind()

1.普通函数调用模式

函数调用模式中的函数不是对象的属性值,而是直接作为函数调用,在这种模式下this指向全局对象。

function test() {
    this.a = 3
}
test() //直接调用
console.log(a); // 3

如果上述代码运行在浏览器上,则a会被挂载到全局对象window上;如果运行在node环境下,则会挂载到全局对象global上。

2.对象方法调用模式

方法调用模式是指函数作为对象的的属性(方法)被调用。

const obj = {
    name: 'lisi',
    age: 13,
    sayName: sayName
}

function sayName() {
    console.log(this.name);
}

obj.sayName() //lisi


//添加额外代码
const obj2 = {
    name: 'zs',
    age: 12,
    sayName: obj.sayName
}

obj2.sayName() //zs

上述代码中,obj.sayName()执行时,由于是obj调用sayName,所以this指向obj,结果打印lisi;obj2.sayName()也是同样的道理,但是obj2中有个迷惑性的地方obj2的sayName属性值是obj.sayName,obj.sayName只是函数的内存地址,并不是调用。总结而言,作为对象方法调用时,只需要看方法的调用者是谁就行了。

3.构造器调用模式

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

const p1 = new Person('lisi')
console.log(p1.name); //lisi

通过构造函数创建一个实例后,那么this就会指向这个实例。当然其结果是因为new操作时会自动执行一些操作。

  1. 在内存中创建一个新对象
  2. 将新对象的原型指向构造函数的prototype的值
  3. 将新对象赋值给构造函数内部的this(this指向新对象)
  4. 执行构造函数内部代码(给新对象添加属性和方法)
  5. 如果构造函数返回非空对象,则返回该对象;否则返回刚创建的新对象

我们可以看出,上述操作中有this指向这个新对象这一步,这就是this指向这个实例的原因。

4.call、apply、bind

使用call、apply、bind可以显示地将this指向某个对象。

//运行在浏览器上
var name = 'zs'
    
function sayName() {
    console.log(this.name);
}

const obj = {
    name: 'lisi'
}

sayName() //zs

function test() {
    sayName.call(obj)
}

test() //lisi

以上代码中直接执行sayName时打印的是zs,但是通过test函数sayName.call()执行后,打印的是lisi。这说明了,第一次打印时,this指向的是全局;而第二次打印时,this指向的是obj。call的作用就是显示的更改了this的指向,同理apply与bind也是,而且使用方法大体相同。

apply与call的区别(面试中比较常见)

apply与call第一个参数都是this将指向的对象;apply第二个参数是一个数组作为参数,call第一个参数后可以接收任意个参数。

5.几种调用模式的优先级

构造器调用 > call、apply、bind > 对象方法调用 > 普通方法调用

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值