amy-blog's People
amy-blog's Issues
JavaScript:理解事件循环
JavaScript:理解事件循环
话说js是单线程的,它通过浏览器事件循环轮询事件队列,来实现异步。然而,事件循环的时机是什么时候?浏览器是如何帮助JS引擎线程实现异步的?
浏览器页面进程的四个线程
首先说一下,chrome会为每一个tab创建一个进程,每个页面进程下可以创建多个线程,比如http请求线程(Ajax)、界面渲染线程(HTML&CSS)、JS引擎线程(JS)、浏览器事件触发线程(UI&DOM)、定时器(Timer)。
(既然渲染线程和js引擎是两个线程,为什么执行js会阻塞页面渲染?)
js的异步原理
用图片说话吧,请欣赏宝宝刚出炉热腾腾的萌图。
实在惭愧,画完图以后,就不想打字了说话了。发现自己爱绘画胜过文字~~~大家凑合着看啦。
JavaScript:理解prototype与__proto__,原型与原型链
JavaScript:理解prototype与__proto__,原型与原型链
JS中的继承是原型继承,通过原型实现的。为了理解原型,我想先讲讲对象的内部属性[[prototype]]和属性_proto_,函数的属性prototype。
对象的内部属性[[prototype]]和属性_proto_
每个对象都有内部属性[[prototype]]和属性__proto__,一个对象的__proto__ 属性和自己的内部属性[[Prototype]]指向一个相同的值 (通常称这个值为原型),原型的值可以是一个对象值也可以是null(比如说Object.prototype.__proto__的值就是null)。该属性可能会引发一些错误,因为用户可能会不知道该属性的特殊性,而给它赋值,从而改变了这个对象的原型。如果需要访问一个对象的原型,应该使用方法Object.getPrototypeOf。
改变__proto__ 属性的值同时也会改变内部属性[[Prototype]]的值,除非该对象是不可扩展的。__proto__ 属性就相当于内部属性[[Prototype]]的可访问版,它们在内容上是等价的,都代表着对象的原型。为了语言简洁,我们接下来说到对象原型,只用__proto__属性来说。
函数的属性prototype
每个函数都有属性prototype,函数的属性prototype是一个原型对象,这个原型对象里有一个constructor属性指向这个函数本身,还可以有其他自定义的属性。
同时,因为函数也是对象,所以每个函数也都有内部属性[[prototype]]和属性_proto_。
函数的属性__proto__,就是函数本身这个对象的原型,而属性prototype是,在函数作为构造函数时,赋值给实例对象的属性__proto__,也就是由函数所构造的实例对象的原型。
原型链的形成
一个对象的原型可以是构造函数的prototype隐式赋值给该对象的属性__proto__的,可以是将其他对象直接显示赋值给该对象的属性__proto__的,不管是怎么生成的,对象的原型也是一个对象,而这个原型对象也有它的__proto__属性。当对象寻找一个属性时,先找本身的属性里有没有,没有的话,再在其属性__proto__的原型对象中找,原型对象中没有,再在它的原型对象中找,一环接一环,这就是原型链。
JavaScript:理解执行环境、作用域链和活动对象
JavaScript:理解执行环境、作用域链和活动对象
作用域的原理,对JS将如何解析标识符做出了解答。而作用域的形成与执行环境和活动对象紧密相关。
我们对于JS标识符解析的判断,存在一个常见误区
首先,看一个关于JS标识符解析的问题 ,源于风雪之隅提出的问题
var name = 'globalName';
function funcA() {
console.log(name);
var name = 'funAName';
console.log(name);
console.log(age);
}
funcA();
这段代码的运行结果是怎样的?
相信会有人跟我最初遇到这个问题时一样,以为结果会是这样:
globalName
funAName
[脚本错误: ReferenceError]
我们认为:在funA中, 第一次console.log的时候,会取到全局变量name的值'globalName', 而第二次值被局部变量name覆盖, 所以第二次console.log是'funAName'。 而age属性没有定义, 所以脚本会出错。
但是实际上,运行结果是这样的:
undefined
funAName
[脚本错误: ReferenceError]
为什么会这样呢?在JS中,标识符解析是沿作用域链一级一级地搜索标识符的过程,搜索过程始终从作用域链的前端开始,然后逐级地向后回溯,直到找到标识符为止(如果找不到标识符,通常会导致错误发生)。所以为了正确地判断标识符的解析结果,我们必须把作用域链原理弄清楚。
深入理解作用域原理能够为我们解密这个误区
作用域链(scope chain)的生成跟执行环境(execution context)、函数对象(function object)和活动对象(activation object)紧密相关。
执行环境
执行环境是JavaScript中最为重要的一个概念。执行函数定义了变量或函数有权访问的其它数据,决定了它们各自的行为。每个执行环境都有一个与之关联的变量对象(variable object)和一个作用域链(scope chain),环境中定义的所以变量和函数都保存在其变量对象中。执行环境分为两种,一种是全局执行环境,一种是函数执行环境。
-
全局执行环境
全局执行环境是最外围的一个执行环境,其变量对象就是全局活动对象(window activation object),全局执行环境直到应用程序退出——例如关闭网页或浏览器——时才会被销毁。
-
函数执行环境
每个函数都有自己的执行环境。当执行流进入一个函数时,函数环境就会被推入一个环境栈中。当函数执行完之后,栈将其环境弹出,把控制权返回给之前的执行环境。函数执行环境的变量对象是该函数的活动对象(activation object)。
作用域链
对于每一个执行环境,都会创建一个与之关联的作用域链。每个执行环境的作用域链的前端,始终都是该执行环境的变量对象,对于全局执行环境就相当于window对象,对于函数执行环境就相当于该函数的活动对象;对于全局执行环境,已经是根部,没有后续,对于函数执行环境,其作用域链的后续是该函数对象的[[scope]]属性里的作用域链。
函数对象
在一个函数定义的时候, 会创建一个这个函数对象的[[scope]]属性(内部属性,只有JS引擎可以访问, 但FireFox的几个引擎(SpiderMonkey和Rhino)提供了私有属性__parent__来访问它),并将这个[[scope]]属性指向定义它的作用域链上。 在这里的问题中,因为funcA定义在全局环境, 所以此时的[[scope]]只是指向全局活动对象window active object。
活动对象
在一个函数对象被调用的时候,会创建一个活动对象,首先将该函数的每个形参和实参,都添加为该活动对象的属性和值;将该函数体内显示声明的变量和函数,也添加为该活动的的属性(在刚进入该函数执行环境时,未赋值,所以值为undefined,这个是JS的提前声明机制)。
然后将这个活动对象做为该函数执行环境的作用域链的最前端,并将这个函数对象的[[scope]]属性里作用域链接入到该函数执行环境作用域链的后端。
现在让我们回到最初的问题
var name = 'globalName';
function funcA() {
//当funcA()被调用时,刚进入funcA的执行环境,其作用域链最前端的funA activation object里有name属性,值为undefined。
console.log(name);
var name = 'funAName';
console.log(name);
console.log(age);
}
funcA();
虽然感觉这个例子的误区跟JS提前声明机制的关系也很大,但是理解funA.[[scope]]属性的作用域链是funA定义时的作用域链,而不是被调用时的作用域链,对于看懂多层函数嵌套的情况下作用域链的坑,也是非常关键的。
Recommend Projects
-
React
A declarative, efficient, and flexible JavaScript library for building user interfaces.
-
Vue.js
🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
-
Typescript
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
-
TensorFlow
An Open Source Machine Learning Framework for Everyone
-
Django
The Web framework for perfectionists with deadlines.
-
Laravel
A PHP framework for web artisans
-
D3
Bring data to life with SVG, Canvas and HTML. 📊📈🎉
-
Recommend Topics
-
javascript
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
-
web
Some thing interesting about web. New door for the world.
-
server
A server is a program made to process requests and deliver data to clients.
-
Machine learning
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
-
Visualization
Some thing interesting about visualization, use data art
-
Game
Some thing interesting about game, make everyone happy.
Recommend Org
-
Facebook
We are working to build community through open source technology. NB: members must have two-factor auth.
-
Microsoft
Open source projects and samples from Microsoft.
-
Google
Google ❤️ Open Source for everyone.
-
Alibaba
Alibaba Open Source for everyone
-
D3
Data-Driven Documents codes.
-
Tencent
China tencent open source team.