JS中this的9种指向详解(web前端开发javascript语法基础)

一直以来,我对js中的this指向问题都不是特别清楚。平时在写代码时只知道,对象中的方法如果使用this,则这个this代表的就是这个对象,但是对其使用和判断并不能信手拈来,好多时候还是得过且过,不明所以。所以我查看了很多资料,彻底扫除this关键字的盲区,也希望对大家有所帮助。

js中的this其实是函数调用的上下文,在我看来这个定义包括两方面:1、在一个函数中,this是调用这个函数的对象;2、一个函数可能会被以不同的方式调用,不同的调用方式下,this的含义不同。因此,函数中this的含义可以视为是在运行时确定的。

总结了以下几种情况的this指向:

一、普通函数:

1、全局直接调用函数时,在非严格模式中,函数中的this代表着全局对象window或者global,在严格模式中,函数中的this为undefined。

function angry_it_man(){
    "use strict"
    if(this == undefined){
        console.log('欢迎关注微信公众号:愤怒的it男');
    }else{
        console.log(this);
    }
};
angry_it_man();
function angry_it_man(){

    if(this == undefined){
        console.log('欢迎关注微信公众号:愤怒的it男');
    }else{
        console.log(this);
    }
};
angry_it_man();

2、通过对象调用方法时,对象方法中的this代表着该对象。

var name = '欢迎关注微信公众号:愤怒的it男';
var angry_it_man = {
    name : '欢迎关注微信公众号:angry_it_man',
    say : function(){
        return this.name;
    },
}

console.log(angry_it_man.say()); // 对象中的this指向angry_it_man对象

f = angry_it_man.say; // 将对象中的say抽离
console.log(f()); // 对象中的this指向全局对象window或者global

3、使用构造函数创建对象时,构造函数中的this代表着new出来的对象。

var name = '欢迎关注微信公众号:愤怒的it男';
var Angry_IT_Man = function(){
    this.name = '欢迎关注微信公众号:angry_it_man';
    this.say = function(){
        return this.name;
    }
}

var angry_it_man = new Angry_IT_Man();
console.log(angry_it_man.say()); // 对象中的this指向angry_it_man对象

f = angry_it_man.say; // 将对象中的say抽离
console.log(f()); // 对象中的this指向全局对象window或者global

4、使用call、apply、bind绑定的,this指向绑定的对象。

call的调用方式为:function.call(argthis,arg1,arg2,…),apply的调用方式为:function.apply(argthis,[arg1,arg2,…]),call和apply的第一个参数就是function的调用上下文,也就是函数中的this值。

var angry_it_man1 = {
  name: '欢迎关注微信公众号:愤怒的it男',
}
var angry_it_man2 = {
  name: '欢迎关注微信公众号:angry_it_man',
}
var say = function (){
    return this.name;
}
console.log(say.call(angry_it_man1));
console.log(say.apply(angry_it_man2));

bind的调用方式为:function.bind(argthis,arg1,arg2,…),bind方法不会立即执行函数,而是返回一个新函数,这个新函数的this值被绑定到argthis对象上,一旦绑定成功,则this不会再变,重新绑定也无效。

var angry_it_man1 = {
  name: '欢迎关注微信公众号:愤怒的it男',
}
var angry_it_man2 = {
  name: '欢迎关注微信公众号:angry_it_man',
}

var it_man = {
    say:function (){
        return this.name;
    }
}
var func = it_man.say.bind(angry_it_man1);
console.log(func());
console.log(func.apply(angry_it_man2)); // 经过bind绑定后this不再改变
console.log(func.bind(angry_it_man2)()); // 重新绑定无效

二、箭头函数:

1、箭头函数中的this等于其定义环境的this,并且箭头函数一经构建,其this指针就被绑定,且不能被任何方法改变。

如果箭头函数在某个函数中被定义,其this值等于外部函数被执行时的this值。

var name = '欢迎关注微信公众号:愤怒的it男';
var Angry_IT_Man = function(){
  this.name = '欢迎关注微信公众号:angry_it_man';
  this.say = ()=>{return this.name;};
}
var angry_it_man = new Angry_IT_Man() 
console.log(angry_it_man.say()) // 对象中的this指向angry_it_man对象

f = angry_it_man.say; // 将对象中的say抽离
console.log(f()) // 箭头函数的this固定指向angry_it_man

如果箭头函数的定义不在任何函数中,则其this为全局对象。

var name = '欢迎关注微信公众号:愤怒的it男';
var angry_it_man = ()=>{
  this.name = '欢迎关注微信公众号:angry_it_man';
}
angry_it_man(); // 箭头函数是在最外围创造的,因此其this指向window
console.log(name)

三、特殊情景:

1、在HTML事件句柄中,this指向接收事件的HTML元素。

<button onclick="this.style.display='none'">欢迎关注微信公众号:愤怒的it男</button>

2、立即执行函数(IIFE),this会100% 指向全局对象window或者global。

var name = '欢迎关注微信公众号:愤怒的it男';
(function(){
    console.log(this.name);
})();

3、setTimeout 中传入的函数,this会100% 指向全局对象window或者global。

var name = '欢迎关注微信公众号:愤怒的it男';
var angry_it_man = {
  name: '欢迎关注微信公众号:angry_it_man',
  say: function() {
    setTimeout(function(){
      console.log(this.name);
    },3000)
  }
}

angry_it_man.say();

4、setInterval 中传入的函数,this会100% 指向全局对象window或者global。

var name = '欢迎关注微信公众号:愤怒的it男';
var angry_it_man = {
  name: '欢迎关注微信公众号:angry_it_man',
  say: function() {
    setInterval(function(){
      console.log(this.name);
    },3000)
  }
}

angry_it_man.say();

 欢迎关注作者微信公众号【愤怒的it男】

  • 1
    点赞
  • 7
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
JavaScript的set和get方法是用于定义对象的属性的访问器方法。它们允许我们对属性的读取和赋值进行控制和处理。 通过set方法,我们可以在给属性赋值时执行一些操作。例如,我们可以检查赋给属性的值是否符合特定的规则或范围。如果不符合规则,我们可以抛出一个异常或执行其他的处理逻辑。这方式可以防止不合理的值被赋给属性。 通过get方法,我们可以在读取属性值时执行一些操作。这样,我们可以对属性的读取进行一些处理,例如计算或格式化。这些操作可以帮助我们从底层数据提取所需的值。 下面是一个使用set和get方法的简单示例: ``` const obj = { _age: 0, set age(value) { if (value < 0) { throw new Error('年龄不能为负数'); } this._age = value; }, get age() { return this._age; } }; obj.age = 20; // 调用set方法 console.log(obj.age); // 调用get方法,输出20 obj.age = -10; // 调用set方法,抛出异常 ``` 在上面的示例,我们定义了一个名为`age`的属性,使用了set和get方法。在set方法,我们检查给属性赋值的值是否小于0。如果小于0,则抛出一个错误。在get方法,我们直接返回`_age`的值。 总结一下,set和get方法可以让我们对属性的读取和赋值进行控制和处理。通过这方式,我们可以确保属性的值符合我们的要求,同时还可以在属性的读取和赋值过程执行一些其他操作。这样,我们可以更好地控制和管理对象的属性。

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值