JavaScript作用域学习笔记
文章部分实例和内容来自鸟哥的blogJavascript作用域原理
前端基础进阶(三):变量对象详解 波同学
在JS中,作用域的概念和其他语言差不多,是JS中一个极为重要的概念。在每次调用一个函数的时候 ,就会进入一个函数内的作用域,当从函数返回以后,就返回调用前的作用域.
理解作用域,首先理解几个概念
变量对象:执行环境(execution context)定义所有的变量和函数都存在这个对象中。虽然我们编写的代码无法访问这个对象,但是解析器在处理数据时后台会使用它
var foo=10;function func(){};//因为是在全局作用域当中,so...Global VO={foo:10,func:<function>}
变量对象的创建经历以下几个过程:
- 建立arguments对象,检查上下文中的参数,建立该对象下的属性和属性值。
- 检查当前上下文的函数声明
- 检查上下文变量声明,每找到一个变量声明,就在变量对象中以变量名建立一个属性,属性值为undefined。如果该变量名的属性已经存在,为了防止同名的函数被修改为undefined,则会直接跳过,原属性值不会被修改。
由上可以看出function的优先级比var优先级高
活动对象:在调用func的时候, 会创建一个活动对象(假设为aObj, 由JS引擎预编译时刻创建, 后面会介绍),并创建arguments属性
function foo(x,y){var z=30;function bar(){};}foo(10,20);//当执行到foo(10,20)时即会产生AOActivation Object={z:30,x:10,y:20,bar:<function>,arguments:{0:10,1:20,length:2}}
注意到, 因为函数对象的[[scope]]属性是在定义一个函数的时候决定的, 而非调用的时候, 所以如下面的例子
var name = 'laruence';function echo() {alert(name);}function env() {var name = 'eve';echo();}env();
结果
laruence
可以看出一段函数被激活时有两个阶段,一个是创建阶段,一种执行阶段
1.生成变量对象 1.变量赋值
创建阶段 ==》2.建立作用域 =====》执行==》2.函数引用 ===》出栈 回收
3.确定this的指向 3.执行代码
看下面梨字
// demo01
function test() {console.log(a);console.log(foo());var a = 1;function foo() {return 2;}
}test();
从上下文开始理解,全局作用域的运行test()
时,test()的执行上下文开始创建。
创建过程
testEC = {// 变量对象VO: {},scopeChain: {},this: {}
}// 因为本文暂时不详细解释作用域链和this,所以把变量对象专门提出来说明// VO 为 Variable Object的缩写,即变量对象
VO = {arguments: {...}, //注:在浏览器的展示中,函数的参数可能并不是放在arguments对象中,这里为了方便理解,我做了这样的处理foo: <foo reference> // 表示foo的地址引用a: undefined
}
变量对象和活动对象是一种对象,只不过是处于执行上下文的不同生命周期。
// 执行阶段
VO -> AO // Active Object
AO = {arguments: {...},foo: <foo reference>,a: 1
}
因此demo1变成了如下代码
function test() {function foo() {return 2;}var a;console.log(a);console.log(foo());a = 1;
}test();
实际的例子:
function factory(){var name="laruence";var intro=function(){console.log("I'm "+name);}return intro;
}
function app(para){var name=para;var func=factory();func();
}app("eve");
当调用app的时候, scope chain是由: {window活动对象(全局)}->{app的活动对象} 组成.
此时的scope chain如下:
[[scope chain]]=[
Active Object={this:window,arguments:{0:"eve",length:1}name:'eve'func:<function>para:"eve",
},
Global VO={this:window,app:<function>,window:<object>,document:<object>
}
]
当调用进入factory的函数体的时候, 此时的factory的scope chain为:
[[scope chain]]={
Active Object={this:window,arguments:{},name:"laruence",intro:<function>,
},
Global Object(Variable Object)={this:window,factory:<function>,app:<function>,window:<object>,document:<object>
}
}
在定义intro
函数的时候,intro
函数[[scope]]为:
[[scope chain]]={
Object={name:"laruence",intro:<function>,this:<factory>, //注意这里的this指向arguments:{}
},
Gloabal Object={this:window,factory:<function>,document:<object>,window:<object>
}
}
从factory
函数返回后,在app体内调用intro时,发生了标识符的解析,而此时的scope chain是:
[[scope chain]]={intro AO={<intro 活动对象>} ,Factory AO={name:"laruence",intro:<function>,},Global VO={this:window,factory:<function>,document:<obeject>,window:<object>}
}
因为scope chain中,并不包含factory活动对象. 所以, name标识符解析的结果应该是factory活动对象中的name属性, 也就是’laruence’.
转载于:https://www.cnblogs.com/meng2017/p/8167623.html
JavaScript作用域学习笔记相关推荐
- JavaScript作用域学习笔记(ife2015spring学习心得)
本文参照以下两位前辈的文章,加上自己的见解,有错误之处还望大家指出 鸟哥:Javascript作用域原理 理解 JavaScript 作用域和作用域链 为什么要理解作用域 初学js便听人说这门语言作用 ...
- JavaScript闭包学习笔记
闭包(closure)是JavaScript语言的一个难点,也是它的特色,很多高级应用都要依靠闭包实现. 下面就是我的学习笔记,对于JavaScript初学者应该是很有用的. 一.变量的作用域 要理解 ...
- Javascript入门学习笔记
JS入门学习笔记目录 1.JS简介 2.组成部分 3.特点 4.作用 5.JS三种添加方式 6.变量 7.数据类型 8.检测数据类型 9.逗号运算符 10.算术运算符 11.关系运算符 12.逻辑运算 ...
- Java Web--HTML、CSS、JavaScript详细学习笔记(内含丰富示例代码)
** Java Web–HTML.CSS.JavaScript学习笔记 ** HTML(Hyper Text Markup Language超文本标记语言):控制的是页面的内容,是由标签组成的语言,能 ...
- javascript深入浅出——学习笔记(六种数据类型和隐式转换)
在慕课之前学过JS深入浅出,最近发现很多东西都记不太清楚了,再复习一遍好了,感觉这个课程真的超级棒的,做做笔记,再添加一些学习内容?随时补充 课程大纲 1.数据类型 2.表达式和运算符 3.语句 4. ...
- javascript面向对象学习笔记(一)——继承
最近在学习html5,玩了下canvas,发现js中很多的东西都不太记得了.翻了下笔记后发现还是去图书馆逛逛把,到借阅区找了我一直想看的<javascript design patterns&g ...
- 前端JavaScript的学习笔记
前端知识体系 想要成为真正的"互联网Java全栈工程师"还有很长的一段路要走,其中前端是绕不开的一门必修课.本阶段课程的主要目的就是带领Java后台程序员认识前端.了解前端.掌握前 ...
- JavaScript Reflect 学习笔记
今天我们来学习JavaScript中的反射和ES6的Reflect对象. 什么是反射? 反射机制是指在程序运行期间能够获取自身的信息,比如一个对象能够在运行时就知道自己有哪些属性和方法. 在ES6之前 ...
- JavaScript红皮书学习笔记
1.什么是javaScript JavaScript 历史回顾 JavaScript 是什么(实现) JavaScript 是一门用来与网页交互的脚本语言,包含以下三个组成部分. ECMASc ...
最新文章
- 设计模式复习-命令模式
- Wpf体系结构的学习
- 一个设计反模式——究竟什么是轮子理论
- Spring+SpringMVC +MyBatis整合配置文件案例66666
- [scikit-learn 机器学习] 7. 朴素贝叶斯
- spark sql读取hive底层_[大数据]spark sql读写Hive数据不一致
- Angular启动过程介绍
- js数组去重的四种方式
- B - 吉哥系列故事——完美队形II HDU - 4513 (马拉车)
- android 圆形自定义进度条,Android自定义漂亮的圆形进度条
- Pyhton词云示例(移植-情人节专用版)
- DZ先生怪谈国标28181-2016之目录查询
- DS1302的电子万年历_51单片机,年月日、星期、时分秒、农历和温度,带闹钟,全套资料
- 正则表达式,判断输入的字符串是否只包含数字、字母、下划线三种随机组合,字符串可以包含一个或多个空格但头尾不能为空格,全为空格组成等限定字符串格式规则
- C++中如何判断一个字符串中包含另一个字符串
- 我的Android进阶之旅------gt;/storage/sdcard0, /sdcard, /mnt/sdcard ,/storage/emulated/legacy 的区别...
- mt6631 BT /无线/ GPS /调频 设计的通知
- 开源项目推荐:推荐5款前端的开源项目,vue、uniapp、react学无止境用无止境_
- 解决javax.xml.parsers.DocumentBuilderFactory.setFeature(Ljava/lang/String;Z)V异常
- 【学习进度】截至2022.9.6,已学习的C++知识