this的指向问题、箭头函数和普通函数的区别

this的指向问题(this指向一般谁调用它,它就指向谁)

  • 全局执行上下文中,非严格模式下this指向window,严格模式下this指向undefined,在node.js中this指向global
console.log(this); // 在浏览器中输出 window 对象
  • 函数调用(此时函数不是作为一个对象的属性,是直接函数来调用的)
    当为普通函数时,this指向window,严格模式下指向undefined
    当函数为箭头函数时,绑定的是父作用域的this指向
function example() {
  console.log(this); // 非严格模式下输出 window,严格模式下输出 undefined
}
example();
  • 当一个函数作为一个对象的方法来调用的时候,this指向这个对象,同样箭头函数除外,它会捕获其所在上下文的this
const obj = {
  name: 'Object Name',
  greet: function() {
    console.log('Hello, ' + this.name);
  }
};
obj.greet(); // 输出: Hello, Object Name
  • 构造函数中的this,使用new关键字创建对象时,this在构造函数中指向新创建的对象
function Person () {
  console.log(this)
  this.name = '妹妹'
}
var obj = new Person() // 得到一个实例化对象,继承了Person函数的属性
console.log(obj)
  • 事件中的this,在事件处理中this通常指向触发事件的元素
const button = document.getElementById('myButton');
button.addEventListener('click', function() {
  console.log(this); // 输出: button 元素
});
  • apply、call、bind中的this,apply和call改变的是函数运行时的this的指向,bind返回一个this绑定了传入对象的新函数。这个函数的this指向使用new时会被改变,直接使用该函数this指向传如的对象。
const obj = { name: '妹妹', age: 18 }
function Person () {
  console.log(this.name)
}
Person.apply(obj) 
Person.call(obj) 
Person.bind(obj)

  • 箭头函数,箭头函数没有自己的this上下文,它会捕获其所在上下文的this的值,作为自己的this的值
const obj = {
  name: 'Object Name',
  greet: () => {
    console.log('Hello, ' + this.name);
  }
};
obj.greet(); // 箭头函数中的 this 指向全局对象或undefined(严格模式)
  • setTimeout,setInterval中的this
    全局中
function timer() {
  console.log(this);
}
setTimeout(timer, 1000); // 在浏览器中,this 指向 window 对象
	在对象方法中这里又要分两种情况了 ,定时器内的函数参数是否使用了箭头函数
        const obj1 = {
            timerMethod: function () {
                console.log(this); // 在方法中,this 指向 obj1
                setTimeout(function () { // 注意这里使用的是普通函数如果是箭头函数就会不同
                    console.log(this); // this 指向全局对象,而不是 obj1
                }, 1000);
            }
        };
        obj1.timerMethod();

        const obj2 = {
            timerMethod: function () {
                this.value = 'Hello';
                setTimeout(() => { // 此时这里是箭头函数,它没有this,它会捕获其所在上下文的this值,箭头函数的this将与定义箭头函数this的上下文相同
                    console.log(this.value); // 正确地访问到 this.value,输出 'Hello'
                }, 1000);
            }
        };
        obj2.timerMethod();

        const obj3 = {
            value: 'Hello',
            timerMethod: function () {
                setTimeout(function () { // 这里的参数是普通函数我们可以使用call、apply改变this的指向
                    console.log(this.value); // this 指向 obj
                }.call(this), 1000);
            }
        };
        obj3.timerMethod();
        
        const obj4 = {
            value: 'Hello',
            timerMethod: function () {
                setTimeout( () => {
                    console.log(this.value); // this 指向 obj
                }.call(this), 1000);// 这里就不能这样使用 会直接报代码错误的
            }
        };
        obj4.timerMethod();

总结:

  1. 全局作用域中的this指向window
  2. 普通函数this指向window,箭头函数指向它的上下文this
  3. 对象中方法的this指向该方法所属的对象
  4. 构造函数中的this指向实例出来的对象
  5. 事件当中的this指向当前绑定的元素
  6. 定时器中的this指向,需要根据定时器的函数参数是否是箭头函数再进行判断
  7. apply 、call 和 bind 调用中的this指向它想要指向的this

箭头函数与普通函数的区别

  • 语法简洁 () => {}
// 普通函数
const add = function(x, y) {
  return x + y;
};

// 箭头函数
const add = (x, y) => x + y;
  • this上下文
    1、箭头函数不会创建自己的this上下文,它会捕获其所在上下文的this值,作为自己的this值,并且这个this值是不可更改的。即使使用apply call bind 都是不能更改的
    2、普通函数的this值在每次调用时都会重新确定,通常指向调用它的对象,除非使用call、apply或bind方法。
const obj = {
  name: 'Alice',
  greet: () => console.log(`Hello, ${this.name}`), // `this`指向全局对象或undefined(严格模式)
};
obj.greet(); // 如果在严格模式下,将输出 undefined
  • 箭头函数不能用作构造函数,意思不能使用new关键字来调用箭头函数,因为箭头函数没有prototype属性,在指向new操作时,我们需要将构造函数的原型赋值给实例对象的原型。
  • argument对象 箭头函数中没有自己的arguments对象,如果需要访问函数的参数,可以使用剩余参数(rest parameters)代替。
// 普通函数
function foo() {
  console.log(arguments);
}

// 箭头函数
const foo = (...args) => {
  console.log(args);
};
  • 箭头函数不能作为生成器函数,也就是说,不能在其内部使用yield关键字
const gen = () => {
  yield 1; // 语法错误
};

总结
1、箭头函数没有this,它会捕获上下文的this,作为自己的this值,该值任何方法都不能更改的。
2、箭头函数没有原型对象,所以不能进行new实例化对象,当然就不能做构造函数
3、箭头的函数没有arguments对象,可以使用剩余参数代替
4、语法简洁,不能作为生成器函数

  • 24
    点赞
  • 8
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值