数据类型和变量
数据类型
Number
123(正常数字)、NaN(不是数字)、Infinity(无限大)
16进制表示:0xff19
比较运算符
==
会自动转换数据类型再比较,会得到非常诡异的结果。
===
不会转换类型。先判断数据类型是否一致,一致的话再比较具体值。
特殊:
-
NaN===NaN;//false
唯一判断NaN的方法是通过isNaN()
isNaN(NaN);//true
- 浮点数由于精度的问题,比较不会相等。
1/3===(1-2/3);//false
应该用:Math.abs(1/3-(1-2/3))<0.000001;//true
null和undefined
null表示空值。0是一个数字。''是一个空字符串。
JavaScript的设计者希望用null表示一个空的值,而undefined表示值未定义。事实证明,这并没有什么卵用,区分两者的意义不大。大多数情况下,我们都应该用null。undefined仅仅在判断函数参数是否传递的情况下有用。
数组
创建方法:
[1,2,'abc']
new Array(1,2,3)
从可读性考虑,建议使用第一种方法来创建数组。
数组元素通过索引来访问:
var arr = [1,2,3];
console.log(arr[0]);
对象
JavaScript的对象是一组由键-值组成的无序集合。
var person = {
name: 'Bob',
age: 20,
tags: ['js', 'web', 'mobile'],
city: 'Beijing',
hasCar: true,
zipcode: null
};
变量
strict模式
JavaScript在设计之初,为了方便初学者学习,并不强制要求用var申明变量。这个设计错误带来了严重的后果:如果一个变量没有通过var申明就被使用,那么该变量就自动被申明为全局变量。
在同一个页面的不同的JavaScript文件中,如果都不用var申明,恰好都使用了变量i,将造成变量i互相影响,产生难以调试的错误结果。
使用var申明的变量则不是全局变量,它的范围被限制在该变量被申明的函数体内。
在strict模式下运行的JavaScript代码,强制通过var申明变量,未使用var申明变量就使用的,将导致运行错误。
启用strict模式的方法是在JavaScript代码的第一行写上:
'use strict';
字符串
转义:
\n
:换行
\\:\(两个反斜杠转义成一个斜杠)
ASCII字符可以用\x##
形式的十六进制表示:
\x41
:A
\u####
表示一个Unicode字符:
\u4e2d\u6587
:中文
es6新增换行字符串的表示:
var str = `你好
我是
一棵树`;
代码 | 含义 |
---|---|
s.length |
长度 |
s[2] |
区字符串某个字符,类似数组。索引越界不会报错,返回undefined |
注意:字符串是不可变的,如果对字符串的某个索引赋值,不会有任何错误,但是,也没有任何效果。
var s = 'Test';
s[0] = 'X';
alert(s); // s仍然为'Test'
代码(调用这些方法不会改变原来的字符串,而是返回一个新字符串) | 含义 |
---|---|
s.toUpperCase |
大写 |
s.toLowerCase |
小写 |
'hello,world'.indexOf('world') |
返回7(注意区分大小写) |
s.substring(0,10) |
返回字串,注意前包后不包。没有第二个参数代表到最后 |
数组
arr.length
来获取数组长度
注意:
- 直接给Array的length赋值会改变Array的大小。
var arr = [1, 2, 3];
arr.length; // 3
arr.length = 6;
arr; // arr变为[1, 2, 3, undefined, undefined, undefined]
arr.length = 2;arr; // arr变为[1, 2]
- 如果通过索引赋值时,索引超过了范围,同样会引起Array
大小的变化
var arr = [1, 2, 3];
arr[5] = 'x';
arr; // arr变为[1, 2, 3, undefined, undefined, 'x']
方法 | 含义 |
---|---|
arr.indexOf(10); |
ie8不兼容该方法,可以使用$.inArray(value,array) 代替。注意10和'10'不是一回事。 |
arr.slice(2,4) |
对应str.substring。如果没有参数相当于复制整个数组。var copy = arr.slice() |
arr.push(1,2) |
向数组中添加,返回数组新长度 |
arr.pop() |
返回并删除数组最后一个元素。空数组不会报错,而是返回undefined |
arr.unshift(1,2) |
类似push,从数组开头添加 |
arr.shift() |
返回并删除数组第一个元素 |
arr.sort() |
对数组进行排序 |
arr.reverse() |
对数组进行反转 |
splice |
从指定索引删除n个元素,然后再插入几个元素 |
arr1.concat(arr2); |
将两个数组进行拼接并返回新数组(并没有修改当前数组) |
arr.join('-') |
将数组的每一个元素用指定字符串连接,然后返回字符串。 |
`` | |
`` | |
`` | |
`` | |
`` |
splice
var arr = ['Microsoft', 'Apple', 'Yahoo', 'AOL', 'Excite', 'Oracle'];
// 从索引2开始删除3个元素,然后再添加两个元素:
arr.splice(2, 3, 'Google', 'Facebook'); // 返回删除的元素 ['Yahoo', 'AOL', 'Excite']
arr; // ['Microsoft', 'Apple', 'Google', 'Facebook', 'Oracle']
// 只删除,不添加:
arr.splice(2, 2); // ['Google', 'Facebook']
arr; // ['Microsoft', 'Apple', 'Oracle']
// 只添加,不删除:
arr.splice(2, 0, 'Google', 'Facebook'); // 返回[],因为没有删除任何元素
arr; // ['Microsoft', 'Apple', 'Google', 'Facebook', 'Oracle']
join
var arr = ['A', 'B', 'C', 1, 2, 3];
arr.join('-'); // 'A-B-C-1-2-3'
对象
var xiaoming = {
name: '小明',
birth: 1990,
school: 'No.1 Middle School',
height: 1.70,
weight: 65,
score: null
};
访问属性是通过.操作符完成的,但这要求属性名必须是一个有效的变量名。如果属性名包含特殊字符,就必须用''括起来:
var xiaohong = {
name: '小红',
'middle-school': 'No.1 Middle School'
};
xiaohong['middle-school'];
xiaohong.name;
代码 | 含义 |
---|---|
xiaohong.sex='男'; |
给对象添加属性 |
delete xiaohong.sex; |
删除对象的属性 |
'name' in xiaohong |
判断某个对象是否拥有某个属性(这个属性有可能是继承来的)。 |
xiaohong.hasOwnProperty('name') |
判断对象自身是否拥有某个属性 |
条件判断
if-else
注意:JavaScript把null、undefined、0、NaN、''
都视为false。
循环
for(;;)
for...in
(可以把一个对象的所有属性依次循环出来)
for...of
(for in和for of的差别就是,for in操作数组、字符串等取出来的是索引key,for of操作数组、字符串等取出来的是值value)
var o = {
name: 'Jack',
age: 20,
city: 'Beijing'
};
for (var key in o) {
if (o.hasOwnProperty(key)) {//过滤掉继承过来的属性
alert(key); // 'name', 'age', 'city'
}
}
由于Array也是对象,而它的每个元素的索引被视为对象的属性,因此,for ... in循环可以直接循环出Array的索引(这里得出来的索引是String而不是Number):
var a = ['A', 'B', 'C'];
for (var i in a) {
alert(i); // '0', '1', '2'
alert(a[i]); // 'A', 'B', 'C'
}
while
do...while
Map和Set
JavaScript的默认对象表示方式{}可以视为其他语言中的Map或Dictionary的数据结构,即一组键值对。
但是JavaScript的对象有个小问题,就是键必须是字符串。但实际上Number或者其他数据类型作为键也是非常合理的。
为了解决这个问题,最新的ES6规范引入了新的数据类型Map。
'use strict';
var m = new Map();
var s = new Set();
alert('你的浏览器支持Map和Set!');
iterable
遍历Array可以采用下标循环,遍历Map和Set就无法使用下标。为了统一集合类型,ES6标准引入了新的iterable类型,Array、Map和Set都属于iterable类型。
具有iterable类型的集合可以通过新的for ... of循环来遍历。
'use strict';
var a = [1, 2, 3];
for (var x of a) {
}
alert('你的浏览器支持for ... of');