JS作用域 上下文 执行器上下文 作用域链的理解

一、作用域

作用域就是变量和函数的可访问范围,控制变量和函数的可见性与生命周期。

静态作用域(词法作用域):在词法分析的阶段就确定了,不会改变,变量的作用域在定义时决定而不是执行时决定,通过静态分析就能确定。JS采用静态作用域

动态作用域:在运行的时候根据程序的流程信息来动态决定,而不是在写代码时静态确定,即不关心函数和作用域如何声明以及在何处声明,只关心它们在何处调用。

JS的词法作用域:

如果一个文档流中包含多个script代码段,它们的运行顺序是:

(1)读入第一个代码段,一段一段的分析执行

(2)做词法分析,有错则报语法错误,如果还有下一个代码段则读入下一个代码段并做词法分析

(3)对var变量function定义做预备解析(不会报错,只2解析正确的声明)

(4)执行代码段,有错则报错

举例

var value = 1;

function foo() { console.log(value); }

function bar() { var value = 2; foo(); }

bar();/1

分析:执行foo函数的时候,先从foo函数局部作用域中查找是否有变量value,如果没有就从全局作用域中查找变量value的值

而如果是采用动态作用域的话,就是从foo函数内部查找value变量,没有就从调用函数的作用域里找,则会打印2

全局作用域、局部作用域和块级作用域

全局作用域:在任何地方都可以访问到的对象拥有全局作用域,全局作用域的变量时全局对象的属性,不论在什么函数中都可以直接访问,不需要加上全局对象,加上则会提供搜索效率。

最外层函数体外声明的变量具有全局作用域,没有用var声明的变量就有全局作用域,所以声明局部变量必须要用var

局部作用域:函数体内用var声明的变量具有局部作用域,成为局部变量 函数的参数也具有局部作用域

var a=3; // 全局变量
function fn(b){ // 局部变量
c=2; // 全局变量
var d=5; // 局部变量
function subFn(){
var e=d; // 父函数的局部变量对子函数可见
for(var i=0;i<3;i++){
console.write(i);
}
alert(i);// 3, 在for循环内声明,循环外function内仍然可见,没有块作用域
}
}
alert(c); // 在function内声明但不带var修饰,仍然是全局变量
块级作用域 使用let const关键字生命的变量会形成块级作用域。

if (true) {
// 'if' 条件语句块不会创建一个新的作用域
// name 在全局作用域中,因为通过 'var' 关键字定义
var name = 'Hammad';
// likes 在局部(本地)作用域中,因为通过 'let' 关键字定义
let likes = 'Coding';
// skills 在局部(本地)作用域中,因为通过 'const' 关键字定义
const skills = 'JavaScript and PHP';
}
console.log(name); // logs 'Hammad'
console.log(likes); // Uncaught ReferenceError: likes is not defined
console.log(skills); // Uncaught ReferenceError: skills is not defined

二、上下文

作用域是变量的可访问性,不同的是上下文用来指定代码某些特定部分中的this值,可以使用call()、apply()、bind()改变this指向

三、作用域链

JS中的每个函数都表示为一个函数对象(函数实例),函数对象有一个仅供JS引擎使用的属性,通过语法分析和预解析,将属性指向函数定义时作用域中额=的所有对象集合,这个对象集合就是函数的作用域链,包含函数定义时作用域中所有可访问的数据。

转载于:https://www.cnblogs.com/zyl0123/p/11604281.html

你可能感兴趣的:(JS作用域 上下文 执行器上下文 作用域链的理解)