原文:你不知道的js系列 A 动态作用域 动态作用域 是和 JavaScript中的词法作用域 对立的概念. 动态作用域和 JavaScript 中的另外一个机制 (this)很相似. 词法作用域是在代码编写时就定义好了的(假设没有使用 eval() 或者 with 欺骗词法作用域) 动态作用域也就意味着在运行时才能动态确定. function foo() { console.log( a ); } function bar() { var a = 3; foo(); } var a = 2;…
原文:你不知道的js系列 一个简单粗暴的定义 闭包就是即使一个函数在它所在的词法作用域外部被执行,这个函数依然可以访问这个作用域. 比如: function foo() { var a = 2; function bar() { console.log( a ); } bar(); } foo(); 这个代码和我们讨论嵌套作用域时一样,函数 bar() 可以访问外部作用域中的变量 a(RHS 查询) 这是 “闭包” 吗?……不完全是.这只是解释了对 a 的引用是通过词法作用域的查询规则,这些规则…
  原文:你不知道的js系列 在第(二)节中提到的,标识符在作用域中声明,这些作用域就像是一个容器,一个嵌套一个,这个嵌套关系是在代码编写时定义的. 那么到底是什么产生了一个新的作用域,只有函数能做到吗?JavaScript 的其它代码结构能否创建一个作用域呢? 函数作用域 观察下面的代码: function foo(a) { var b = 2; // some code function bar() { // ... } // more code var c = 3; } 在这段代码中,fo…
原文:你不知道的js系列 先有鸡还是先有蛋? 如下代码: a = 2; var a; console.log( a ); 很多开发者可能会认为结果会输出 undefined,因为 var a 在 a = 2 后面,好像变量似乎被重新定义了,所以结果会是默认值 undefined. 然而,正确结果是 2. 下面这段代码,a 在 定义之前被引用.不会抛出错误,也不会输出 2 . console.log( a ); var a = 2; 结果输出 undefined. 编译器 回忆一下第(一)节中的内…
原文:你不知道的js系列 词法作用域(Lexical Scope) Lex time 一个标准的编译器的第一个阶段就是分词(token化) 词法作用域就是在词法分析时定义的作用域.换句话说,词法作用域是你在写代码的时候,变量和代码块的位置决定的,因此在词法分析时也是固定不变的了. 注:有一些方法可以欺骗词法作用域,从而在词法分析结束之后,修改词法作用域.但好的实践是避免使用这些方法,让词法作用域只经过词法分析,也就是说完全保持编写时的作用域. 下面这段示例代码有三个嵌套作用域, 圈 1 包含了全…
原文:你不知道的js系列 什么是作用域(Scope)? 作用域 是这样一组规则——它定义了如何存放变量,以及程序如何找到之前定义的变量. 编译器原理 JavaScript 通常被归类为动态语言或者解释型语言,但实际上它是编译型语言.它不是像其它传统的编译型语言一样预先编译好,编译后也不能在各种系统上兼容. 但无论如何,JS 引擎采取和传统编译器相同的步骤,只不过以一种更不易被人意识到的负责的方式. 传统编译型语言的处理过程: 1. 分词/词法分析(Tokenizing/Lexing) 将一连串字…
JS之作用域与闭包   作用域在JS中同样也是一个重要的概念.它不复杂,因为ES5中只有全局作用域和函数作用域,我们都知道他没有块级作用域.但在ES6中多了一个let,他可以保证外层块不受内层块的影响.即内层块形成了一个块级作用域,这是let的一个特点.它不简单,因为在许多的函数嵌套的情景下,只有对它理解深刻,才能更好的去分析.今天我们着重讲的是函数作用域与全局作用域. 同样在分析之前,我们来看一段代码. var a=1; function f1(){ var b=2; function f2(…
如何理解js中的作用域,闭包,私有变量,this对象概念呢? 就从一道经典的面试题开始吧! 题目:创建10个<a>标签,点击时候弹出相应的序号 先思考一下,再打开看看 //先思考一下你会怎么写,是不是这样? 可是结果呢,弹出来的都是10,为啥? var i,a for(i=0;i<10;i++){ a=document.createElement('a') a.innerHTML=i+'<br>' a.addEventListener('click',function(eve…
作用域和闭包 ・作用域 引擎:从头到尾负责整个JavaScript的编译及执行过程. 编译器:负责语法分析及代码生成等. 作用域:负责收集并维护由所有声明的标识符(变量)组成的一系列查询,并实施一套非常严格的规则,确定当前执行的代码对这些标识符的访问权限. 作用域是一套规则,用于确定在何处以及如何查找变量(标识符). 如果查找的目的是对变量进行赋值,那么就会使用LHS查询: 如果目的是获取变量的值,就会使用RHS查询. ・词法作用域 无论函数在哪里被调用,也无论它如何被调用,它的词法作用域都只由…
1.作用域 作用域是根据名称找变量的一套规则. 变量的赋值操作会执行两个动作,首先编译器会在当前作用域中声明一个变量(如果之前没有声明过),然后在运行时引擎会在作用域中查找该变量,如果能够找到就会对它赋值. 引擎在查找变量时执行怎样的查找,会影响最终的查找结果. 当变量出现在赋值操作的左侧时进行LHS查询,出现在右侧时进行RHS查询: console.log(a)对a的引用是一个RHS引用,这里a并没有赋予任何值.相应地,需要查找并取得a的值,这样才能将值传递给console.log(..).…
1.对变量提升的理解 1.变量定义(上下文) 2.函数声明 2.说明 this 几种不同的使用场景 常见用法 1.作为构造函数执行 2.作为对象属性执行 3.作为普通函数执行(this === window) 4.call apply bind 3.创建10个 <a>标签,点击的时候弹出来对应的序号 结果:均显示 这种的结果是:每次点击时 i 都为10:点击 click 时,弹出 i,i 是自由变量,这时 i 已经变为 10了,故每次输出都为10:i 是全局作用域,存在覆盖的问题 使用 i 将…
作用域链实例   (1) function example() { var age = 23; alert(age) } var age = 25; example(); alert(age); // 将输出23和25两次   说明: 当执行example时, 首先通过var关键字定义了一个私有变量age, 此时, example成为私有变量age作用域作用域链的终点. 在进行赋值时, 会先从作用域链的终点开始查找变量age, 由于在终点就可以找到, 所以不会继续向上查找, 故而赋值为23后,…
<script> /* js是函数级作用域,在函数内部的变量,内部都能访问, 外部不能访问内部的,但是内部可以访问外部的变量 闭包就是拿到本不该属于他的东西,闭包会造成内存泄漏,你不知道什么时候会用这个闭包,然后这个资源会一直占据内存,造成内存泄漏 */ /*1 --函数内部可以访问外部的变量*/ /*var i = 10; function test() { console.log(i); } test();*/ /*2 在函数外部,我们就不能访问函数内部的变量,不然会报变量没有被定义*/…
什么是闭包 <你不知道的JS>里有对闭包的定义:"当函数可以记住并访问所在的词法作用域,即使函数是在当前作用域之外执行,这就产生了闭包." 讲闭包是啥的太多了...就一句带过...在我的认知中,就是函数套函数,内部的函数能直接访问外部函数的变量.而外部函数的变量,就能被隐藏起来.从而它的优点是能把这些变量隐藏起来,但它的缺点也是这些隐藏的变量难以释放... 总而言之,就是函数里内嵌函数,当这个函数访问外函数的变量时,就可以叫闭包,而真正实现功能呢,就是在外函数return…
例题如下: for (var i = 0; i < 3; i++) {     setTimeout(function() {         console.log(i);     }, 0);     console.log(i); } 结果是:0 1 2 3 3 3很多公司面试都爱出这道题,此题考察的知识点还是蛮多的.为了防止初学者栽在此问题上,此文稍微分析一下.都考察了那些知识点呢?异步.作用域.闭包,你没听错,是闭包.我们来简化此题: setTimeout(function() { …
引子 长久以来一直都没有专门学过 JS ,因为之前有自己啃过 C++ ,又打过一段时间的算法竞赛(写得一手好意大利面条),于是自己折腾自己的网站的时候,一直都把 JS 当 C 写.但写的时候总会遇到一些奇怪的问题,于是打算花点时间看了看<你不知道的JavaScript>.写这篇文章以记录一下一段时间的学习内容,也治疗一下我不爱做笔记和总结的毛病.如果你也是一直按着别的语言的编程习惯来写 JS 而没有专门去了解过它,不妨一起来了解一下 JS 的一些独特之处. 首先来看一段代码: console.…
原文地址:Functional-Light-JS 原文作者:Kyle Simpson-<You-Dont-Know-JS>作者 关于译者:这是一个流淌着沪江血液的纯粹工程:认真,是 HTML 最坚实的梁柱:分享,是 CSS 里最闪耀的一瞥:总结,是 JavaScript 中最严谨的逻辑.经过捶打磨练,成就了本书的中文版.本书包含了函数式编程之精髓,希望可以帮助大家在学习函数式编程的道路上走的更顺畅.比心. 译者团队(排名不分先后):阿希.blueken.brucecham.cfanlife.d…
原文地址:Functional-Light-JS 原文作者:Kyle Simpson-<You-Dont-Know-JS>作者 关于译者:这是一个流淌着沪江血液的纯粹工程:认真,是 HTML 最坚实的梁柱:分享,是 CSS 里最闪耀的一瞥:总结,是 JavaScript 中最严谨的逻辑.经过捶打磨练,成就了本书的中文版.本书包含了函数式编程之精髓,希望可以帮助大家在学习函数式编程的道路上走的更顺畅.比心. 译者团队(排名不分先后):阿希.blueken.brucecham.cfanlife.d…
转载▼ 标签: it   js闭包的作用域以及闭包案列的介绍:   首先我们根据前面的介绍来分析js闭包有什么作用,他会给我们编程带来什么好处? 闭包是为了更方便我们在处理js函数的时候会遇到以下的几种情况:   列1: function f1(){var a=1;f2();} function f2(){return a;} f1();//a没有定义   或者说我想调用一个全局变量的时候却发现不能调用,或者没有这个变量,没有定义这个变量,还要在想调用的时候不能重复出现,怎么办呢?所以就有了闭包…
1.JS无块级作用域 <script> function Main(){ if (1==1){ var name = "alex"; } console.log(name); } Main(); </script>执行结果:{}即块级作用域. alex 2.JS采用函数作为作用域链 <script> function Main(){ var innerValue = "alex"; } Main(); console.log(in…
varclassA = function(){ ; } classA.prototype.func1 = function(){ var that = this, ; function a(){ return function(){ alert(var1); alert(this.prop1); }.apply(that); }; a(); } var objA = newClassA(); objA.func1(); 大家应该写过上面类似的代码吧,其实这里我想要表达的是有时候一个方法定义的地方…
第1章 作用域是什么 抛出问题:程序中的变量存储在哪里?程序需要时,如何找到它们? 设计 作用域 的目的:为了更好地存储和访问变量. 作用域:根据名称查找变量的一套规则,用于确定在何处以及如何查找变量(标识符). ☞ 编译原理 JavaScript 是一门编译语言,但它不是 提前编译的,编译结果也不能在分布式系统中进行移植. 程序的源代码在执行前的三个步骤,统称为"编译": 分词/词法分析:将字符串分解成代码块(词法单元) 解析/语法分析:将词法单元流(数组)转换成抽象语法树(Abst…
一.编译过程 常见编译性语言,在程序代码执行之前会经历三个步骤,称为编译. 步骤一:分词或者词法分析 将由字符组成的字符串分解成有意义的代码块,这些代码块被称为词法单元. 例子:  var a = 2; 这一句通常被分解成为下面这些词法单元:var .a . = .2.; .   步骤二:解析或者语法分析 将词法单元流(数组)转换成一个由元素逐级嵌套所组成的代表了程序语法结构的树.这个树被称为"抽象语法树"(Abstract Syntax Tree, AST) 例子: var .a .…
问题: 1.说一下对变量提升的理解 2.说明this几种不同的使用场景 3.如何理解作用域 4.实际开发中闭包的应用 知识点: js没有块级作用域只有函数和全局作用域,如下代码: if(true){ var name='killua' //把name定义在块里和放在外面是一样的,等同于在外面声明一个变量name,在块内给name赋值 }//同等于下面的代码 //建议用下面方式写 var name if(true){ name='killua' } console.log(name) //打印出来…
原文地址:Functional-Light-JS 原文作者:Kyle Simpson-<You-Dont-Know-JS>作者 关于译者:这是一个流淌着沪江血液的纯粹工程:认真,是 HTML 最坚实的梁柱:分享,是 CSS 里最闪耀的一瞥:总结,是 JavaScript 中最严谨的逻辑.经过捶打磨练,成就了本书的中文版.本书包含了函数式编程之精髓,希望可以帮助大家在学习函数式编程的道路上走的更顺畅.比心. 译者团队(排名不分先后):阿希.blueken.brucecham.cfanlife.d…
原文地址:Functional-Light-JS 原文作者:Kyle Simpson-<You-Dont-Know-JS>作者 关于译者:这是一个流淌着沪江血液的纯粹工程:认真,是 HTML 最坚实的梁柱:分享,是 CSS 里最闪耀的一瞥:总结,是 JavaScript 中最严谨的逻辑.经过捶打磨练,成就了本书的中文版.本书包含了函数式编程之精髓,希望可以帮助大家在学习函数式编程的道路上走的更顺畅.比心. 译者团队(排名不分先后):阿希.blueken.brucecham.cfanlife.d…
一.编译过程 常见编译性语言,在程序代码执行之前会经历三个步骤,称为编译. 步骤一:分词或者词法分析 将由字符组成的字符串分解成有意义的代码块,这些代码块被称为词法单元. 例子:  var a = 2; 这一句通常被分解成为下面这些词法单元:var .a . = .2.; .   步骤二:解析或者语法分析 将词法单元流(数组)转换成一个由元素逐级嵌套所组成的代表了程序语法结构的树.这个树被称为“抽象语法树”(Abstract Syntax Tree, AST) 例子: var .a . = .2…
在讲解主要内容之前,我们先来看看JS的解析顺序,我们惯性地觉得JS是从上往下执行的,所以我们要用一个变量来首先声明它,来看下面这段代码: alert(a); var a = 1; 大家觉得这段代码有什么问题吗?会报错吧,a变量没有声明就调用?或者,可能弹出数字1? 实际上,你会发现这段代码执行的结果是弹出一个“undefined”,为什么会这样呢?下面我们就来讲讲JS的解析顺序. 1.JS的解析顺序 其实说JS是自上而下解析是正确的,但是是分为两步: 先自上而下解析声明,包括用var.funct…
原文地址 作用域 JS中有两种作用域:全局作用域|局部作用域 栗子1 console.log(name); //undefined var name = '波妞'; var like = '宗介' console.log(name); //波妞 function fun(){ console.log(name); //波妞 console.log(eat) //ReferenceError: eat is not defined (function(){ console.log(like) //…
第一部分 作用域与闭包 第一章 作用域是什么 1.作用域 变量赋值操作会执行两个动作:首先编译器会在当前作用域中声明一个变量(如果之前没有声明过), 然后会在运行时引擎会在作用域中查找该变量,找到就会对他赋值. 2.理解LHS和RHS操作赋值 简单来说  LHS:查找的目的是进行变量赋值,使用LHS查询[存] RHS:目的是获取变量的值,就会用RHS[取] 3.JavaScript编译原理   例如var a=2会被拆分为 var a在其作用域中声名新变量:a = 2会查询变量a并且对它赋值 4…