在本片文章中,作者将向您讲述 JavaScript 中最鲜为人知的秘密。学习 js 的朋友可以参考下。
Javascript 是一种由 Netscape 的 LiveScript 发展而来的原型化继承的基于对象的动态类型的区分大小写的客户端脚本语言,主要目的是为了解决服务器端语言,比如 Perl,遗留的速度问题,为客户提供更流畅的浏览效果。
- alert(typeof null); //弹出 'object'
如下截图:
尽管 typeof 值显示是 "object",但 null 并不认为是一个对象实例。要知道,JavaScript 中的值都是对象实例,每个数值都是 Number 对象,每个对象都是 Object 对象。因为 null 是没有值的,所以,很明显,null 不是任何东西的实例。因此,下面的值等于 false。
- alert(null instanceof Object); //为 false
这儿我们的变量和函数都声明在全局作用域中。因为 this 指向当前作用域,在这个例子中就是 window。因此,该函数寻找 window.animal,也就是'dog'了。到目前为止,一切正常。然而,实际上,我们可以让函数运行在不同的作用域下,而忽视其本身的作用域。我们可以用一个内置的称为 call()的方法来实现作用域的冒充。 call()方法中的第一个参数可以冒充函数中的 this,因此,这里的 this.animal 实际上就是 myObj.animal,也就是'camel'了。后面的参数就作为普通参数传给函数体。 另外一个与之相关的是 apply()方法,其作用于 call()一样,不同之处在于,传递给函数的参数是以数组形式表示的,而不是独立的变量们。所以,上面的测试代码如果用 apply()表示就是: demo 页面中,点击第一个按钮的结果如下截图:点击第二个和第三个按钮的结果如下:7. 函数可以执行其本身 下面这个是很 OK 的: 这里的解析足够简单:声明一个函数,然后因为 () 解析立即执行它。你可能会奇怪为何要这么做(指直接屁股后面 () 调用),这看上去是有点自相矛盾的:函数包含的通常是我们想稍后执行的代码,而不是当下解析即执行的,否则,我们就没有必要把代码放在函数中。 另外一个执行函数自身 (self-executing functions (SEFs)) 的不错使用是为在延迟代码中使用绑定变量值,例如事件的回调 (callback),超时执行(timeouts) 和间隔执行 (intervals)。如下例子: Newbies 在论坛里总问这里 timeout 的弹出为什么是 goodbye 而不是 hello?答案就 timeout 中的回调函数直到其运行的时候才去赋值 someVar 变量的值。而那个时候,someVar 已经被 goodbye 重写了好长时间了。 SEFs 提供了一个解决此问题的方法。不是像上面一样含蓄地指定 timeout 回调,而是直接将 someVar 值以参数的形式传进去。效果显著,这意味着我们传入并孤立了 someVar 值,保护其无论后面是地震海啸还是女朋友发飙咆哮都不会改变。 风水轮流转,这次,这里的弹出就是 hello 了。这就是函数参数和外部变量的点差别了哈。 例如,最后一个按钮点击后的弹出如下:浏览器 8. FireFox 以 RGB 格式读与返回颜色而非 Hex 直到现在我都没有真正理解为何 Mozilla 会这样子。为了有个清晰的认识,看下面这个例子: 大部分浏览器弹出的结果是 ff9900,而 FireFox 的结果却是 rgb(255, 153, 0),RGB 的形式。经常,处理颜色的时候,我们需要花费不少代码将 RGB 颜色转为 Hex。 下面是上面代码在不同浏览器下的结果:其它杂七杂八 9. 0.1 + 0.2 !== 0.3 这个古怪的问题不只会出现在 JavaScript 中,这是计算机科学中一个普遍存在的问题,影响了很多的语言。标题等式输出的结果是 0.30000000000000004。 这是个被称为机器精度的问题。当 JavaScript 尝试执行(0.1 + 0.2) 这行代码的时候,会把值转换成它们喜欢的二进制口味。这就是问题的起源,0.1 实际上并不是 0.1,而是其二进制形式。从本质上将,当你写下这些值的时候,它们注定要失去精度。你可能只是希望得到个简单的两位小数,但你得到的(根据 Chris Pine 的注解)是二进制浮点计算。好比你想把一段应该翻译成中文简体,结果出来的却是繁体,其中还是有差异是不一样的。 一般处理与此相关的问题有两个做法: 转换成整数再计算,计算完毕再转换成希望的小数内容 调整你的逻辑,设定允许范围为不是指定结果。 例如,我们不应该下面这样: 而可以试试这样: 10. 未定义 (undefined) 可以被定义(defined) 我们以一个和风细雨的小古怪结束。听起来可能有点奇怪,undefined 并不是 JavaScript 中的保留字,尽管它有特殊的意义,并且是唯一的方法确定变量是否未定义。因此: 目前为止,一切看上去风平浪静,正常无比,但剧情总是很狗血: 这就是为什么 jQuery 源码中最外部的闭包函数要有个并没有传入的 undefined 参数,目的就是保护 undefined 不要被外部的些不良乘虚而入。
这儿,我们基于参数 word 动态创建了匹配验证。这段测试代码作用是不区分大小选的情况下选择 car 这个单词。眼睛一扫而过,测试英文句子中只有一个单词是 car,因此这里的演出仅一个单词。\b 是用来表示单词边界的。
这是一个简单的替换,一个字符串,一个星号。但是,如果我们希望在替换发生的时候有更多的控制,该怎么办呢?我们只希望替换 30 以下的数值,该怎么办呢?此时如果仅仅依靠正则表达式是鞭长莫及的。我们需要借助回调函数的东风对每个匹配进行处理。 当每个匹配完成的时候,JavaScript 应用回调函数,传递匹配内容给 match 参数。然后,根据回调函数里面的过滤规则,要么返回星号,要么返回匹配本身(无替换发生)。 如下截图:5. 正则表达式:不只是 match 和 replace 不少 javascript 工程师都是只通过 match 和 replace 和正则表达式打交道。但 JavaScript 所定义的正则表达式相关方法远不止这两个。 其中值得一提的是 test(),其工作方式类似 match(),但是返回值却不一样:test() 返回的是布尔型,用来验证是否匹配,执行速度高于 match()。 上面行代码用来验证字符串是否有三个以上普通字符,显然 "hello" 是符合要求的,所以弹出 true。 结果如下截图:
结果如下截图 (win7 FF4):
结果如下截图,连续弹出两个框框:
结果如下截图:
结果如下截图:
译者注:null 还有被理解为对象占位符一说 NaN 本意是表示某个值不是数值,但是其本身却又是数值,且不等于其自身,很奇怪吧,看下面的代码: 结果如下截图:
来源: http://www.phperz.com/article/17/0405/282753.html