JavaScript数据类型中易被忽略的点
2016-07-24 本文已影响171人
7091a52ac9e5
String
- 字符串中可以包含由反斜杠
\
和字符构成的特殊字符,如\n
换行,\b
退格,\f
换页,\r
回车,\t
Tab;
var multiLine = " first \n second \n third line "
alert(multiLine) // alerts 3 lines
- ""当做转义符号也可以避免一些问题,如
var str = 'I\'m the Valrus'
- 当计算字符串长度时,特殊字符也会参与计算,如:
var str = "My\n" // 3 .`\n`也算其中之一
alert(str.length) // 3
- javascript中的字符串只能读取不能改变;
- javascript中有两种查找子字符串的方法,
indexOf
和lastIndexOf
,返回找到的第一个字符的位置,没找到返回-1; - 逐位运算符
~
not,~n相当于 -(n+1),if ~indexOf
相当于if found
; - 取得子字符串的三种方法
substr, substring, slice
,可以Google找到它们之间的差异,也可以从后文链接中找到; - 字符串的笔记
- 字符串逐位比较,一旦比较出大小就不再往后比较;
"Bob" > "Bar" // true, because o > a
,alert("2" > "14"); // true
- 字符装换为ASCII码比较
- 当有数值参与比较时,会把字符串也转换为数值,如
alert(2 > "14"); // false
Number, Math
- JavaScript中的数值采用双精度(IEEE 754),每个数占8byte;
- JavaScript可以识别十六进制(0xFF),八进制(010)以及科学计数方法的数字(3e5);
-
Infinity
和-Infinity
是两个特殊的值,它们大于或小于任何值,对它们进行运算后依旧会得到Infinity
,二者相除会得到NaN,并不会报错; - 当一个数学运算符不能被正确执行时会得到NaN(
0/0
),它不等于包括其本身的任何数值,只可有isNaN
函数检查; - 除了双向的加号,其它所有的运算符都会把数值形式的字符串转换为数值;
alert( -"12.34" / "2" ) // -6.17
; - 不能转换则返回
NaN
; - 一个由空白符组成的字符串会被转化为0;
- 如果字符串首字母非数字,
parseInt/parseFloat
会返回NaN
,alert( parseInt('a123') )//NaN
; - JavaScript中的数值计算存在精度问题(
alert(0.1 + 0.2 == 0.3)//false
)(浮点数不能被二进制精确的表示),解决方法可以先转化为整数,再除以10alert( (0.1*10 + 0.2*10) / 10 ) // 0.3
,也可以使用toFixed
;
Array
-
shift
,pop
删除对应项,并返回该项; -
unshift
,push
; -
join
,split
; - 如果给数组的length赋值低于数组实际的长度,会删除超过的项;
-
push
,pop
直接操作最后一项,其运行速度快,效率高; -
shift
,unshift
操作第一项,需要记住整个数组,效率低; - 数组中的length方法(属性) 其实是last index+1,
var fruits = [] // empty array fruits[1] = 'Peach' fruits[99] = 'Apple' alert(fruits.length) // 100 (but 2 elements)
- 对数组也可以使用
delete
,但是只会删除该项的值,不会真的删除该项; -
splice
在原数组上更改和slice
返回原数组的一个片段(新数组); -
sort
默认把内容转化为string,然后根据ASCII码比较; -
new Array
返回的是具有指定长度的值为空的数组;
Objects
-
obj.prop
和obj[prop]
二者都可以访问对象中的一项,但是值得注意的是obj.prop里prop是该项的名称,obj[prop]里的prop是该项的值,此时prop是字符串,应该加引号; -
alert("key" in obj) // true, key exists
使用in
运算符可以用来确定是否存在某一项; - 使用
for in
时,子项处理顺序不确定,不同浏览器有所差别; - 对象中可以储存一切类型,包括函数;
- 可以利用对象实现链式调用,其关键在于每次的返回值为this;
var ladder = {
step: 0,
up: function() {
this.step++
return this
},
down: function() {
this.step--
return this
},
showStep: function() {
alert(this.step)
return this
}
}
ladder.up().up().down().up().down().showStep() // 1
- 使用构造函数创建对象时,
var animal = new Animal()
和var animal = new Animal
等同; - 使用构造函数创建对象时,其关键在于this,如果构造函数返回了一个对象则会忽略this;
- JS中存在
Math
,Date
,RegExp
三种内置对象,函数从某种程度上来说也是对象,String,Number,Booleans三者比较特殊,它们各自拥有一些方法;
对象转换为简单数据类型
转化为字符串
- 如果对象中存在toString方法,且返回一个简单类型数据,那么就返回这个字符串(所有数组默认拥有,所以一般执行到此完毕);
- 默认
alert( {key: 'value'} ) // toString for Objects outputs: [object Object]
alert( [1,2] ) // toString for Arrays lists elements "1,2"
alert( new Date ) // toString for Dates outputs the date as a string
- 可以自己定义一个toString方法
var user = {
firstName: 'John',
toString: function() {
return 'User ' + this.firstName
}
}
alert( user ) // User John
- 如果存在valueOf方法,且返回一个简单类型数据,那么返回这个;
- alert()会触发装换为字符串
转换为数值(两种情况下发生,非常常见)
- 对数值进行计算的方法(
Math.sin(obj)
,isNaN(obj)
)以及运算符(+,-,*,/等等) - 做比较时(注:obj1==obj2,只有二者引用同一对象时才相等);
Number(obj)
也会转换, - 数值转换规则如下
- 如果存在valueOf方法,且返回一个简单类型数据,那么返回这个结果;
- 如果对象中存在toString方法,且返回一个简单类型数据,那么就返回这个字符串;
alert( new Date() ) // The date in human-readable form alert( +new Date() ) // Microseconds till 1 Jan 1970
- 自己定义一个valueOf方法
var room = { num: 777, valueOf: function() { return this.num } } alert( +room ) // 777
- 不存在valueOf方法,但是存在toString方法时会调用此方法
var room = { num: 777, toString: function() { return this.num } } alert( room / 3 ) // 259
- 注意只需要返回简单数值类型即可(
Numeric,String,Boolean
),不一定非要返回数值;
装换为布尔值
-
装换表
|Value | Converted to…|
|:------|:----------|
|true/false | no conversion|
|undefined, null | false|
|Number | 0, NaN become false, others - true.
|String | "" becomes false, any other - true|
|Object | true| -
注意,字符"0"为true;
-
涉及到逻辑运算符会触发布尔装换;
-
但是也有比较奇怪的地方,看下面两例
alert( [0] == 0 ) // true
alert( "\n0\n" == 0 ) // true
alert( "\n0\n" == false ) // true
//
if ([0]) alert(1) // 1, if treats [0] as true
if ("\n0\n") alert(2) // 2, if treats "\n0\n" as true
- 仔细想想如何转换的,就可以理解了。
==
只比较值得结果,[0],“0”装换为数值后就是0,但是当他们是数组中的一项,或字符串时并非是空的。
再看一个比较奇怪的例子
alert( [] == ![] ) // true
```分析一下这个例子有利于更加好的理解类型装换
- 首先,看右边![],逻辑非对[]进行布尔转换,依据上面的装换表,数组其实也是对象,object装换为真。所以右边![] = !true = false;
- 再看左边,对象与简单类型比较时,会按数值方式装换,没有valueOf,将使用toString进行装换(以逗号分隔的字符串)那么就装换为一个空的字符串''=false;
- 所以二者相等;
检测一下你是否真的掌握了数值装换,看看下面的题目能不能理解
```javascript
6 / "3" = 2
"2" * "3" = 6
4 + 5 + "px" = "9px"
"$" + 4 + 5 = "$45"
"4" - 2 = 2
"4px" - 2 = NaN
7 / 0 = Infinity
{}[0] = undefined
parseInt("09") = "0" or "9" // octal or decimal, depends on the browser
5 && 2 = 2
2 && 5 = 5
5 || 0 = 5
0 || 5 = 5
说明
本文对各类型并未做详尽的说明,想了解更多资料可以参考以下文章