无为清净楼资源网 Design By www.qnjia.com
因为我在写这文章的时候,百度里找资料,找到了园友的一篇文章,写的很好,可是我写了又不想放弃,所以就在里面拿了很多东西过来!~~

[翻译]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';
})()

如果这个是一个面试题,面试官问你这个结果是多少?你怎么回答?

我们先看结果吧!

JavaScript中变量提升 Hoisting

结果是 undefined?和你上面自己想的一样吗?

好吧,我就不故弄玄虚了。其实,这里面隐藏了一个陷阱-----JavaScript中的变量提升(Hoisting);

二。深度剖析

现在我来解释下提升是什么意思?顾名思义,就是把下面的东西提到上面。在JS中,就是把定义在后面的东东(变量或函数)提升到前面中定义。

在解释提升之前,我们先来看一下js中的作用域(scoping)问题。

对于JavaScript新手来说scoping是最令人困惑的部分之一。事实上,不仅仅是新手,我遇到或很多有经验的JavaScript程序员也不能完全理解scoping。JavaScript的scoping如此复杂的原因是它看上去非常像C系语言的成员。请看下面的C程序:

复制代码 代码如下:
#include <stdio.h>
int main() {
int x = 1;
printf("%d, ", x); // 1
if (1) {
int x = 2;
printf("%d, ", x); // 2
}
printf("%d\n", x); // 1
}


这段程序的输出是1,2,1。这是因为在C系语言有块级作用域(block-level scope),当进入到一个块时,就像if语句,在这个块级作用域中会声明新的变量,这些变量不会影响到外部作用域。但是JavaScript却不是这样。在Firebug中试试下面的代码:

复制代码 代码如下:
var x = 1;
console.log(x); // 1
if (true) {
var x = 2;
console.log(x); //2
}
console.log(x);// 2


在这段代码中,Firebug显示1,2,2。这是因为JavaScript是函数级作用域(function-level scope)。这和C系语言是完全不同的。块,就像if语句,并不会创建一个新的作用域。只有函数才会创建新的作用域。

对于大部分熟悉C,C++,C#或是Java的程序员来说,这是意料之外并且不被待见的。幸运的是,因为JavaScript函数的灵活性,对于这个问题我们有一个解决方案。如果你必须在函数中创建一个临时的作用域,请像下面这样做:

复制代码 代码如下:
function foo() {
var x = 1;
if (x) {
(function () {
var x = 2;
// some other code
}());
}
// x is still 1.
}


这种方面确实非常灵活,它使用在任何需要创建一个临时作用域的地方,不仅仅是某个块中。但是,我强烈建议你花点时间好好理解下JavaScript scoping。它实在是非常强力,而且它也是我最喜欢的语言特性之一。如果你很好的理解了scoping,理解hoisting将会更加容易。

2.1变量提升
变量提升,很简单,就是把变量提升提到函数的top的地方。我么需要说明的是,变量提升 只是提升变量的声明,并不会把赋值也提升上来。

比如:

我们定义三个变量:
复制代码 代码如下:
(function(){
var a='One';
var b='Two';
var c='Three';
})()

实际上它是这样子的:

复制代码 代码如下:
(function(){
var a,b,c;
a='One';
b='Two';
c='Three';
})()

这个时候就把变量提升了呀。

好,我们现在回到第一段code里面。为什么会报错呢?其实,根据我么根据上面变量提升原件以及js的作用域(块级作用域)的分析,得知 上面代码真正变成如下:
复制代码 代码如下:
var v='Hello World';
(function(){
var v;
alert(v);
v='I love you';
})()

所以,才会提示说“undefined”。

从这里,我们也学习到,我们在写js code 的时候,我么需要把变量放在块级作用域的顶端,比如我在上面所举的例子:var a,b,c;。防止出现意外。

2.2 函数提升
函数提升是把整个函数都提到前面去。

在我们写js code 的时候,我们有2中写法,一种是函数表达式,另外一种是函数声明方式。我们需要重点注意的是,只有函数声明形式才能被提升。

函数声明方式提升【成功】

复制代码 代码如下:
function myTest(){
foo();
function foo(){
alert("我来自 foo");
}
}
myTest();


函数表达式方式提升【失败】

复制代码 代码如下:
function myTest(){
foo();
var foo =function foo(){
alert("我来自 foo");
}
}
myTest();

结果如下:

JavaScript中变量提升 Hoisting

左边报错了。没骗你。

应该到这里基本都可以弄懂了。~
呵呵。。
再次谢谢Beta Rabbit

作者:Lanny☆兰东才
标签:
变量提升,Hoisting

无为清净楼资源网 Design By www.qnjia.com
广告合作:本站广告合作请联系QQ:858582 申请时备注:广告合作(否则不回)
免责声明:本站文章均来自网站采集或用户投稿,网站不提供任何软件下载或自行开发的软件! 如有用户或公司发现本站内容信息存在侵权行为,请邮件告知! 858582#qq.com
无为清净楼资源网 Design By www.qnjia.com

《魔兽世界》大逃杀!60人新游玩模式《强袭风暴》3月21日上线

暴雪近日发布了《魔兽世界》10.2.6 更新内容,新游玩模式《强袭风暴》即将于3月21 日在亚服上线,届时玩家将前往阿拉希高地展开一场 60 人大逃杀对战。

艾泽拉斯的冒险者已经征服了艾泽拉斯的大地及遥远的彼岸。他们在对抗世界上最致命的敌人时展现出过人的手腕,并且成功阻止终结宇宙等级的威胁。当他们在为即将于《魔兽世界》资料片《地心之战》中来袭的萨拉塔斯势力做战斗准备时,他们还需要在熟悉的阿拉希高地面对一个全新的敌人──那就是彼此。在《巨龙崛起》10.2.6 更新的《强袭风暴》中,玩家将会进入一个全新的海盗主题大逃杀式限时活动,其中包含极高的风险和史诗级的奖励。

《强袭风暴》不是普通的战场,作为一个独立于主游戏之外的活动,玩家可以用大逃杀的风格来体验《魔兽世界》,不分职业、不分装备(除了你在赛局中捡到的),光是技巧和战略的强弱之分就能决定出谁才是能坚持到最后的赢家。本次活动将会开放单人和双人模式,玩家在加入海盗主题的预赛大厅区域前,可以从强袭风暴角色画面新增好友。游玩游戏将可以累计名望轨迹,《巨龙崛起》和《魔兽世界:巫妖王之怒 经典版》的玩家都可以获得奖励。