数据类型和定义javascript
JavaScript众多类型中有个Null类型,它有个惟一的值null, 即它的字面量,定义为彻底没有任何意义的值。其表现得像个对象,以下检测代码:java
以下截图:正则表达式
尽管typeof值显示是"object",但null并不认为是一个对象实例。要知道,JavaScript中的值都是对象实例,每一个数值都 是Number对象,每一个对象都是Object对象。由于null是没有值的,因此,很明显,null不是任何东西的实例。所以,下面的值等于 false。数组
译者注:null还有被理解为对象占位符一说浏览器
NaN本意是表示某个值不是数值,可是其自己却又是数值,且不等于其自身,很奇怪吧,看下面的代码:闭包
结果以下截图:app
实际上NaN不等于任何东西。要确认某玩意是否是NaN只能使用isNaN.函数
下面是JavaScript另外一个极品怪癖:测试
结果以下截图:this
想要知道这里发生了什么,你须要理解truthy和falsy这个概念。它们是一种true/flase字面量。在JavaScript中,所 有的非Boolean型值都会内置一个boolean标志,当这个值被要求有boolean行为的时候,这个内置布尔值就会出现,例如当你要跟 Boolean型值比对的时候。
由于苹果不能和梨作比较,因此当JavaScript两个不一样类型的值要求作比较的时候,它首先会将其弱化成相同的类型。false, undefined, null, 0, "", NaN都弱化成false。这种强制转化并非一直存在的,只有看成为表达式使用的时候。看下面这个简单的例子:
结果以下截图:
上面测试中,咱们试图将数值0和boolean值false作比较,因二者的数据类型不兼容,JavaScript自动强制转换成统一的等同的truthy和falsy,其中0等同于false(正如上面所说起的)。
你可能注意到了,上面一些等同false的值中并无空数组。只因空数组是个怪胚子:其自己实际上属于truthy,可是当空数组与Boolean型作比较的时候,其行为表现又属于falsy。不解?这是由缘由的。先举个例子验证下空数组的奇怪脾气:
结果以下截图,连续弹出两个框框:
译者注:之因此会有这种差别,根据做者的说法,数组内置toString()方法,例如直接alert的时候,会以join(“,”)的形式弹 出字符串,空数组天然就是空字符串,因而等同false。具体可参见做者另一篇文章,《Twisted logic: understanding truthy & falsy》。不过我我的奇怪的是,像空对象,空函数,弱等于true或者false的时候都显示false,为什么?真的由于数组是个怪胎,须要特殊考虑 吗?
为避免强制转换在比较方面的问题,你可使用强等于(===)代替弱等于(==)。
结果以下截图(win7 FF4):
若是你想深刻探究JavaScript中类型强制转换等些特有的癖好,能够参见官方相关的文档规范:section 11.9.3 of the ECMA-262
这是JavaScript最不为人知的秘密之一,v1.3中首次引入。大部分状况下,replace()的使用相似下面:
这是一个简单的替换,一个字符串,一个星号。可是,若是咱们但愿在替换发生的时候有更多的控制,该怎么办呢?咱们只但愿替换30如下的数值,该怎么办呢?此时若是仅仅依靠正则表达式是鞭长莫及的。咱们须要借助回调函数的东风对每一个匹配进行处理。
当每一个匹配完成的时候,JavaScript应用回调函数,传递匹配内容给match参数。而后,根据回调函数里面的过滤规则,要么返回星号,要么返回匹配自己(无替换发生)。
以下截图:
很多javascript工程师都是只经过match和replace和正则表达式打交道。但JavaScript所定义的正则表达式相关方法远不止这两个。
其中值得一提的是test(),其工做方式相似match(),可是返回值却不同:test()返回的是布尔型,用来验证是否匹配,执行速度高于match()。
上面行代码用来验证字符串是否有三个以上普通字符,显然"hello"是符合要求的,因此弹出true。
结果以下截图:
咱们还应注意RegExp对象,你能够用此建立动态正则表达式对象,例如:
这儿,咱们基于参数word动态建立了匹配验证。这段测试代码做用是不区分大小选的状况下选择car这个单词。眼睛一扫而过,测试英文句子中只有一个单词是car,所以这里的演出仅一个单词。\b是用来表示单词边界的。
结果以下截图:
做用域这玩意是用来决定什么变量是可用的,独立的JavaScript(如JavaScript不是运行中函数中)在window对象的全局做用域下操做,window对象在任何状况下均可以访问。然而函数中声明的局部变量只能在该函数中使用。
这儿咱们的变量和函数都声明在全局做用域中。由于this指向当前做用域,在这个例子中就是window。所以,该函数寻找 window.animal,也就是'dog'了。到目前为止,一切正常。然而,实际上,咱们可让函数运行在不一样的做用域下,而忽视其自己的做用域。我 们能够用一个内置的称为call()的方法来实现做用域的冒充。
call()方法中的第一个参数能够冒充函数中的this,所以,这里的this.animal实际上就是myObj.animal,也就是'camel'了。后面的参数就做为普通参数传给函数体。
另一个与之相关的是apply()方法,其做用于call()同样,不一样之处在于,传递给函数的参数是以数组形式表示的,而不是独立的变量们。因此,上面的测试代码若是用apply()表示就是:
demo页面中,点击第一个按钮的结果以下截图:
点击第二个和第三个按钮的结果以下:
下面这个是很OK的:
这里的解析足够简单:声明一个函数,而后由于()解析当即执行它。你可能会奇怪为什么要这么作(指直接屁股后面()调用),这看上去是有点自相矛盾的:函数包含的一般是咱们想稍后执行的代码,而不是当下解析即执行的,不然,咱们就没有必要把代码放在函数中。
另一个执行函数自身(self-executing functions (SEFs))的不错使用是为在延迟代码中使用绑定变量值,例如事件的回调(callback),超时执行(timeouts)和间隔执行(intervals)。以下例子:
Newbies在论坛里总问这里timeout的弹出为何是goodbye而不是hello?答案就timeout中的回调函数直到其运行的时候才去赋值someVar变量的值。而那个时候,someVar已经被goodbye重写了好长时间了。
SEFs提供了一个解决此问题的方法。不是像上面同样含蓄地指定timeout回调,而是直接将someVar值以参数的形式传进去。效果显著,这意味着咱们传入并孤立了someVar值,保护其不管后面是地震海啸仍是女友发飙咆哮都不会改变。
风水轮流转,此次,这里的弹出就是hello了。这就是函数参数和外部变量的点差异了哈。
例如,最后一个按钮点击后的弹出以下:
直到如今我都没有真正理解为什么Mozilla会这样子。为了有个清晰的认识,看下面这个例子:
大部分浏览器弹出的结果是ff9900,而FireFox的结果倒是rgb(255, 153, 0),RGB的形式。常常,处理颜色的时候,咱们须要花费很多代码将RGB颜色转为Hex。
下面是上面代码在不一样浏览器下的结果:
这个古怪的问题不仅会出如今JavaScript中,这是计算机科学中一个广泛存在的问题,影响了不少的语言。标题等式输出的结果是0.30000000000000004。
这是个被称为机器精度的问题。当JavaScript尝试执行(0.1 + 0.2)这行代码的时候,会把值转换成它们喜欢的二进制口味。这就是问题的起源,0.1实际上并非0.1,而是其二进制形式。从本质上将,当你写下这些 值的时候,它们注定要失去精度。你可能只是但愿获得个简单的两位小数,但你获得的(根据Chris Pine的注解)是二进制浮点计算。比如你想把一段应该翻译成中文简体,结果出来的倒是繁体,其中仍是有差别是不同的。
通常处理与此相关的问题有两个作法:
例如,咱们不该该下面这样:
而能够试试这样:
咱们以一个和风细雨的小古怪结束。听起来可能有点奇怪,undefined并非JavaScript中的保留字,尽管它有特殊的意义,而且是惟一的方法肯定变量是否未定义。所以:
目前为止,一切看上去风平浪静,正常无比,但剧情老是很狗血:
这就是为何jQuery源码中最外部的闭包函数要有个并无传入的undefined参数,目的就是保护undefined不要被外部的些不良乘虚而入。