欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页  >  IT编程

JS 为什么在涉及到模块开发this的时候使用类似 self = this 的形式 p7

程序员文章站 2022-05-02 13:42:50
JS 动态作用域(调用栈)实际上也没有准确说明的,大多数我们使用对多和认知上大多是词法作用域,但是this的机制跟动态作用域很像。 这是理所当然的,不是么?实际上我们平时接触的最多可能就是这种,词法作用域(实际上当我们没有使用到关键字this时,都是这种) 但是有时候我们也想这样: 实际上,是不会的 ......

js 动态作用域(调用栈)实际上也没有准确说明的,大多数我们使用对多和认知上大多是词法作用域,但是this的机制跟动态作用域很像。

var a = 2;

function fn(){
     console.log(a);
}

fn();// 2

这是理所当然的,不是么?实际上我们平时接触的最多可能就是这种,词法作用域(实际上当我们没有使用到关键字this时,都是这种)

但是有时候我们也想这样:

var a = 2;

function fn(){
    
  console.log(a);
} 


function fn2(){
  var a = 3;
  fn();
}

fn2();// 输出3

实际上,是不会的,还是输出2 ~

 

使用this看看

var obj = { id:'我是内部id',x : function (){console.log(this.id)} }
var id = "我是外部id";
obj.x(); //我是内部id

window.settimeout(obj.x,100); //我是外部id

this 在window调用的时候访问了其作用域 中的id “我的外部id”,这跟 一级标识符有关,this会执行第一级调用它的对象,并绑定其作用域,所以如你所看到的一样,输出了外部id

那么怎么解决这个问题:

使用self或者自定义一个变量声明来告诉它我要使用 “词法作用域

var obj = {
   id : '我是内部id',
   x : function(){
      var self = this;
      
      settimeout(function timer(){console.log(self.id)},100)
   }

}

obj.x(); // 我是内部id

或者使用箭头函数(箭头函数在设计this绑定适会放弃普通this的规则)

var obj = {
   id : '我是内部id',
   x : function(){
      
      settimeout(()=>{console.log(this.id)},100)
   }
}

或者使用bind绑定:

var obj = {
   id : '我是内部id',
   x : function(){
      
      settimeout(function timer(){console.log(this.id)}.bind(this),100)
   }

}

上面的self 可能不明显,因为settimeout看上去是在函数内部,但是实际上调用的还是通过window去调用,按照之前所说,还应该是输出 外部id,但是实际输出为内部id,如果还是有点晕,再补充2个,可能会更加深你的理解

如果你看到最后的话~