拥有一段关于你的回忆已经足够了~
今天是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