js中this的指向问题

5 篇文章 0 订阅
5 篇文章 0 订阅

在 JavaScript 中,this 是一个特殊的关键字,它指向当前函数或方法所属的对象。在不同情况下,this 的指向可能会不同,这取决于函数或方法被调用的方式。

  • 在非箭头函数下, this 指向调用其所在函数的对象,而且是离谁近就是指向谁(此对于常规对象,原型链, getter & setter等都适用);
  • 构造函数下,this与被创建的新对象绑定;
  • DOM事件,this指向触发事件的元素;
  • 内联事件分两种情况,bind绑定, call & apply 方法等。

1、在全局环境下,this指向window对象

// 在浏览器中,全局对象为 window 对象:
console.log(this === window); // true

this.a = 30;
console.log(window.a); // 30

2、函数上下文调用

简单来说就是谁调用这个函数,this就指向谁

function foo(num){
    console.log("foo: " + num);

    //记录foo被调用次数
    this.count++;
}

foo.count = 0;

for(let i=0; i<10; i++){
    if(i > 5){
        foo(i);
    }
}

console.log(foo.count); // 0

这里打印是0的原因是因为调用foo方法的是window对象,但是window对象中并没有count这个属性,因此每次执行this.count++的时候都是undefined,最后打印到的foo.count还是0。

3、对象中的this

let o = {
let o = {
  prop: "hello",
  f: function() {
    console.log(this.prop);
  }
};

o.f(); // 输出 "hello"
let a = o.f
a()//输出undefined,此时相当于window.a(),this指向window对象

4、构造函数中的this

构造函数中的this与被创建的新对象绑定。

function fruit(name){
    console.log(name, this);
}

const f1 = new fruit('apple');  // apple fruit {}
const f2 = new fruit('banana'); // banana fruit {}
console.log(f1, f2, f1 === f2); // fruit {} fruit {} false

从上面例子可以看出来f1和f2的this是不一样的

5、显式绑定(call和apply绑定this时会调用一次函数,bind则不会调用)

1、call、apply
apply 方法接受一个数组或类数组作为函数的参数,而 call 则接受多个参数列表。

// 水果对象
function fruit(){
    console.log(this.name, arguments);
}

var apple = {
    name: '苹果'
}

var banana = {
    name: '香蕉'
}

fruit.call(banana, banana, apple)  // 香蕉 { '0': { name: '香蕉' }, '1': { name: '苹果' } }
fruit.apply(apple, [banana, apple]) 苹果 { '0': { name: '香蕉' }, '1': { name: '苹果' } }

2、bind
下面是bind绑定的示例,只是将一个值绑定到函数的this上,并将绑定好的函数返回,只有在fruit函数才会输出信息,例:

function fruit(){
    console.log(this.name);
}
let apple = {
    name: '苹果'
}
fruit = fruit.bind(apple);
fruit(); // 苹果

6、this的优先级问题

  1. new绑定
  2. 显式绑定
  3. 隐式绑定
  4. 默认绑定(严格模式下会绑定到undefined)

7、箭头函数的this

由于箭头函数不绑定this, 它会捕获其所在(即定义的位置)上下文的this值, 作为自己的this值,所以 call() / apply() / bind() 方法对于箭头函数来说只是传入参数,对它的 this 毫无影响。

function Person() {  
    this.age = 0;  
    setInterval(() => {
        // 回调里面的 `this` 变量就指向了期望的那个对象了
        console.log(this)
    }, 3000);
}

var p = new Person();
  • 2
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值