问答文章1 问答文章501 问答文章1001 问答文章1501 问答文章2001 问答文章2501 问答文章3001 问答文章3501 问答文章4001 问答文章4501 问答文章5001 问答文章5501 问答文章6001 问答文章6501 问答文章7001 问答文章7501 问答文章8001 问答文章8501 问答文章9001 问答文章9501

开发大规模Web应用的目录

发布网友 发布时间:2022-05-18 10:36

我来回答

2个回答

懂视网 时间:2022-05-18 14:57

Scoping & Hoisting



上面这段代码在运行时会产生什么结果?

尽管对于有经验的程序员来说这只是小菜一碟,不过我还是顺着初学者常见的思路做一番描述:

1.创建了全局变量 a,定义其值为 1
2.创建了函数 foo
3.在 foo 的函数体内,if 语句将不会执行,因为 !a 会将变量 a 转变成布尔的假值,也就是 false
4.跳过条件分支,alert 变量 a,最终的结果应该是输出 1

嗯,看起来无懈可击的推理啊,但让人惊讶的是:答案竟然是 2!为什么?

别着急,我会解释给你听。首先我要告诉你这不是什么错误,而是 JavaScript 语言解释器的一个(非官方的)特性,某人(Ben Cherry)把这个特性叫做:Hoisting(目前尚未有标准的翻译,比较常见的是提升)。

声明与定义

为了理解 Hoisting,我们先来看一个简单的情况:

var a = 1;

你是否想过,上面这句代码在运行的时候到底发生了什么?
你是否知道,就这句代码而言,“声明变量 a” 和 “定义变量 a”这两个说法哪一个才是正确的?
•下例叫做 “声明变量”:

var a;

•下例叫做 “定义变量”:

var a = 1;

•声明:是指你声称某样东西的存在,比如一个变量或一个函数;但你没有说明这样东西到底是什么,仅仅是告诉解释器这样东西存在而已;
•定义:是指你指明了某样东西的具体实现,比如一个变量的值是多少,一个函数的函数体是什么,确切的表达了这样东西的意义。

总结一下:

var a; // 这是声明
a = 1; // 这是定义(赋值)
var a = 1; // 合二为一:声明变量的存在并赋值给它

重点来了:当你以为你只做了一件事情的时候(var a = 1),实际上解释器把这件事情分解成了两个步骤,一个是声明(var a),另一个是定义(a = 1)。

这和 Hoisting 有何关系?

回到最开始的那个令人困惑的例子,我告诉你解释器是如何分析你的代码的:



如代码所示,在进入函数体后解释器声明了新的变量 a,而无论 if 语句的条件如何,都将为新的变量 a 赋值为 2。你若不相信可以在函数体外面 alert(a),然后再执行 foo() 对比一下结果就知道了。

Scoping(作用域)

有人可能会问了:“为什么不是在 if 语句内声明变量 a?”

因为 JavaScript 没有块级作用域(Block Scoping),只有函数作用域(Function Scoping),所以说不是看见一对花括号 {} 就代表产生了新的作用域,和 C 不一样!

当解析器读到 if 语句的时候,它发现此处有一个变量声明和赋值,于是解析器会将其声明提升至当前作用域的顶部(这是默认行为,并且无法更改),这个行为就叫做 Hoisting。

OK,大家都懂了,你懂了吗……

懂了不代表就会用了,就拿最开始的例子来说,如果我就是想要 alert(a) 出那个 1 可咋整呢?

创建新的作用域

alert(a) 在执行的时候,会去寻找变量 a 的位置,它从当前作用域开始向上(或者说向外)一直查找到顶层作用域为止,若是找不到就报 undefined。

因为在 alert(a) 的同级作用域里,我们再次声明了本地变量 a,所以它报 2;所以我们可以把本地变量 a 的声明向下(或者说向内)移动,这样 alert(a) 就找不到它了。

记住:JavaScript 只有函数作用域!



你或许在无数的 JavaScript 书籍和文章里读到过:“请始终保持作用域内所有变量的声明放置在作用域的顶部”,现在你应该明白为什么有此一说了吧?因为这样可以避免 Hoisting 特性给你带来的困扰(我不是很情愿这么说,因为 Hoisting 本身并没有什么错),也可以很明确的告诉所有阅读代码的人(包括你自己)在当前作用域内有哪些变量可以访问。但是,变量声明的提升并非 Hoisting 的全部。在 JavaScript 中,有四种方式可以让命名进入到作用域中(按优先级):

1.语言定义的命名:比如 this 或者 arguments,它们在所有作用域内都有效且优先级最高,所以在任何地方你都不能把变量命名为 this 之类的,这样是没有意义的
2.形式参数:函数定义时声明的形式参数会作为变量被 hoisting 至该函数的作用域内。所以形式参数是本地的,不是外部的或者全局的。当然你可以在执行函数的时候把外部变量传进来,但是传进来之后就是本地的了
3.函数声明:函数体内部还可以声明函数,不过它们也都是本地的了
4.变量声明:这个优先级其实还是最低的,不过它们也都是最常用的

另外,还记得之前我们讨论过 声明 和 定义 的区别吧?当时我并没有说为什么要理解这个区别,不过现在是时候了,记住:

Hosting 只提升了命名,没有提升定义

这一点和我们接下来要讲到的东西息息相关,请看:

函数声明与函数表达式的差别

先看两个例子:






同学,在了解了 Scoping & Hoisting 之后,你知道怎么解释这一切了吧?

在第一个例子里,函数 foo 是一个声明,既然是声明就会被提升(我特意包裹了一个外层作用域,因为全局作用域需要你的想象,不是那么直观,但是道理是一样的),所以在执行 foo() 之前,作用域就知道函数 foo 的存在了。这叫做函数声明(Function Declaration),函数声明会连通命名和函数体一起被提升至作用域顶部。

然而在第二个例子里,被提升的仅仅是变量名 foo,至于它的定义依然停留在原处。因此在执行 foo() 之前,作用域只知道 foo 的命名,不知道它到底是什么,所以执行会报错(通常会是:undefined is not a function)。这叫做函数表达式(Function Expression),函数表达式只有命名会被提升,定义的函数体则不会。

尾记:Ben Cherry 的原文解释的更加详细,只不过是英文而已。我这篇是借花献佛,主要是更浅显的解释给初学者听,若要看更多的示例,请移步原作,谢谢。

热心网友 时间:2022-05-18 12:05

Foreword
preface
1.the tenets
managing complexity
molar components
achieving molarity
benefits of molarity
ten tenets for large web applications
2.object orientation
the fundamentals of oop
why object orientation?
uml class diagrams
generalization
association
modeling a web page
defining page types
defining mole types
writing the code
achieving molarity
object-oriented php
classes and interfaces
inheritance in php
object-oriented javascript
objects
inheritance in javascript
3.large-scale html
molar html
a bad example: using a table and presentation markup
a better example: using css
the best example: semantically meaningful html
benefits of good html
html tags
bad html tags
good html tags
ids, classes, and names
conventions for naming
xhtml
benefits of xhtml
xhtml guidelines
rdfa
rdfa triples
applying rdfa
html 5
4.large-scale css
molar css
including css
applying css
specificity and importance
scoping with css
standard mole formats
positioning techniques
css box model
document flow
relative positioning
absolute positioning
floating
layouts and containers
example layouts
example containers
other practices
browser reset css
font normalization
5.large-scale javascript
molar javascript
including javascript
scoping with javascript
working with the dom
common dom methods
popular dom libraries
working with events
event handling normalization
a bad example: global data in event handlers
a good example: object data in event handlers
event-driven applications
working with animation
motion animation
sizing animation
color transition
an example: chained selection lists
6.data management
dynamic moles
data managers
creating data managers
extending data managers
data using sql as a source
an sql example
data using xml as a source
an xml example
data from web services
data in the json format
cookies and forms
managing data in cookies
managing data from forms
7.large-scale php
molar web pages
generating pages in php
working with pages
public interface for the page class
abstract interface for the page class
implementation of the page class
extending the page class
working with moles
public interface for the mole class
abstract interface for the mole class
implementation of the mole class
extending the mole class
an example mole: slideshow
layouts and containers
special considerations
handling mole variations
multiple instances of a mole
dynamic javascript and css
implementing nested moles
8.large-scale ajax
in the browser
managing connections
using ajax libraries
on the server
exchange formats
server proxies
molar ajax
mvc and ajax
using ajax with mvc
public interface for the model object
implementation of the model object
public interface for the view object
abstract interface for the view object
view object implementation
public interface for the connect object
abstract interface for the connect object
implementation of the connect object
controllers
an example of ajax with mvc: accordion lists
9.performance
caching opportunities
caching css and javascript
caching moles
caching for pages
caching with ajax
using expires headers
managing javascript
javascript placement
javascript minification
removing plicates
distribution of assets
content delivery networks
minimizing dns lookups
minimizing http requests
control over site metrics
molar testing
using test data
creating test data
10.application architecture
thinking molarly
organizing components
sitewide architecture
section architecture
architecture for pages
architecture and maintenance
reorganizing mole uses
adding mole variations
making widespread changes
changes in data sources
exposing moles externally
index

声明声明:本网页内容为用户发布,旨在传播知识,不代表本网认同其观点,若有侵权等问题请及时与本网联系,我们将在第一时间删除处理。E-MAIL:11247931@qq.com
最新的PS3与FF13同捆版主机编号CECH-2007B可以播放全区的蓝光碟么? 一个有关PS3同捆问题 我电脑的CPU使用跳动幅度很大,谁能告诉我怎么回事啊? 谁能告诉我的电脑是怎么回事 开机了正常 就是该显示桌面的图标时候十来... 谁能告诉一下 我打开电脑到桌面时出现这样 是怎么回事啊 电脑一开机就出这个谁知道怎么回事啊! 我的x7plus没有信号。 电话交换机设置教程 程控电话交换机怎么设置 程控数字交换机功能 程控交换机如何配置 有了霰粒肿怎么治疗才会有好转? 霰粒肿具体如何治疗 你好,霰粒肿怎么治疗 得了霰粒肿怎么治疗? 霰粒肿的治疗方法 男领导生日送什么礼物好 送男领导什么生日礼物好 50岁领导生日送什么礼物比较好男 员工送男老板过生日送什么礼物呢? 男领导过生日送什么礼物最好 实用才是王道 小狗得了皮肤病,治后好反复 【车主点评:现代途胜 有种品牌叫现代有辆车叫途胜】 SUV中的途胜怎么样,请懂行的人评价一下 现代途胜2.0值不值得买啊到底,途胜网上评价太低了吧 北京现代 途胜 评价一下它的性价比怎么样? 【车主点评:现代途胜我的美好!】 怎么做泡椒才好吃啊 施耐德空调加氟口是那个? 1匹空调外机小管(高压)接头和大管(低压)接头应该哪个在上面和下面,加氟口应该在哪个上面 空调外机加氟口在哪里图 在晚上,我们应该如何护肤? 晚上如何护肤 法律途径和司法途径的区别 可以走司法途径吗? 什么是五鬼日,怎么计算 五鬼凶日是那几日 金口诀五鬼歌看不明白 结婚时犯五鬼日怎么解??帮帮忙 要快 搬家犯五鬼日 五鬼日重丧日同犯是哪些日子? 搬新家如何选好日子,有3个重要环节? 蓝梦岛有异性spa吗 10月去巴厘岛,请大家推荐几个巴厘岛中文代理的联系方式 请问巴厘岛跟团自由活动期间去哪里玩比较好? 巴厘岛是不是属于韩国? 10月1日放假去哪旅游?4000元—5000元左右。谢谢啦 谁能帮我回答下这十个问题,关于java web,高手请进~~~ 集中器和负控终端有什么区别? 配电室里的中央信号装置和负控终端是一回事么 电力需求侧管理终端就是负控终端吗