作用域

JavaScript中变量提升------Hoisting

左心房为你撑大大i 提交于 2019-11-28 09:58:40
前言 因为我在写这文章的时候,百度里找资料,找到了园友的一篇文章,写的很好,可是我写了又不想放弃,所以就在里面拿了很多东西过来!~~ [翻译]JavaScript Scoping and Hoisting 希望得到大家谅解。 因为这个问题很是经典,而且容易出错,所以在介绍一次。哈哈。莫怪哦。 一。案发现场 我们先看一段很简单的代码: var v='Hello World'; alert(v); 这个没有疑问吧,弹出“Hello World”。OK,我们继续。 我们在看一段Code: var v='Hello World'; (function(){ alert(v); })() 经过运行之后,我们发现,还是和我们预期的一样,弹出了“Hello World”。 好了,有意思的来了。接着在看一段下面的代码: var v='Hello World'; (function(){ alert(v); var v='I love you'; })() 如果这个是一个面试题,面试官问你这个结果是多少?你怎么回答? 我们先看结果吧! 结果是 undefined?和你上面自己想的一样吗? 好吧,我就不故弄玄虚了。其实,这里面隐藏了一个陷阱-----JavaScript中的变量提升(Hoisting); 二。深度剖析 现在我来解释下提升是什么意思?顾名思义,就是把下面的东西提到上面。在JS中

function变量困惑

我是研究僧i 提交于 2019-11-28 09:58:31
1 var name = "The Window"; 2 var object = { 3 name : "My Object", 4 getNameFunc : function(){ 5 return function(){ 6 return this.name; 7 }; 8 } 9 }; 一个经典的代码,在高程也出现过的,意在说明 this 和 闭包变量作用域。 以前写过一篇记录一下,最近在sf看到一博客文章,又突然陷入深思。 http://blog.segmentfault.com/findingea/1190000000537129 首先,说一下2个关键点: 1.function的作用域:在function中访问一变量,首先看function执行体内是否存在该变量,不存在,则往function的调用环境,去查询,如果是多层调用,则会遵循内部找不到就往外部查找,一直到全局作用域,这也就是作用域链。 1.1一般说来,闭包,即内部函数调用了外部函数的变量,并返回自身给外部使用,此时,即可访问到外部函数的变量,这里能不能说其实也是套用了所谓的作用域链原理呢。 2. function的作用域内,本身执行体的执行环境包含参数arguments和this两个自带的,不会导致需要去外部找变量,上面的经典问题中,this.name之所以返回的是 the window 即全局变量

JavaScript: 变量提升和函数提升

假如想象 提交于 2019-11-28 09:58:16
第一篇文章中提到了变量的提升,所以今天就来介绍一下变量提升和函数提升。这个知识点可谓是老生常谈了,不过其中有些细节方面博主很想借此机会,好好总结一下。 今天主要介绍以下几点: 1. 变量提升 2. 函数提升 3. 为什么要进行提升 4. 最佳实践 那么,我们就开始进入主题吧。 1. 变量提升 通常JS引擎会在正式执行之前先进行一次预编译,在这个过程中,首先将变量声明及函数声明提升至当前作用域的顶端,然后进行接下来的处理。(注:当前流行的JS引擎大都对源码进行了编译,由于引擎的不同,编译形式也会有所差异,我们这里说的预编译和提升其实是抽象出来的、易于理解的概念) 下面的代码中,我们在函数中声明了一个变量,不过这个变量声明是在if语句块中: function hoistVariable() { if (!foo) { var foo = 5; } console.log(foo); // 5 }hoistVariable(); 运行代码,我们会发现foo的值是5,初学者可能对此不甚理解,如果外层作用域也存在一个foo变量,就更加困惑了,该不会是打印外层作用域中的foo变量吧?答案是:不会,如果当前作用域中存在此变量声明,无论它在什么地方声明,引用此变量时就会在当前作用域中查找,不会去外层作用域了。 那么至于说打印结果,这要提到预编译机制了,经过一次预编译之后,上面的代码逻辑如下: //

作用域

不打扰是莪最后的温柔 提交于 2019-11-28 09:56:00
javascript中有个作用域的概念。 全局作用域 函数作用域 作用域取决于函数定义的地方,与函数执行无关。 function F1() { var a = 100; return function () { console.log(a) } } var f1 = F1(); var a = 200; f1() 这段代码打印结果: 100; 我们这样来看, F1定义的时候,作用域已经生成。 然后,把F1 赋值给 f1, 此时,f1 是一段函数,如下: function() { console.log(a) } 复制代码 然后,定义了一个全局变量a,在全局环境去执行f1. 注意: 作用域取决于函数定义的地方,与函数执行无关。 此时f1执行,去找a的变量,F1的局部作用域去找。 他会找到a = 100; 而不是a=200; 作用域是分层的,内层作用域可以访问外层作用域的变量,反之则不可以 来源: https://www.cnblogs.com/psxiao/p/11403863.html

JavaScript的函数和作用域闭包

巧了我就是萌 提交于 2019-11-28 08:07:13
1. 函数 1.1 定义函数 function add(x, y){ return x + y; } 上述函数定义如下: 关键字 function 指出这是一个函数定义; add 是函数的名称; (x, y) 括号内列出函数的参数,多个参数以 , 分隔; {} 之间的代码是函数体,可以包含若干语句,甚至可以没有任何语句。 函数体内部的语句在执行时,一旦执行到 return 时,函数就执行完毕,并将结果返回。 如果没有 return 语句,函数执行完毕后也会返回结果,只是结果为 undefined 。 JavaScript的函数也是一个对象, 函数名可以视为指向该函数的变量 。因此,函数也可以像下面这样定义。 var add = function (x, y){ return x + y; } 这种情况下, function (x, y){} 是一个匿名函数,它没有函数名。但是,这个匿名函数赋值给了变量 add ,所以,通过变量 add 就可以调用该函数。 1.2 调用函数 调用函数时,按顺序传入参数即可。 add(1, 2); // 3 关键字 arguments 只在函数内部起作用。我们通过 arguments 可以获得调用者传入的所有参数。事实上, arguments 最常用于判断传入参数的个数。 function add(x, y){ for(let i = 0; i <

JavaScript编程基础2

血红的双手。 提交于 2019-11-28 08:01:42
JavaScript 编程基础 1 JavaScript 基础语法 1-1 注释 在JavaScript中,注释可以分为单行注释和多行注释。 关于注释的作用,之所以书写注释,就是为了让阅读代码的人更加方便。 单行注释如下: // 这是一个单行注释 多行注释如下: /* * * 这是 _ 个较长的 * 多行的注释 * */ 1-2 语句 在 JavaScript 中,语句一般我们都会采用以分号结尾,每条语句独占一行的形式来书写代码。 let i = 10; console.log(i); //10 1-3 标识符 所谓标识符,就是指用来标识某个实体的一个符号。就是自己起一个名字,这个 名字可以用来作为变量名,函数名,对象名等。需要遵守一定的规则,其命名的规则大致可以分为 2大类: 硬性要求和软性要求 硬性要求 ・ 1 .可以是由数字,字母,下划线和美元符号组成,不允许包含其他特殊符号 -2.不能以数字开头 • 3.禁止使用J avaScript中的关键词和保留字来进行命名 -4.严格区分大小写 软性要求 •望文知意 命名的 3 种方法 匈牙利命名法 特点是标识符的名字 以一个或者多个小写字母开头,表示了该变量的数据类型。 数据类型 对应前缀 Array数组 a Boolean 布尔 b Float浮点 f Function fn Interger(int)整型 i Object对象

闭包

耗尽温柔 提交于 2019-11-28 08:01:15
前言 闭包:指函数变量被隐藏在作用域链之内,这时看起来像是函数将变量“包裹”起来了(函数对象通过作用域相互关联起来,函数体内部的变量都可以保存在函数作用域内,这种特性在计算机文献中成为闭包)。闭包是一个可以重用的对象,又保护对象不被篡改的一种机制。 作用域和作用域链 作用域:作用域是一个变量的可用范围,其实质是一个保存变量的对象,使用作用域可以避免不同范围的变量相互干扰。 全局作用域:在 JavaScript 中的全局作用域就是 windows。优点是可以重复使用,随处可用,但会造成全局污染(全局污染指在两个脚本中存在同名的变量,当这两个脚本在同一个窗口中运行时,由同名变量造成的混乱。) 函数作用域:临时创建的活动对象 AO(activation object),该对象包含了函数的所有局部变量、命名参数、参数集合以及 this,当运行上下文被销毁时活动也会被销毁(闭包形成的原因就是因为活动对象被引用着无法销毁而导致的)。优点是不污染全局,但不可重复使用且仅在函数内才可以使用。 程序执行的原理 来源: https://www.cnblogs.com/aioverg/p/11400623.html

JS闭包各种坑

守給你的承諾、 提交于 2019-11-28 07:39:43
闭包是js开发惯用的技巧,什么是闭包? 闭包指的是:能够访问另一个函数作用域的变量的函数 。清晰的讲:闭包就是一个函数,这个函数能够访问其他函数的作用域中的变量。eg: function outer() { var a = '变量1' var inner = function () { console.info(a) } return inner // inner 就是一个闭包函数,因为他能够访问到outer函数的作用域 } 很多人会搞不懂匿名函数与闭包的关系,实际上,闭包是站在作用域的角度上来定义的,因为inner访问到outer作用域的变量,所以inner就是一个闭包函数。虽然定义很简单,但是有很多坑点,比如this指向、变量的作用域,稍微不注意可能就造成内存泄露。我们先把问题抛一边,思考一个问题: 为什么闭包函数能够访问其他函数的作用域 ? 从堆栈的角度看待js函数   基本变量的值一般都是存在栈内存中,而对象类型的变量的值存储在堆内存中,栈内存存储对应空间地址。基本的数据类型: Number 、Boolean、Undefined、String、Null。 var a = 1 //a是一个基本类型 var b = {m: 20 } //b是一个对象 对应内存存储: 当我们执行 b={m:30}时,堆内存就有新的对象{m:30},栈内存的b指向新的空间地址( 指向{m:30}

ES6 let命令

若如初见. 提交于 2019-11-28 07:35:29
我们都知道JavaScript分三部分组成,分别是:ECMAScript(核心)、DOM(文档对象模型)、BOM(浏览器对象模型)。后面我们就说说关于ECMAScript的知识。 有时候我们会在一些招聘简章上写着那样的一些要求——熟悉ES6。 那什么是ES6? ES6是ECMAScript 6.0的简称,它是 JavaScript 语言的下一代标准,已经在 2015 年 6 月正式发布了。它的目标,是使得 JavaScript 语言可以用来编写复杂的大型应用程序,成为企业级开发语言。 ES6新增指令——let 1.块级作用域 我们知道JavaScript是没有块级作用域这个概念的,而let指令的出现恰好弥补了这一点。 块作用域由 { } 包括,if语句和for语句里面的{ }也属于块作用域。 let块级作用域的体现 //案例一 { var a=56; let b=30; } console.log(a);//56 console.log(b);//报错 //案例2 //var 情况 var a=[]; for(var i=0;i<10;i++){ a[i]=function(){ console.log(i);//10 }; } a[6](); //函数调用 ,a[6]=function(){console.log(i)};根据作用域链向上寻找,找到全局变量i //let情况

静态变量、全局变量和局部变量

霸气de小男生 提交于 2019-11-28 06:03:28
1.从作用域看: C++变量根据定义的位置的不同的生命周期,具有不同的作用域,作用域可分为6种: 全局作用域,局部作用域,语句作用域,类作用域,命名空间作用域和文件作用域。 1>全局变量具有全局作用域。全局变量只需在一个源文件中定义,就可以作用于所有的源文件。当然,其他不包含全局变量定义的源文件需要用extern关键字再次声明这个全局变量。 2>静态局部变量具有局部作用域,它只被初始化一次,自从第一次被初始化直到程序运行结束都一直存在,它和全局变量的区别在于全局变量对所有的函数都是可见的,而静态局部变量只对定义自己的函数体始终可见。 3>局部变量也只有局部作用域,它是自动对象(auto),它在程序运行期间不是一直存在,而是只在函数执行期间存在,函数的一次调用执行结束后,变量被撤销,其所占用的内存也被收回。 4>静态全局变量也具有全局作用域, 它与全局变量的区别在于如果程序包含多个文件的话,它作用于定义它的文件里,不能作用到其它文件里,即被static关键字修饰过的变量具有文件作用域。这样即使两个不同的源文件都定义了相同名字的静态全局变量,它们也是不同的变量。 2.从分配内存空间看: 1> 全局变量,静态局部变量,静态全局变量都在静态存储区分配空间,而局部变量在栈里分配空间 2>全局变量本身就是静态存储方式,静态全局变量当然也是静态存储方式。这两者在存储方式上并无不同