this怎么那么难呢?

2019-12-19 15:00:44 浏览数 (1)

拥有一段关于你的回忆已经足够了~


今天是2019年12月17年,星期三。今天北京是个大晴天,我下楼遛弯的时候看到天灰常的蓝。2019年还有不到15天就结束了,各位宝宝年初的目标实现了几个呢?emmm,我还有一个目标没有实现,时间不多了,作为明年的目标吧,哈哈哈哈哈哈哈哈~

对于我这菜鸟级别的前端开发工程师来说this简直太难了,每次只能让自己认识的深入一点点,也只能这样了。

这次的重新学习this,有一个心得:想要学懂this,一定要先学习作用域。

this与词法作用域


在js内部,作用域确实与对象类似,可见的标识符都是它的属性。但是作用域无法通过js代码访问,它存在于js引擎内部。

思考下面的代码,它试图跨域边界,使用this来隐式引用函数的词法作用域。

代码语言:javascript复制
function foo(){
   var a=2;
   this.bar(); 
}
function bar(){
  console.log(this.a)
}
foo() // ReferenceError: a is not define

以上代码调用bar()最自然的方法是省略前面的this,直接使用词法引用标识符。

此外,这段代码的开发者还试图使用this联通foo()和bar()的词法作用域。从而让bar()可以访问foo()作用域里的变量啊。这是不可能实现的,使用this不可能在词法作用域中查到什么。

每当你想要this和词法作用域的查找混合使用时,一定要提醒自己,这是无法实现的。

this到底是什么


this是在运行时进行绑定的,并不是在编写时绑定,它的上下文取决于函数调用时的各种条件。this的绑定取决于函数的调用方式。

当一个函数被调用时,会创建一个活动记录(有时候也成为执行上下文)。这个记录包含函数在哪里被调用(调用栈)、函数的调用方式、传入的参数等信息。this就是这个记录的一个属性,会在函数执行的过程中用到。

this到底是什么


this是在运行时进行绑定的,并不是在编写时绑定,它的上下文取决于函数调用时的各种条件。this的绑定取决于函数的调用方式。

当一个函数被调用时,会创建一个活动记录(有时候也成为执行上下文)。这个记录包含函数在哪里被调用(调用栈)、函数的调用方式、传入的参数等信息。this就是这个记录的一个属性,会在函数执行的过程中用到。

调用位置


在理解this绑定过程之前,首先要理解调用位置:函数在代码 中被调用的位置。最重要的是要分析调用栈。(为了到达当前执行位置所调用的所有函数)我们关心的调用位置就在当前正在执行的函数的前一个调用中。

代码语言:javascript复制
function baz(){  //当前调用栈是:baz,因此当前调用位置是全局作用域
  console.log("baz");
  bar() // bar的调用位置
}
function bar(){ //当前调用栈是 bar->bar ,因此当前调用位置是在baz中
   console.log("bar");
   foo(); // foo的调用位置
}

function foo(){ //当前调用栈是baz->bar -> foo 因此当前调用位置是在bar中
  console.log("foo")
}
baz(); // baz的调用位置

从调用栈中分析出真正的调用位置,决定了this的绑定。

绑定规则


先找到调用位置,然后根据优先级应用下面的四条规则的哪一条

- 默认规则:

无法应用其他规则的默认规则

代码语言:javascript复制
function foo(){
  console.log(this.a)
}
var a =2;
foo();

foo()是直接使用不带任何修饰的函数引用进行调用的,因此只能使用默认绑定。

若使用严格模式,则不能将全局对象进行默认绑定

代码语言:javascript复制
function foo(){
  "use strict";
   console.log(this.a) 
 }
 var a = 2;
 foo() // TypeError : this is undefined

- 隐式绑定:

另一条需要考虑的规则是调用位置是否有上下文对象,或者说是否被某个对象拥有或者包含。

那个... 太晚了,该睡觉了,明天还要上班,明天继续,宝宝们也早点睡

愿我们有能力不向生活缴械投降---Lin

0 人点赞