谁能用简单明白的一句话总结下执行上下文是什么意思?? 是作用域吗
js上下文总结
01 context
任何方法,谁调用了它,则就是它的context。
这个和this的描述是一致的:
this最终指向的是调用它的对象
上下文就是this的指向。
02 不稳定的context
context在js的表现经常出现一些看似"不稳定"的情况,下面列出了一些"不稳定"。
(1) new和非new
下面是一道常见的面试题,问①和②分别输出什么结果?
虽然简单,却是对context最全的理解。
①输出 say 的实例
②输出window吗?
显然我们凭借这段代码是无法做出对②的判断,因为我们根本不知道say()的运行环境是什么。
(2) 方法赋值
下面试题,将方法赋值给一个变量。
结果:
①输出 喵
②输出 嗷嗷嗷
这里可以理解:因为say其实只是引用了一个函数,函数的运行依赖context,不同的context必然有不同结果。
(3) Event Loop
Event Loop又叫事件循环,由于js没有多线程,处理多个任务的时候,就需要采用异步队列(如定时器、I/O、Promse),或者利用浏览器的多线程启动多个任务(如ajax)。
那么异步任务,它的context就是浏览器当前打开的窗口了,即window。
下面是一个常见的面试问题:
①和②都输出window。
(4) 自执行函数
看下面一个问题:
①和②都输出window,这里也说明了自执行函数是被window调用。
03 闭包拯救世界
面对不稳定的context,闭包可以被动解决这些问题。
因为我们所期望的context,和闭包所表现的scope惊人相似。
于是我们纷纷这样做:
上面做法用_this代替this,使得正常访问外层this。
04 bind来优化
对于用闭包来改变context的问题,不是很优雅。
用bind会更简洁。
实现是下面代码:
通过bind直接改变当前函数的context,这样子做法是符合我们的阅读习惯的。
05 call和apply
call和apply又叫对象冒充,是在方法执行的时候,传入一个对象,顶替原有的context。
下面代码通过call,主动改变的执行函数的context。这在封装里面很重要。
点击div,打印div元素。
06 箭头函数
可能意识到context这个问题,于是es6推出箭头函数。箭头函数采用词法作用域,这使得它和闭包的解决极为相似。
注意:arguments本身在箭头函数下,会指向外层函数的arguments (同this一样)。
这里①和②都正常输出了。
07 Arguments
Arguments也是context绕不过去的坎,Arguments是函数的内部对象,js在执行函数的时候,会根据Arguments初始化函数内部的变量。
arguments.callee可以访问到当前函数。
arguments.callee.caller可以访问调用当前函数的函数。
arguments上面特性严格模式下是不允许被使用的。