你不知道的JavaScript(作用域和闭包)
作用域和闭包
・作用域
引擎:从头到尾负责整个JavaScript的编译及执行过程。
编译器:负责语法分析及代码生成等。
作用域:负责收集并维护由所有声明的标识符(变量)组成的一系列查询,并实施一套非常严格的规则,确定当前执行的代码对这些标识符的访问权限。
作用域是一套规则,用于确定在何处以及如何查找变量(标识符)。
如果查找的目的是对变量进行赋值,那么就会使用LHS查询;
如果目的是获取变量的值,就会使用RHS查询。
・词法作用域
无论函数在哪里被调用,也无论它如何被调用,它的词法作用域都只由函数被声明时所处的位置决定。
欺骗词法:两种机制。欺骗词法作用域会导致性能下降。
eval():
function foo(str, a) {
eval(str);
console.log(a, b);
}
var b = 2;
foo(“var b = 3; ”, 1);
// 1, 3
with():
function foo(obj) {
with(obj) {
a = 2;
}
}
var o1 = { a: 3};
var o2 = { b: 3};
foo(o1);
console.log(o1.a); // 2
foo(o2);
console.log(o2.a); // undefined
console.log(a); // 2
・函数作用域和块作用域
隐藏内部实现:可以把变量和函数包裹在一个函数的作用域中,然后用这个作用域来隐藏它们。
最小特权原则(最小授权或最小暴露原则):最小限度地暴露必要内容,而将其他内容都隐藏起来。
规避冲突:隐藏作用域中的变量和函数,可以避免同名标识符之间的冲突。
包装函数:
(function foo() {
var a = 3;
console.log(a);
})();
匿名函数:
setTimeout(function() {…}, 1000);
缺点:
匿名函数在栈追踪中不会显示出有意义的函数名,使得调试困难;
如果没有函数名,当需要引用自身时只能使用已过期的arguments.callee引用;
匿名函数省略了对于代码可读性/可理解性很重要的函数名。
给函数表达式指定一个函数名可以有效解决以上问题:
setTimeout(function timeoutHandler() {…}, 1000);
块作用域:
let关键字可以将变量绑定到所在的任意作用域中;
使用let进行的声明不会在块作用域中进行提升;
提升:
只有声明本身会被提升,而赋值或其他运行逻辑会留在原地。
如果提升改变了代码执行的顺序,会造成非常严重的破坏;
函数声明和变量声明都会被提升,但是函数会首先被提升;
foo(); // 1
var foo;
function foo() {
console.log(1);
}
foo = function() {
console.log(2);
}
・作用域闭包
只要使用了回调函数,实际上就是在使用闭包;
模块模式具备的两个必要条件:
必须有外部的封闭函数,该函数必须至少被调用一次;
封闭函数必须返回至少一个内部函数,这样内部函数才能在私有作用域中形成闭包,并且可以访问或者修改私有的状态;
function CoolModule() {
var something = “cool”;
var another = [1, 2, 3];
function doSomething() {
console.log(something);
}
function doAnother() {
console.log(another.join(“!”));
}
return {
doSomething: doSomething,
doAnother: doAnother
};
}
var foo = CoolModule();
foo.doSomething();
你不知道的JavaScript(作用域和闭包)的更多相关文章
- javascript作用域和闭包之我见
javascript作用域和闭包之我见 看了<你不知道的JavaScript(上卷)>的第一部分--作用域和闭包,感受颇深,遂写一篇读书笔记加深印象.路过的大牛欢迎指点,对这方面不懂的同学 ...
- JavaScript 作用域和闭包——另一个角度:扩展你对作用域和闭包的认识【翻译+整理】
原文地址 --这篇文章有点意思,可以扩展你对作用域和闭包的认识. 本文内容 背景 作用域 闭包 臭名昭著的循环问题 自调用函数(匿名函数) 其他 我认为,尝试向别人解释 JavaScript 作用域和 ...
- 你不知道的JavaScript --- 作用域相关
本篇是<你不知道的JavaScript>的读书笔记 什么是作用域? 程序离不变量,那么变量存储在哪里?程序需要时如何找到他们? 这些问题说明需要一套设计良好的规则来存储变量, 并且之后可以 ...
- JavaScript作用域和闭包
在JavaScript中,作用域是执行代码的上下文.作用域有3种类型: 1.全局作用域 2.局部作用域---(又叫函数作用域) 3.eval作用域 var foo =0;//全局作用域console. ...
- 举例详细说明javascript作用域、闭包原理以及性能问题(转)
转自:http://www.cnblogs.com/mrsunny/archive/2011/11/03/2233978.html 这可能是每一个jser都曾经为之头疼的却又非常经典的问题,关系到内存 ...
- JavaScript 作用域和闭包
作用域的嵌套将形成作用域链,函数的嵌套将形成闭包.闭包与作用域链是 JavaScript 区别于其它语言的重要特性之一. 作用域 JavaScript 中有两种作用域:函数作用域和全局作用域. 在一个 ...
- javascript作用域、闭包、对象与原型链
原文作者总结得特别好,自己收藏一下.^-^ 1.作用域1.1函数作用域JS的在函数中定义的局部变量只对这个函数内部可见,称之谓函数作用域.它没有块级作用域(因此if.for等语句中的花括号不是独立作用 ...
- javascript作用域与闭包
Javasript作用域概要 在javascript中,作用域是执行代码的上下文,作用域有三种类型: 1) 全局作用域 2) 局部作用域(函数作用域) 3) eval作用域 var foo = ...
- JavaScript作用域与闭包总结
1.全局作用域 所有浏览器都支持 window 对象,它表示浏览器窗口,JavaScript 全局对象.函数以及变量均自动成为 window 对象的成员.所以,全局变量是 window 对象的属性,全 ...
- javascript——作用域与闭包
http://www.cnblogs.com/lucio-yr/p/4047972.html 一.作用域: 在函数内部:用 var 声明的表示局部变量,未用var的是全局变量. 作用域取决于变量定义时 ...
随机推荐
- UVALive 5990 Array Diversit
题意:对于一个数列A,substring是一个连续子串,subsequence是其非连续子序列.对于一个数字序列,记它的diversity是它的最大元素减去最小元素的差.给出一个数字序列,求与它div ...
- the identity used to sign the executable is no longer valid.解决方法
the identity used to sign the executable is no longer valid.解决方法 一.重新下载Provisioning Profile 1.到devel ...
- oracle 零散知识汇集
1. Select '登陆' + 2 From dual会报错: ora- 01722 无效数字,原理是oracle把'登陆'当成数字来和2进行加法运算. Select '登陆'|| 2 From d ...
- 账户管理命令 useradd、groupadd
内容提要: 1. 掌握用户的 增/删/改 命令 2. 掌握组的 增/删/改 命令 组管理 1)groupadd groupadd 用于添加组账号.格式如下: groupadd [-g GID] GRO ...
- [PWA] 9. Service worker registerion && service work's props, methods and listeners
In some rare cases, you need to ask user to refresh the browsser to update the version. Maybe becaus ...
- migrate from weblogic to tomcat: directory mapping--reference
Question: I am trying to migrate from weblogic to tomcat. in weblogic I have <virtual-directory-m ...
- Android(java)学习笔记233: 远程服务的应用场景(移动支付案例)
一. 移动支付: 用户需要在移动终端提交账号.密码以及金额等数据 到 远端服务器.然后远端服务器匹配这些信息,进行逻辑判断,进而完成交易,返回交易成功或失败的信息给移动终端.用户提交账号. ...
- HDU 2476 String painter(区间dp)
题意: 给定两个字符串,让求最少的变化次数从第一个串变到第二个串 思路: 区间dp, 直接考虑两个串的话太困难,就只考虑第二个串,求从空白串变到第二个串的最小次数,dp[i][j] 表示i->j ...
- uva 1146 Now or late (暴力2-SAT)
/* 裸地2-SAT问题 关键是模型转化 最小的最大 显然二分 关键是Judge的时候怎么判断 每个航班是早是晚直接影响判断 早晚只能选一个 如果我们定义bool变量xi表示 i航班是否早到 每个航班 ...
- 总结Linux下查看流量工具
Linux服务器要查看带宽情况,可以使用nethogs.dstat.nload.iftop.ifstat工具. 而每个工具都有自己的特色,这里简单总结一下使用方法. 一.nethogs 查看这台设备上 ...