javascript语言精粹,《JavaScript语言精粹修订版》epub下载在线阅读,求百度网盘云资源
javascript语言精粹,《JavaScript语言精粹修订版》epub下载在线阅读,求百度网盘云资源详细介绍
本文目录一览: 入门JavaScript的书籍有哪些推荐
入门:《深入浅出JavaScript》《JavaScriptDOM编程艺术》《JavaScriptDOM高级程序设计》进阶:《ppk谈JavaScript》《精通JavaScript》《JavaScript高级程序设计》高级:《JavaScript语言精粹》《JavaScript设计模式》《SecretsoftheJavaScriptNinja》《高性能JavaScript》
JavaScript语言精粹的介绍
《JavaScript语言精粹》是2009年由电子工业出版社出版的图书,该书作者是Douglas Crockford,译者是赵泽欣 鄢学鹍。该书从语法、对象、函数、继承、数组、正则表达式、方法、样式和优美的特性这9个方面介绍了javascript语言本质。
JavaScript语言精粹的作品目录
前言. i第1章 精华 1为什么是javascript? 2分析javascript 3一个简单的试验场 4第2章 语法 5空白 5标识符 6数字 7字符串 8语句 10表达式 15字面量 17函数 19第3章 对象 20对象字面量 20检索 21更新 22引用 22原型 22.反射 23枚举 24删除 24减少全局变量污染 25第4章 函数 26函数对象 26函数字面量 27调用 27参数 31返回 31异常 32给类型增加方法 32递归 34作用域 36闭包 37回调 40模块 40级联 42套用 43记忆 44第5章 继承.. 46伪类 47对象说明符 50原型 50函数化 52部件 55第6章 数组 58数组字面量 58长度 59删除 60枚举 60混淆的地方 61方法 62维度 63第7章 正则表达式 65一个例子 66结构 70元素 72第8章 方法 78第9章 代码风格 94第10章 优美的特性 98附录a:糟粕 101附录b:鸡肋 109附录c:jslint 115附录d:语法图 125附录e:json 136索引... 147
求推荐一些关于web前端的一些教程书籍,适合新手的
这里主要介绍一下我在web学习前端开发过程中的一些书和经验。都是一些个人经验,因为每个人的学习方法不同,大家权当参考吧。
我学习一般以看书为主,然后辅以一些优秀的视频教程,还有网上的文章。也有同学以看视频为主的,我舍友就是这样。
如果你是真心想学习web前端、以后想朝着这个方向发展,那么你一定要来这个企鹅裙,前面前面是二9六,中间是5九一,最后面就是二九零,来这里可以这里学习经验,得到专人解答,这样你可以成长的更快!!!
我把现在的书籍一般分为两类,一类是偏理论型的,如“权威指南”这些书;一类是偏实践型的,理论相对较少,比较多例子和接近解决方案。在初学阶段,我一般会各挑选一本比较好的,同时也会借很多同类型的书籍,不过主要是用来做参考,但并不会通读。
例如我在学习javascript的时候,我基本把图书馆基本能借的javascript书都借了,主要是图灵和博文视点出版的书。例如《JavaScript核心技术》,《精通JavaScript
》,《JAVASCRIPT语言精髓与编程实践》,《JavaScript设计模式》,《JavaScript语言精粹》,《JavaScript
DOM编程艺术》,《ppk谈JavaScript》,《高性能网站建设指南
》等,还有其他很多js的书,如果借不到,就直接在图书馆七楼看,例如权威指南;也有一些一般的书,这里没有提到,这些书,我并不是全部都会认真看过,因为初学阶段这样学习效率不高。权威指南我现在还没看完,但是如果要全面深入学习的话,看两本还是不够的。但我喜欢以集中在两本书以内学习作为切入点,这样能使我将精力集中在,并且发现问题。
我在上面提到的书,都是比较好的书,适合不同的阶段,例如《JavaScript语言精粹》这本书是属于很精华的读物,入门的时候看可能会比较吃力,当你对JS有一定的驾驭能力的时候,可能就会发现其中的奥妙。我当时花精力看的主要是《精通JavaScript
》,《JAVASCRIPT语言精髓与编程实践》,《JavaScript核心技术》也花了不少时间,感觉收获不是很大,可能当时理解不够深刻,权威指南也是后来才看。《JavaScript核心技术》给我的帮助没想象中大,但里面说的知识我是很认真在看,可能不适合入门吧,但很多事情冥冥之中的联系谁又能说得清楚呢,早期花时间在《JavaScript核心技术》上未必就是坏事。
《精通JavaScript
》是偏实践型一类的书,作者是JQuery之父,书中有很多非常好的例子,还有jS的相关技巧,兼容浏览器的方法等。有很多例子都是作者处理问题的总结,我当时几乎把里面的每个例子都测试了一遍,受益匪浅,当然,书中也有不少瑕疵,不知道是我借的那本书印刷问题还是怎么的,有些代码运行并不兼容,也有些函数方法并不能成功运行。到后半部分的示例也比较繁琐,我只是粗略看了一番。实际到后来我看网上的评论,这本书适合进阶的人看,现在回头看,感觉确实有jQuery源码分析的感觉,而且部分内容并不适合初学者阅读。但是书中的第三部分确实是很有用的。
上面说了很多关于个人在学习JS上的一些心得,无非也就是想说明一点,有时候并不能找到一本真正适合初学者的书,或者教程。有些书确实不错,未必就适合你,有时候我们也会走错路,但学习不应就此止步。
我接下来会写一些自己读过的书,并且觉得好的书推荐给大家,希望对大家有用:
HTML相关:
《Web标准实战》比较简单,适合入门
《Web标准设计》
《深入浅出HTML》
CSS相关
《CSS设计彻底研究》视频教程很好,书本我并没有详细研究,不好说建议。
《CSS网站布局实录》CSS的书我看得比较少,这本算是看得比较全了,听说第二版不错。
CSS的书有很多非常好的,这里就不一一细说了。/special/webstandards/这个网址有一些相关的介绍。
javascript相关:
《精通JavaScript》第三部分非常好
《JAVASCRIPT语言精髓与编程实践》这本书对原型和继承做了非常精辟的解释,网上大部分关于原型的文章都是参考此书的。
《悟透javascript》这本书第一章是介绍原型和继承的,第三章也介绍了跨域的一个解决方法,还有就是作者对程序和人生的理解哲学很有深度。
《JavaScript权威指南》这本书就不用说了
《高性能网站建设指南》这类书有两本不同版本,都是关于web性能优化的
《JavaScript语言精粹》进阶的好书
《JavaScript设计模式》进阶的好书
SEO;
《SEO教程:搜索引擎优化入门与进阶》这本书有些地方我认为说得不大确切,但是总体还不错。
这些书,大部分都是我读过的,觉得很好,所以推荐给大家。当然好书还不仅仅上述这些而已。如果其他同学觉得还有其他的书不错,也欢迎补充。因为要深入地学习,这些书是远远不够的。
零基础怎么快速学习web前端开发?
网站开发开发大致分为前端和后端,前端主要负责实现视觉和交互效果,以及与服务器通信,完成业务逻辑。其核心价值在于对用户体验的追求。昌平计算机学习建议可以按如下思路学习系统学习:
基础知识:
1、HTML+CSS这部分建议在W3school在线教程上学习,边学边练,每章后还有小测试。之后可以模仿一些网站做些页面。在实践中积累了一些经验后,可以系统的读一两本书,推荐《HeadFirstHTML与CSS中文版》,这本书讲的太细了,我没能拿出耐心细读。你可以根据情况斟酌。
2、JavaScript要学的内容实在很多,如果没有其他编程语言的基础的话,学起来可能要费些力,还是建议先在W3school上学习。之后建议马上看《Javascript语言精粹》,JS是一门很混乱的语言,这本书能够帮助你区分哪些是语言的精华,哪些是糟粕,对于语言精华,应该深入学习。糟粕部分能看懂别人写的代码就行,自己就不用尝试了。
进阶:
有了以上基础,就可以进行一般的静态网页设计,不过对于复杂的页面还需要进一步学习。
1、CSS。必看《精通CSS》,看完这本书你应该对:盒子模型,流动,Block,inline,层叠,样式优先级,等概念非常了解了。作为练习可以看下《CSS艺门之匠》这本书,它对标题,背景,圆角,导航条,table,表单等主题都有详细的介绍。
2、Javascript。上面提到内容还不足以让你胜任JS编程。在有了基础之后,进一步学习内容包括:
a)框架。
推荐jQuery,简单易用,在W3school简单学习js后,直接上手jQuery即可完成一些简单的项目。学习方法也很简单,照着产品文档做几个页面就行了,不用面面俱到,以后遇到问题查文档就行了。框架可以帮你屏蔽浏览器的差异性,让你能更专注与Web开发学习的精髓部分。补充:可以使用Codecademy学习Javascript,jQuery,用户体验真的很好(感谢TonyOuyang)。
b)Javascript语言范式。这个名字可能并不恰当,只是我找不到可以描述“面向对象”,“函数式”这个两个概念的概念。Javascript不完全是一个面向对象的语言,它的很多设计理念都有函数编程语言的影子,甚至说如果你不用面向对象,完全可以把它理解成一门函数式编程语言。
Javascript的很多语言特性,都是因为他具有函数式语言的特点才存在的。这部分推荐先学习面向对象的基本理论,对封装,继承,多态等概念要理解,维基百科,百度百科会是你的帮手,另外推荐《ObjectOrientedJavascript》,应该有中文版。对与函数式编程我了解的也不系统,不好多说,可以自己百度一下。
c)Javascript语言内部机制。必须弄清如下概念:JS中变量的作用域,变量传递方式,函数的定义环境与执行环境,闭包,函数的四种调用方式(一般函数,对象的方法,apply,call),以及四种调用方式下,‘this’指向的是谁。这部分内容你会在《Javascript语言精粹》中详细了解。另外,你必须理解json。
d)dom编程,这个Web前端工程师的核心技能之一。必读《Dom编程艺术》,另外《高性能Javascript》这本书中关于dom编程的部分讲的也很好。
e)Ajax编程,这是另一核心技术。Ajax建议在网上查些资料,了解这个概念的来龙去脉,百度百科,维基百科上的内容就足够了。真正编程是很容易的,如今几乎所有框架都对Ajax有良好的封装,编程并不复杂。
如何理解JavaScript语言精粹中的函数化模式
1.方法调用模式
当一个函数被保存为对象的一个属性时,我们称之为一个方法。当一个方法被调用时,this被绑定到该对象。
[javascript] view plain copy
function A() {
this.x = 1; //定义a.x
this.b = function () { //定义a.b
this.helper = function () { //定义a.helper
console.log(this); //4.console.log(a)
}
this.helper(); //3.调用a.helper(); 此时的helper,是一个方法,所以helper中的this指向a
}
this.b(); //2.调用a.b(),此时的b是a的一个属性,所以是一个方法,所以b中的this指向a
}
var a = new A(); //1.创建a对象
输出: A {x:1}
2.函数调用模式
当一个函数不是一个对象的属性时,就是被当做一个函数来调用的。此时this被绑定到全局对象。
[javascript] view plain copy
function A() {
this.x = 1;
this.b = function () {
var helper = function () {
console.log(this);
}
helper(); //此时的helper不是任何对象的属性,只是一个函数
}
this.b();
}
var a = new A();
输出: Window {external: Object, ......}
3.构造器调用模式
用new关键字,此时this被绑定到创建出来的新对象上。
[javascript] view plain copy
function A() {
this.x = 1;
this.b = function () {
this.helper = function () { //定义aa.helper
console.log(this); //4.console.log(aa)
}
this.helper(); //3.调用aa.helper(); 此时的helper,是一个方法,所以helper中的this指向aa
}
var aa = new this.b(); //2.创建一个新的对象aa,所以b()中的this指向aa
}
var a = new A(); //1.创建a对象
输出: A.b {} ;
另外,这里举Splunk吉祥物pony的例子来说一说new操作符做的事情:
[javascript] view plain copy
function Pony(color) {
// var this = Object.create(Pony.prototype);
// instance members
this.color = color;
// private members
var age = 50;
// private methods
function secreteMethod() {
console.log('Secret!');
}
// make private member visible due to closure
this.getAge = function() {
console.log('My age is : ' + age);
};
// return this;
}
// methods
Pony.prototype.tellColor = function() {
console.log('I am ' + this.color);
};
// static attributes
Pony.type = 'horse';
var pony = new Pony('white');
pony.tellColor();
pony.getAge();
what happens?
[javascript] view plain copy
var pony = new Pony('white');
// equals
var pony = {};
pony.__proto__ = Pony.prototype;
Pony.call(pony, 'white');
4.apply调用模式
js是一门函数式的面向对象编程语言,所以函数可以有方法。apply(or call)方法允许我们构建一个参数数组传递给调用函数,也允许我们选择this的值。它接受两个参数,第一个是要绑定给this的值,第二个是一个参数数组。
[javascript] view plain copy
function People (name) {
this.name = name;
}
People.prototype.greet = function () {
console.log('hi,'+this.name);
};
var dog = {
name: 'hobbo'
};
People.prototype.greet.apply(dog);
输出: hi,hobbo
总结:
this默认指向global object
当函数作为对象的属性被调用时,函数中的this指向那个对象
当使用new操作符来调用函数时,函数中的this指向新创建的对象
当使用apply或者call来调用函数时,this指向被传给call活apply的第一个参数。如果第一个参数是空或者不是一个对象,this指向global object
JavaScript语言精粹78页push方法如何实现的
js中函数(或者称方法),也是对象。
apply就是函数对象的方法(call也是,功能类似,参数不同)。
js中函数或方法调用的时候,需要有主体对象(this),如果没指定,默认是全局对象(浏览器中就是 window),如果是定义在某个对象的方法,通过某个对象的实例调用,主体对象就是该对象的实例。
如果需要在调用方法的时候改变主体对象,就需要用到apply或call两个方法。
//函数定义apply(object,arguments);call(object, ...args);两者都是将函数定义时的主体对象,转移到第一个参数object上,区别在于apply第二个参数是一个数组,数组元素对应该方法或函数的参数,而call定义是无限参数,从第二个参数开始依次对应到该方法第一个参数。
所以,你截图中这段代码,可以这样解释:
//以下为将原代码语句拆分后的解释//这个是准备传递到splice的参数(第1,2位)var newargs= [this.length,0];//arguments 就是当前函数调用的全部参数,是一个类数组对象,但不是数组//所以要将Array的slice方法用到arguments上就用到了apply,这里将参数转换为数组var curargs=Array.prototype.slice.apply(arguments);//将第1,2位参数和后面参数(需要加到数组的元素)合并起来newargs=newargs.concat(curargs);//调用apply,对象其实还是自己,把上面的参数传进来this.splice.apply(this,newargs);
《JavaScript语言精粹修订版》epub下载在线阅读,求百度网盘云资源
《JavaScript语言精粹》(Douglas Crockford)电子书网盘下载免费在线阅读
资源链接:
链接:https://pan.baidu.com/s/1cZk6niLEBy1Br6gvtjxZdQ
提取码:y0jn
书名:JavaScript语言精粹
作者:Douglas Crockford
译者:赵泽欣
豆瓣评分:9.1
出版社:电子工业出版社
出版年份:2009-4
页数:155
内容简介:
本书通过对JavaScript语言的分析,甄别出好的和坏的特性,从而提取出相对这门语言的整体而言具有更好的可靠性、可读性和可维护性的JavaScript的子集,以便你能用它创建真正可扩展的和高效的代码。
雅虎资深JavaScript架构师Douglas Crockford倾力之作。
向读者介绍如何运用JavaScript创建真正可扩展的和高效的代码。
作者简介:
Douglas Crockford是一名来自Yahoo!的资深JavaScript架构师,以创造和维护JSON (JavaScriptObject Notation) 格式而为大家所熟知。他定期在各类会议上发表有关高级JavaScript的主题演讲。
关于JavaScript 的好书有哪些
推荐《javascript高级程序设计》,这本书也是我现在正在看的书,觉得还不错现在现在已经出了第二版了,感觉主要是让我们以面向对象的思想去编写javascript。
第一本:《JavaScript权威指南》,经典级教材,很厚一本,俗称“犀牛书”,囊括了JS几乎所有的基础知识,新版本还加入了最新的技术内容,适合初学者,有经验的开发者也常常作为随手翻阅的语法书。
第二本:《JavaScript语言精粹》,俗称“蝴蝶书”,是介绍JavaScript语言本质一本书,教你全面了解这门语言的糟粕部分,构建出优雅高效的代码。
第三本:《JavaScript高级程序设计》,这本是我强烈推荐的,是非常经典的JavaScript畅销书,内容全面深入、贴近实战,详细讲解了JavaScript语言的核心,又展示了现有规范及实现以及为开发Web应用提供的各种支持和特性。
如何编写高质量JS代码_基础知识
想写出高效的javascript类库却无从下手;尝试阅读别人的类库,却理解得似懂给懂;打算好好钻研js高级函数,但权威书上的内容太零散,即使记住“用法”,但到要“用”的时候却没有想“法”。也许你和我一样,好像有一顾无形的力量约束着我们的计划,让我们一再认为知识面的局限性,致使我们原地踏步,难以向前跨越。这段时间,各种作业、课程设计、实验报告,压力倍增。难得挤出一点点时间,绝不睡懒觉,整理总结往日所看的书,只为了可以离写自己的类库近一点。本文参考自《javascript语言精粹》和《Effective JavaScript》。例子都被调试过,理解过后,我想把一些“深奥”的道理说得浅显一点点。1.变量作用域作用域对于程序员来说就像氧气。它无处不在,甚至,你往往不会去想他。但当它被污染时(例如使用全局对象),你会感觉到窒息(例如应用响应变慢)。javascript核心作用域规则很简单,被精心设计,且很强大。有效地使用javascript需要掌握变量作用域的一些基本概念,并了解一些可能导致难以捉摸的、令人讨厌的问题的极端情况。1.1尽量少用全局变量javascript很容易在全局命名空间中创建变量。创建全局变量毫不费力,因为它不需要任何形式的声明,而且能被整个程序的所有代码自动地访问。对于我们这些初学者,遇到某些需求(例如,传输的数据被记录下来、等待某时机某函数调用时使用;或者是某函数被经常使用)时,好不犹豫想到全局函数,甚至大一学到的C语言面向过程思想太根深蒂固,系统整整齐齐地都是满满函数。定义全局变量会污染共享的公共命名空间,并可能导致意外的命名冲突。全局变量也不利于模块化,因为它会导致程序中独立组件间的不必要耦合。严重地说,过多的全局(包括样式表,直接定义div或者a的样式),整合到多人开发过称将会成为灾难性错误。这就是为什么jQuery的所有代码都被包裹在一个立即执行的匿名表达式——自调用匿名函数。当浏览器加载完jQuery文件后,自调用匿名函数立即开始执行,初始化jQuery的各个模块,避免破坏和污染全局变量以至于影响到其他代码。 代码如下:(function(window,undefined){ var jQuery = ... //... window.jQuery = window.$ = jQuery;})(window);另外,你或许会认为,“先怎么怎么写,日后再整理”比较方便,但优秀的程序员会不断地留意程序的结构、持续地归类相关的功能以及分离不相关的组件,并这些行为作为编程过称中的一部分。 由于全局命名空间是javascript程序中独立的组件经行交互的唯一途径,因此,利用全局命名控件的情况是不可避免的。组件或程序库不得不定义一些全局变量。以便程序中的其他部分使用。否则最好使用局部变量。 代码如下:this.foo ;//undefinedfoo = " global foo";this.foo ;//"global foo"var foo = "global foo";this.foo = "changed";foo ;//changedjavascript的全局命名空间也被暴露在程序全局作用域中可以访问的全局对象,该对象作为this关键字的初始值。在web浏览器中,全局对象被绑定在全局window变量。这就意味你创建全局变量有两种方法:在全局作用域内使用var声明他,或者将其加入到全局对象中。使用var声明的好处是能清晰地表达全局变量在程序范围中的影响。鉴于引用为绑定的全局变量会导致运行时错误,因此,保存作用域清晰和简洁会使代码的使用者更容易理解程序声明了那些全局变量。由于全局对象提供了全局环境的动态反应机制,所以可以使用它查询一个运行环境,检测在这个平台下哪些特性可用。eg.ES5引入了一个全局的JSON对象来读写JSON格式的数据。 代码如下:if(!this.JSON){ this.JSON = { parse : .., stringify : ... } } 如果你提供了JSON的实现,你当然可以简单无条件地使用自己的实现。但是由宿主环境提供的内置实现几乎更适合的,因为它们是用C语言写进浏览器的。因为它们按照一定的标准对正确性和一致性进行了严格检查,并且普遍来说比第三方实现提供更好的性能。当初数据结构课程设计模拟串的基本操作,要求不能使用语言本身提供的方法。javascript对数组的基本操作实现得很好,如果只是出于一般的学习需要,模拟语言本身提供的方法的想法很好,但是如果真正投入开发,无需考虑第一时间选择使用javascript内置方法。1.2避免使用withwith语句提供任何“便利“,让你的应用变得不可靠和低效率。我们需要对单一对象依次调用一系列方法。使用with语句可以很方便地避免对对象的重复引用: 代码如下:function status(info){ var widget = new Widget(); with(widget){ setBackground("blue"); setForeground("white"); setText("Status : "+info); show(); } }使用with语句从模块对象中”导入“(import)变量也是很有诱惑力的。 代码如下:function f(x,y){ with(Math){ return min(round(x),sqrt(y));//抽象引用 }}事实上,javascript对待所有的变量都是相同的。javascript从最内层的作用域开始向外查找变量。with语言对待一个对象犹如该对象代表一个变量作用域,因此,在with代码块的内部,变量查找从搜索给定的变量名的属性开始。如果在这个对象中没有找到该属性,则继续在外部作用域中搜索。with块中的每个外部变量的引用都隐式地假设在with对象(以及它的任何原型对象)中没有同名的属性。而在程序的其他地方创建或修改with对象或其原型对象不一定会遵循这样的假设。javascript引擎当然不会读取局部代码来获取你使用了那些局部变量。javascript作用域可被表示为高效的内部数据结构,变量查找会非常快速。但是由于with代码块需要搜索对象的原型链来查找with代码里的所有变量,因此,其运行速度远远低于一般的代码块。替代with语言,简单的做法,是将对象绑定在一个简短的变量名上。 代码如下:function status(info){ var w = new Widget(); w.setBackground("blue"); w.setForeground("white"); w.setText("Status : "+info); w.show(); }其他情况下,最好的方法是将局部变量显式地绑定到相关的属性上。 代码如下:function f(x,y){ var min = Math.min, round = Math.round, sqrt = Math.sqrt; return min(round(x),sqrt(y));}1.3熟练掌握闭包理解闭包有单个概念:a)javascript允许你引用在当前函数以外定义的变量。 代码如下:function makeSandwich(){ var magicIngredient = "peanut butter"; function make(filling){ return magicIngredient + " and " + filling; } return make("jelly"); }makeSandwich();// "peanut butter and jelly"b)即使外部函数已经返回,当前函数仍然可以引用在外部函数所定义的变量 代码如下:function makeSandwich(){ var magicIngredient = "peanut butter"; function make(filling){ return magicIngredient + " and " + filling; } return make; }var f = sandwichMaker();f("jelly"); // "peanut butter and jelly"f("bananas"); // "peanut butter and bananas"f("mallows"); // "peanut butter and mallows"javascriptd的函数值包含了比调用它们时所执行所需要的代码还要多的信息。而且,javascript函数值还在内部存储它们可能会引用的定义在其封闭作用域的变量。那些在其所涵盖的作用域内跟踪变量的函数被称为闭包。 make函数就是一个闭包,其代码引用了两个外部变量:magicIngredient和filling。每当make函数被调用时,其代码都能引用这两个变量,因为闭包存储了这两个变量。函数可以引用在其作用域内的任何变量,包括参数和外部函数变量。我们可以利用这一点来编写更加通用的sandwichMaker函数。 代码如下:function makeSandwich(magicIngredient){ function make(filling){ return magicIngredient + " and " + filling; } return make; }var f = sandwichMaker(”ham“);f("cheese"); // "ham and cheese"f("mustard"); // "ham and mustard"闭包是javascript最优雅、最有表现力的特性之一,也是许多习惯用法的核心。c)闭包可以更新外部变量的值。事实上,闭包存储的是外部变量的引用,而不是它们的值的副本。因此,对于任何具有访问这些外部变量的闭包,都可以进行更新。 代码如下:function box(){ var val = undefined; return { set : function(newval) {val = newval;}, get : function (){return val;}, type : function(){return typeof val;} };}var b = box();b.type(); //undefinedb.set(98.6);b.get();//98.6b.type();//number该例子产生一个包含三个闭包的对象。这三个闭包是set,type和get属性,它们都共享访问val变量,set闭包更新val的值。随后调用get和type查看更新的结果。1.4理解变量声明提升javascript支持此法作用域(对变量foo的引用会被绑定到声明foo变量最近的作用域中),但不支持块级作用域(变量定义的作用域并不是离其最近的封闭语句或代码块)。不明白这个特性将会导致一些微妙的bug: 代码如下:function isWinner(player,others){ var highest = 0; for(var i = 0,n = others.length ;i highest){ highest = player.score; } } return player.score > highest;}1.5 当心命名函数表达式笨拙的作用域 代码如下:function double(x){ return x*2; }var f = function(x){ return x*2; }同一段函数代码也可以作为一个表达式,却具有截然不同的含义。匿名函数和命名函数表达式的官方区别在于后者会绑定到与其函数名相同的变量上,该变量作为该函数的一个局部变量。这可以用来写递归函数表达式。 代码如下:var f = function find(tree,key){ //.... return find(tree.left , key) || find(tree.right,key); }值得注意的是,变量find的作用域只在其自身函数中,不像函数声明,命名函数表达式不能通过其内部的函数名在外部被引用。 代码如下:find(myTree,"foo");//error : find is not defined; var constructor = function(){ return null; }var f= function(){ return constructor();};f();//{}(in ES3 environments)该程序看起来会产生null,但其实会产生一个新的对象。因为命名函数变量作用域内继承了Object.prototype.constructor(即Oject的构造函数),就像with语句一样,这个作用域会因Object.prototype的动态改变而受到影响。在系统中避免对象污染函数表达式作用域的办法是避免任何时候在Object.prototype中添加属性,以避免使用任何与标准Object.prototype属性同名的局部变量。 在流行的javascript引擎中另外一个缺点是对命名函数表达式的声明进行提升。 代码如下:var f = function g(){return 17;}g(); //17 (in nonconformat environment)一些javascript环境甚至把f和g这两个函数作为不同的对象,从而导致不必要的内存分配。1.6 当心局部块函数声明笨拙的作用域 代码如下:function f() {return "global" ; }function test(x){ function f(){return "local";} var result = []; if(x){ result.push(f()); } result.push(f()); result result;}test(true); //["local","local"]test(false); //["local"] 代码如下:function f() {return "global" ; }function test(x){ var result = []; if(x){ function f(){return "local";} result.push(f()); } result.push(f()); result result;}test(true); //["local","local"]test(false); //["local"]javascript没有块级作用域,所以内部函数f的作用域应该是整个test函数。一些javascript环境确实如此,但并不是所有javascript环境都这样,javascript实现在严格模式下将这类函数报告为错误(具有局部块函数声明的处于严格模式下的程序将报告成一个语法错误),有助于检测不可移植代码,为未来的标准版本在给局部块函数声明给更明智和可以的语义。针对这种情况,可以考虑在test函数内声明一局部变量指向全局函数f。