前言 也就前天时间,突然企业QQ闪起来,在聊天窗口中出现这么一串js代码! [], ! ![], ! !![],这是表示什么意思呢?那么这就是今天要分享的背景了,我们复习一遍,感谢@阮一峰老师的整理。有点长,需要点耐心~~ 正文从这开始~ JavaScript是一种动态类型语言,变量是没有类型的,可以随时赋予任意值。但是,数据本身和各种运算是有类型的,因此运算时变量需要转换类型。大多数情况下,这种数据类型转换是自动的,但是有时也需要手动强制转换。 强制转换 强制转换主要指使用Number、String和Boolean三个构造函数,手动将各种类型的值,转换成数字、字符串或者布尔值。 Number函数:强制转换成数值 使用Number函数,可以将任意类型的值转化成数字。 (1)原始类型值的转换规则
Number函数将字符串转为数值,要比parseInt函数严格很多。基本上,只要有一个字符无法转成数值,整个字符串就会被转为NaN。 上面代码中,parseInt逐个解析字符,而Number函数整体转换字符串的类型。 Number函数会自动过滤一个字符串前导和后缀的空格。 (2)对象的转换规则 对象的转换规则比较复杂。
上面代码的valueOf方法返回对象本身({a:1}),所以对toString方法的返回值“[object Object]”使用Number方法,得到NaN。 如果toString方法返回的不是原始类型的值,结果就会报错。 上面代码的valueOf和toString方法,返回的都是对象,所以转成数值时会报错。 从上面的例子可以看出,valueOf和toString方法,都是可以自定义的。 上面代码对三个对象使用Number方法。第一个对象返回valueOf方法的值,第二个对象返回toString方法的值,第三个对象表示valueOf方法先于toString方法执行。 String函数:强制转换成字符串 使用String函数,可以将任意类型的值转化成字符串。规则如下: (1)原始类型值的转换规则
2)对象的转换规则 如果要将对象转为字符串,则是采用以下步骤。
String方法的这种过程正好与Number方法相反。
如果toString方法和valueOf方法,返回的都不是原始类型的值,则String方法报错。 下面是一个自定义toString方法的例子。 上面代码对三个对象使用String方法。第一个对象返回toString方法的值(数值3),然后对其使用String方法,得到字符串“3”;第二个对象返回的还是toString方法的值(”[object Object]”),这次直接就是字符串;第三个对象表示toString方法先于valueOf方法执行。 Boolean函数:强制转换成布尔值 使用Boolean函数,可以将任意类型的变量转为布尔值。 (1)原始类型值的转换方法 以下六个值的转化结果为false,其他的值全部为true。
(2)对象的转换规则 所有对象的布尔值都是true,甚至连false对应的布尔对象也是true。 请注意,空对象{}和空数组[]也会被转成true。 自动转换 当遇到以下几种情况,JavaScript会自动转换数据类型:
自动转换为布尔值 当JavaScript遇到预期为布尔值的地方(比如if语句的条件部分),就会将非布尔值的参数自动转换为布尔值。它的转换规则与上面的“强制转换成布尔值”的规则相同,也就是说,在预期为布尔值的地方,系统内部会自动调用Boolean方法。 因此除了以下六个值,其他都是自动转为true:
自动转换为字符串 当JavaScript遇到预期为字符串的地方,就会将非字符串的数据自动转为字符串,转换规则与“强制转换为字符串”相同。 字符串的自动转换,主要发生在加法运算时。当一个值为字符串,另一个值为非字符串,则后者转为字符串。 自动转换为数值 当JavaScript遇到预期为数值的地方,就会将参数值自动转换为数值,转换规则与“强制转换为数值”相同。 除了加法运算符有可能把运算子转为字符串,其他运算符都会把两侧的运算子自动转成数值。 上面都是二元算术运算符的例子,JavaScript的两个一元算术运算符正号和负号也会把运算子自动转为数值。 小结 由于自动转换有很大的不确定性,而且不易除错,建议在预期为布尔值、数值、字符串的地方,全部使用Boolean、Number和String方法进行显式转换。 加法运算符的类型转化 加法运算符( )需要特别讨论,因为它可以完成两种运算(加法和字符连接),所以不仅涉及到数据类型的转换,还涉及到确定运算类型。 三种情况 加法运算符的类型转换,可以分成三种情况讨论。 (1)运算子之中存在字符串 两个运算子之中,只要有一个是字符串,则另一个不管是什么类型,都会被自动转为字符串,然后执行字符串连接运算。前面的《自动转换为字符串》一节,已经举了很多例子。 (2)两个运算子都为数值或布尔值 这种情况下,执行加法运算,布尔值转为数值(true为1,false为0)。 (3)运算子之中存在对象 运算子之中存在对象(或者准确地说,存在非原始类型的值),则先调用该对象的valueOf方法。如果返回结果为原始类型的值,则运用上面两条规则;否则继续调用该对象的toString方法,对其返回值运用上面两条规则。
有趣的是,如果更换上面代码的运算次序,就会得到不同的值。
将{a:1}放置在括号之中,由于JavaScript引擎预期括号之中是一个值,所以不把它当作代码块处理,而是当作对象处理,所以最终结果为“[object Object]1”。
上面代码的toString方法返回一个空对象,JavaScript就会报错,表示无法获得原始类型的值。 四个特殊表达式 有了上面这些例子,我们再进一步来看四个特殊表达式。 (1)空数组 空数组
(2)空数组 空对象
(3)空对象 空数组 JavaScript引擎将空对象视为一个空的代码块,加以忽略。因此,整个表达式就变成“ []”,等于对空数组求正值,因此结果就是0。转化过程如下: 如果JavaScript不把前面的空对象视为代码块,则结果为字符串“[object Object]”。 (4)空对象 空对象 JavaScript同样将第一个空对象视为一个空代码块,整个表达式就变成“ {}”。这时,后一个空对象的ValueOf方法得到本身,再调用toSting方法,得到字符串“[object Object]”,然后再将这个字符串转成数值,得到NaN。所以,最后的结果就是NaN。转化过程如下: 如果,第一个空对象不被JavaScript视为空代码块,就会得到“[object Object][objectObject]”的结果。 需要指出的是,对于第三和第四种情况,Node.js的运行结果不同于浏览器环境。 可以看到,Node.js没有把第一个空对象视为代码块。原因是Node.js的命令行环境,内部执行机制大概是下面的样子:
后语 最后再来推荐这么一个链接:http://www.jsfuck.com/ 关于本文 作者:@阮一峰 原文链接:http://javascript.ruanyifeng.com/grammar/conversion.html 本文转载自:微信公众账号 - 前端早读课,版权归原作者所有! |
|
声明:文章版权归原作者所有 部分文章转自互联网 如有侵权请联系
[邮箱地址] 删除
|