JavaScript:语言精粹

本文根据Douglas Crockford的《The Good Parts of JavaScript and the Web》的课程内容整理而成。 还参考了一些其余资料在文章结尾部分标出。javascript

另外我将课程视频翻译一下,连接在这里呀《JavaScript语言精粹》java

  • 第一节:这就是JavaScript
  • 第二节:函数是第一公民
  • 第三节:进击的Ajax
  • 第四节:ES5的新世界
  • 第五节:函数趣事
  • 第六节:安全的本质
  • 第七节:同步的控制
  • 第八节:更好的将来

##第一节:这就是JavaScript程序员

  • JavaScript历史
  • Object
  • Number
  • Boolean 和 String
  • Array
  • Date,RegEx,&Type
  • JavaScript语法
  • JavaScript语句

JavaScript历史

在伊利诺伊大学厄本那 - 香槟分校的国家超级计算应用中心,有许多孩子正在为互联网开发应用程序。那时有许多协议被考虑用于在互联网上向人们传输信息,这些方法有WAIS,Archie,Gopher,FTP,Finger,和其余一些协议还有万维网,人们并不知道哪个会赢。因此他们写了一个适用于全部人的应用程序,他们叫它 Mosaic(全球最先一款能够显示图片的浏览器)。由于这种方式实现了在万维网上的浏览功能,万维网赢得了胜利。他们作的事情是他们想出了一个叫作图片标签的东西,它可以在网页上显示图片,这是其余方式没法轻易作到的,由于网页能够显示图像,是它让万维网赢了今后进入了快速的发展。web

这个项目中的一些人来到了加州,在那里他们成立了一个叫网景的公司,网景公司制做了第一款商业浏览器叫网景导航者(Netscape Navigator),这是一个巨大的转折。他们还增长了一系列新功能,他们还想让终端用户的程序变得更简单。它们想作一个相似Mac上HyperCard的程序,HyperCard是一个能够建立简单的应用程序的应用。他们也想让浏览器实现这些功能,因此他们把这项工做交给Brendan Eich。他曾经是Silicon Graphics的内核程序员,正则表达式

他的想法时写一个scheme的解释器去实现,可是他被告诉不要用scheme。去作一我的们喜欢的,流行的语言,类是于Java或者VB,这语言是给小孩准备的。因此他花了10天建立了新的交互形式的浏览器属性,而后又花了10天去设计和实现了一个新的语言。他拿来了编程

  • Java中的语法
  • Scheme中的函数
  • Self中原型的概念

网景给它取名 LiveScript。网景公司浏览器的大获成功引发了微软的注意。同时,在太阳公司设计出了Java语言,能够经过Java虚拟机来摆脱微软。而后也用Java语言作了一个浏览器叫“HotJava”,也很是成功。微软哪能对它们会坐视无论。因此为了一块儿抵抗微软,网景和太阳公司说咱们联盟吧。第一步的计划是,在Netscape浏览器中加入Java,而后太阳公司不接着开发“HotJava”浏览器了。第二步,太阳公司跟网景说,你别整你那LiveScript了,你直接用个人Java。网景公司不一样意,首先是由于Netscape浏览器用Java的方式是用LiveScript接口与浏览器进行通讯的。若是大改的话,影响发版啊。我哪等的起。要不我把名改为从LifeScript改成JavaScript吧。咱就说这是Java的一个子集,Java的小弟弟。太阳公司说也行吧。因而哥俩手拉手出去开个发布会,说了这个谎。因此到今天还有人觉得他俩是亲兄弟呢,清醒一点,一点血缘关系都没有,两个妈两个爹的~哈哈。数组

微软那边也没闲着,先是买了一个作浏览器的公司叫Spyglass,而后把它们的浏览器改个名叫IE。下一步,差啥了?对,缺个JavaScript。别闲着,弄吧。微软团队作事那叫一个认真啊,无论是JavaScript的错误,bug,仍是设计缺陷,同样没改的都给逆向实现了。作完了也不能叫JavaScript,由于Sun拥有JavaScript商标。那咱们就叫它Jscript吧。浏览器

网景公司开始担忧,这样整不完了嘛,赶忙我得整个语言的标准。而后他们去找到W3C。W3C说,滚,没工夫搭理你。接着又去找了ISO,ISO也没吱声。最后总算找到了欧洲计算机制造商协会(ECMA)。ECMA说那咱得成立个委员会啊。而后微软加入了委员会而且占了主导地位,最后这个标准也是基于微软的文档制做的。那这个标准咱们也得起个名,那就用工做委员会名称把叫 ECMAScript。Douglas在课上说这真TM难听~哈哈哈哈安全

如今用的大多数版本是1999年12月出版的IE第三版。而后作了第四版,版本持续了十年最后被放弃了。 在2009年,出版了第五版定义了两种语言,严格的和默认的。2015年,第六版发布。后边咱们会用到ES6。如今咱们回过头来想一想,JavaScript很差的地方来自哪呢?bash

  • 一个是遗留下来的,任何语言中发生的不少事情都是重复之前语言中发生的错误
  • 另一些是好的愿望,一些特性被加到语言中,但愿它变得简单,可是失败了。
  • 最后就是匆忙了,十天时间对于设计和实现编程语言来讲过短。

Object

在JavaScript中,对象是一个可变键值对的集合。每一个属性都有一个在该对象中惟一的键(key)字符串。这个键(key)能够存听任何值。而后你能够对对象进行读取,设置和删除。

  • Get:可使用点表示法或方括号表示法从对象获取属性,方括号中的表达式是一个字符串,这样能够动态访问
  • Set:经过简单的赋值操做
  • Delete:可使用delete操做符从对象中删除属性,少看被用过

须要注意的是 键必须是字符串 ,将任何类型放到方括号中,但JavaScript会将其转换为字符串。一旦建立一个对象,就会拥有这些方法。

能够用对象自面量的方法去建立一个对象。若是对象中属性命名的字段是合法的标识符,就没必要加上引号。否则要加上引号。

大多数经典的面向对象语言,它们都是建立类,而后对象是类的实例,而且类继承自其余的类。JavaScript有一个更简单,更先进的设计。它是基于原型(prototype),其中对象继承自对象。 这是一种委托(delegation )继承的方式。咱们用Object.create()方法去实习。

下面的这个例子,

  • 咱们先用字面量的方法来建立一个mother的对象,有a、b两个属性。全部经过对象字面量的方法建立的对象都链接到Object.prototype,这个JavaScript中标准的对象。
  • 而后使用object.create(mother)方法建立一个daughter的对象,继承自mother。
  • 若是让daughter的b加2,自己没有值b是继承mother的值b。因此加完等于4,把它存放在daughter对象中。

读取操做是沿着原型链进行查找的,储存操做将始终在最外的对象中


Number

在JavaScript中,Number是一个比Java更简单的数字系统,没有ints(原始类型整数) and integers(包装类型整数)。它基于IEEE-754标准的64位二进制浮点,在Java和其余语言中被叫成双重浮点。

  • 这样就有一个缺陷就是交换律不在生效。
  • 最大数字是9千万亿,以上数字会失真。

由于咱们用二进制浮点表示小数部分,因此小数部分是进行模拟的,这样就会出现。

0.1 + 0.2 == 0.30000000000000004;
复制代码

Number是一个基本包装类型,因此他有继承自number.prototype的方法。

不过与对象不一样的是,对象的生命周期。

let a = 0.30000000000000004;

let b = a.toFixed(2) //生命周期存在与这一行代码中。

------------------

let a = new Number(0.30000000000000004); //在调用方法时会建立一个Number类型的一个实例
let b = a.toFixed(2); //在实例上调用指定的方法
a = null;             //销毁这个实例
复制代码

这意味着咱们不能在运行时调加方法。

Java在拥有一个单独的数学对象,当时Java是由于考虑到计算机的配置,准备在低配的电脑中将数学函数的功能删除,但计算机的配置愈来愈高,这并无发生。JavaScript也拿来了这个Math对象。

  • 还有一个特殊的数字NaN, NaN表明没有定义或者错误的运算。NaN不等于NaN
  • 值Infinity表明极大值

Boolean 和 String

Boolean有两个值true 和 false

String字符串是不可改变的,一旦你建立一个字符串,它就没法更改。因此说不管你在 string 类型上调用何种方法,都不会对值有改变。

String能够用单引号或者双引号的字面量方式来表示。建议双引号程序以外的字符串好比URL等。 单引号用于程序以内的,好比属性等。

字符串和数字之间能够相互转化:字符串转化成为数字

  • 用Number( )函数
  • 用一元加操做符
  • 用parseInt函数

parseInt是从Java借鉴来的东西,它会将值转换为数字,但会在第一个非数字字符处中止解析,而且不返回任何缘由。这个设计很是糟糕,因此不推荐使用它。

数字转化成为字符串:

  • 用toString方法
  • 用String 函数

字符串有以下这些方法


Array

数组是基本数据结构之一。当JavaScript的第一个版本并无数组,咱们只能使用对象。经过传递数字,数字变成字符串,相似数组同样的工做。如今有了数组的数据类型,它继承自object,索引转换为字符串。

咱们能够建立一个数组用对象字面量,数组有一个特定的长度属性,而且该属性老是比最高整数下标大1。能够经过设置它的当前长度去添加数组。

Arrays有一套比对象更有趣的方法,对象几乎没有来自原型的有用方法,这些方法都存储在array.prototype中,很是有用。

例如,有sort方法,咱们能够在其中获取一组数字,它正在对字符串进行排序。sort能够采用一个函数参数来接收值对,并根据它们的相对大小返回-1,0或1。因此你能够覆盖这种可怕的行为。

arr.sort((a,b)=>a-b);  //数字从大到小排序
复制代码

个人建议用对的那个,当名称是任意字符串时使用对象,当名称是连续整数时使用数组,不要被术语所迷惑。


Date,RegEx,&Type

Date函数,它的灵感来自Java的Date类,当它在1995年被推出时,还存在 Y2K(千年虫)bug,但终究咱们幸免于难。它已被修复,因此咱们如今能够用了。

咱们也获得了正则表达式,它是从Perl 4借来。这是一个匹配正则表达式文字的正则表达式,但正则表达式必须连在一块儿写,因此对于很长的正则就变得很难读懂。

你能够经过Regulex这个网站,可以用铁路图来表示正则,强烈推荐。

在JavaScript中,全部的值都是对象,除null和undefined以外,它们有时被称为底值。它们很类似,但并不彻底相同,因此不能互换。因此我建议只使用其中一个,选择使用的是undefined,由于这是语言自己使用的那个,它是变量和参数的默认值。若是试图检索对象中不存在一个属性,它不会报错,它会给你undefined。

JavaScript中有一个type运算符,它将返回一个字符串来标识数据类型。

  • 你传递一个数组,它将返回object,这不是一个技术上的错误,由于它是对象,可是这样很没有用。你能够用Array.isArray去判断是不是一个数组
  • 你传递一个null,它将返回object,这就是一个设计上的错误。没有啥理由。更糟糕的是,你想去判断是不是一个对象的时候,还有一个null值,由于它不是对象。(《js高程》上说null返回对象,是为了表示变量将来是一个对象。总之这是一个很差的设计吧。)

JavaScript有一点很蠢,它的每个值都是真或者为假

  • 假值有false,null,undefined,空字符串,0,and NaN
  • 剩下全部值都是真,包括字符串0,和字符串false,全部的对象数组甚者它们是空的

JavaScript是一种松散类型的语言,任何这些类型均可以存储在任何变量中,或做为参数传递给任何函数。这很好,由于在强类型语言中,你最终会花费大量时间来对付类型系统,但其实效果并无那么好。

所以在JavaScript中,对象是经过引用而不是经过值传递,这意味着不会复制对象。事实上,在JavaScript中没有简单的方法来复制一个对象。 “===”运算符比较对象引用,所以只有当两边都是同一个对象时它才会为真


JavaScript语法

JavaScript在语法上是C家族的一员,咱们有标识符,能够以字母、下划线、美圆符号开始

咱们拥有与C类语言相同的运算符集,其中一些工做方式有点不一样,这是你须要注意。JavaScript一个重大错误是加号运算符同时执行加法和链接。这是从Java学到的坏习惯,在Java中,它并非那么糟糕,由于它强类型。JavaScript是松散的类型,若是它们都是数字,它会将它们相加。不然,它会将它们转换为字符串并将它们链接起来,这很糟糕。

咱们已经谈过双平等号及其存在的问题,建议你老是使用三等号。

  • 逻辑符“&&”的工做方式,若是第一个操做数是真实的,则结果是第二个操做数的值。否则,结果为一个操做数的值,所以第二个操做数将不会判断,它确实会短路。
  • 逻辑“||”是工做与它类似的
  • “!”是逻辑非运算符
  • 若是你有!!,!两次,它会将值变为布尔值


JavaScript语句

咱们有一套你指望在C语言中看到的语句,一样有一些差别。

咱们有break标签,因此,若是你有嵌套循环和switch这些东西,这很好。

咱们有for语句能够用来迭代数组,但我不建议使用它。在ES5中,咱们有了forEach和map方法,你能够在数组的每一个元素上调用一个函数。这几乎消除了对for循环的全部需求,所以咱们再也不使用for循环了。

咱们有一个for in语句,它遍历对象的全部属性的名称,不幸的是,它还会遍历全部继承的属性,这些属性一般是你的方法。所以你的方法会与你的数据混淆而且变得一团糟,幸运的是,在ES5中咱们获得了Object.keys。它接受一个对象并返回一个字符串数组,这些字符串只是对象的可枚举的属性。因此我也建议不要使用For in。

关于switch语句的只有一件事,JavaScript改进了switch语句,即switch值不须要是一个数字 它能够是一个字符串。

JavaScript中有异常处理,这很好。在ES3以前咱们没有,这意味着你必需要写永远不会出错的程序,由于没有办法恢复。因此咱们如今有异常,你能够throw任何价值。

异常处理很是简单,只有一个捕获块,它能够捕获一切,但它并不关心发生了什么


好啦~~~下一章是函数~ 这篇文章还有些想加的东西,我慢慢加~

相关文章
相关标签/搜索