【javascript知识进阶】变量声明和提升规则和自定义作用域
来源:互联网 发布:交换机基于mac的acl 编辑:程序博客网 时间:2024/06/11 07:41
1.作用域
尽管 JavaScript 支持一对花括号创建的代码段,但是并不支持块级作用域; 而仅仅支持 函数作用域。
function test() { // 一个作用域 for(var i = 0; i < 10; i++) { // 不是一个作用域 // count } console.log(i); // 10}
2.变量声明提升
JavaScript 会提升变量声明。这意味着 var 表达式和 function 声明都将会被提升到当前作用域的顶部。
bar();var bar = function() {};var someValue = 42;test();function test(data) { if (false) { goo = 1; } else { var goo = 2; } for(var i = 0; i < 100; i++) { var e = data[i]; }}
上面代码在运行之前将会被转化。JavaScript 将会把 var 表达式和 function 声明提升到当前作用域的顶部。
// var 表达式被移动到这里var bar, someValue; // 缺省值是 'undefined'// 函数声明也会提升function test(data) { var goo, i, e; // 没有块级作用域,这些变量被移动到函数顶部 if (false) { goo = 1; } else { goo = 2; } for(i = 0; i < 100; i++) { e = data[i]; }}bar(); // 出错:TypeError,因为 bar 依然是 'undefined'someValue = 42; // 赋值语句不会被提升规则(hoisting)影响bar = function() {};test();
没有块级作用域不仅导致 var 表达式被从循环内移到外部,而且使一些 if 表达式更难看懂。
在原来代码中,if 表达式看起来修改了全局变量 goo,实际上在提升规则被应用后,却是在修改局部变量。
如果没有提升规则(hoisting)的知识,下面的代码看起来会抛出异常 ==ReferenceError==。
// 检查 SomeImportantThing 是否已经被初始化if (!SomeImportantThing) { var SomeImportantThing = {};}
实际上,上面的代码正常运行,因为 var 表达式会被提升到全局作用域的顶部。
var SomeImportantThing;// 其它一些代码,可能会初始化 SomeImportantThing,也可能不会// 检查是否已经被初始化if (!SomeImportantThing) { SomeImportantThing = {};}
如果你能理解下面函数为什么弹出==undefined==,那么大概就能理解变量声明提升规则了
var myvar = 'my value'; (function() { alert(myvar); // undefined var myvar = 'local value'; })();
3.名称解析顺序
比如,当访问函数内的 foo 变量时,JavaScript 会按照下面顺序查找:
- 当前作用域内是否有 var foo 的定义。
- 函数形式参数是否有使用 foo 名称的。
函数自身是否叫做 foo。 - 回溯到上一级作用域,然后从 #1 重新开始。
4.自定义作用域
只有一个全局作用域导致的常见错误是命名冲突。
在上一篇博文中的关于for循环中定义setTimeout错误也是这个问题。
在 JavaScript中,这可以通过 ==自执行函数== 轻松解决。
(function() { // 函数创建一个命名空间 window.foo = function() { // 对外公开的函数,创建了闭包 };})(); // 立即执行此匿名函数
自执行函数被认为是 表达式;因此为了可调用性,它们首先会被执行。
( // 小括号内的函数首先被执行function() {}) // 并且返回函数对象() // 调用上面的执行结果,也就是函数对象
大量使用全局变量被认为是不好的习惯。这样的代码容易产生错误并且维护成本较高。
阅读全文
0 0
- 【javascript知识进阶】变量声明和提升规则和自定义作用域
- JavaScript 变量作用域和声明提升
- javascript作用域和声明提升
- JavaScript变量作用域和变量提升
- Javascript作用域和变量提升
- Javascript 作用域和变量提升
- Javascript 作用域和变量提升
- Javascript作用域和变量提升
- Javascript作用域和变量提升
- Javascript作用域和变量提升
- Javascript作用域和变量提升
- Javascript作用域和变量提升
- Javascript作用域和变量提升
- JavaScript作用域和变量提升
- Javascript作用域和变量提升
- javaScript的作用域和变量提升
- javascript的变量提升和作用域
- Javascript作用域和变量提升
- 第一次写博客,谈谈对java的看法
- 【unity学习笔记】 unity常见错误解决方案
- 关于JetPack L4T Component Manager下载出错问题的解决办法
- 求伪逆的三种方法:直接,SVD,QR及具体的应用
- Qt 之 QSqlDriver Class
- 【javascript知识进阶】变量声明和提升规则和自定义作用域
- HDFS数据块
- 你知道line-height怎么用么?
- 面向对象三大特征
- Spring事务配置的五种方式和spring里面事务的传播属性和事务隔离级别
- 一个基础的以太坊介绍
- Java的ListIterator的privious()方法解说
- iOS NSString和NSDate转换
- 转发IP/TCP相关