JavaScript全面学习(中阶)
1.typeof
操作符总是返回一个字符串:
typeof 123; // 'number' typeof NaN; // 'number' typeof 'str'; // 'string' typeof true; // 'boolean' typeof undefined; // 'undefined' typeof Math.abs; // 'function' typeof null; // 'object' typeof []; // 'object' typeof {}; // 'object' 用typeof
无法区分出null
、Array
和通常意义上的object——{}
2.包装对象:
var n = new Number(123); // 123,生成了新的包装类型 var b = new Boolean(true); // true,生成了新的包装类型 var s = new String('str'); // 'str',生成了新的包装类型 typeof new Number(123); // 'object' new Number(123) === 123; // false typeof new Boolean(true); // 'object' new Boolean(true) === true; // false typeof new String('str'); // 'object' 包装使他们的类型变成了object new String('str') === 'str'; // false 所以对于string
类型,最好不要包装对象。
正确的转换法是不用new
var n = Number('123'); // 123,相当于parseInt()或parseFloat() typeof n; // 'number' var b = Boolean('true'); // true typeof b; // 'boolean' var b2 = Boolean('false'); // true! 'false'字符串转换结果为true!因为它是非空字符串! var b3 = Boolean(''); // false var s = String(123.45); // '123.45' typeof s; // 'string'
总结一下,有这么几条规则需要遵守:
-
不要使用
new Number()
、new Boolean()
、new String()
创建包装对象; -
用
parseInt()
或parseFloat()
来转换任意类型到number
; -
用
String()
来转换任意类型到string
,或者直接调用某个对象的toString()
方法; -
null
和undefined
没有toString()
方法。数字对象的toString()
方法要这样写:123.toString(); // SyntaxError 123..toString(); // '123', 注意是两个点! (123).toString(); // '123' 3.14.toString(); // '3.14' 3.14..toString(); // SyntaxError (3.14).toString(); //'3.14' // 第一个点是指小数点,第二个点才是调用toString()方法,所以3.14不需要用两个点调用toString()方法
-
通常不必把任意类型转换为
boolean
再判断,因为可以直接写if (myVar) {...}
; -
typeof
操作符可以判断出number
、boolean
、string
、function
和undefined
; -
判断
Array
要使用Array.isArray(arr)
; -
判断
null
请使用myVar === null
; -
判断某个全局变量是否存在,用
typeof window.myVar === 'undefined'
; -
函数内部判断某个变量是否存在,用
typeof myVar === 'undefined'
。
3.Date对象,获取本机系统当前时间:
var now = new Date(); now; // Wed Jun 24 2015 19:49:22 GMT+0800 (CST) now.getFullYear(); // 2015, 年份 now.getMonth(); // 5, 月份,注意月份范围是0~11,5表示六月 now.getDate(); // 24, 表示24号 now.getDay(); // 3, 表示星期三 now.getHours(); // 19, 24小时制 now.getMinutes(); // 49, 分钟 now.getSeconds(); // 22, 秒 now.getMilliseconds(); // 875, 毫秒数 now.getTime(); // 1435146562875, 以number形式表示的时间戳
创建一个指定日期和时间的Date
对象:
var d = new Date(2015, 5, 19, 20, 15, 30, 123); d; // Fri Jun 19 2015 20:15:30 GMT+0800 (CST) //注意JavaScript的月份范围用整数表示是0~11,0表示一月,1表示二月…… //或者这样也能创建: var a = Date.parse('2015-06-24T19:49:22.875+08:00'); a; // 1435146562875 返回一个时间戳 //可以再如下转换: var c = new Date(1435146562875); c; // Wed Jun 24 2015 19:49:22 GMT+0800 (CST) c.toLocaleString(); // '2015/6/24 下午7:49:22',本地时间(北京时区+8:00),显示的字符串与操作系统设定的格式有关 c.toUTCString(); // 'Wed, 24 Jun 2015 11:49:22 GMT',UTC时间(世界标准时间),与本地时间相差8小时 科普:格林威治标准时间GMT
4.正则表达式,如果直接给出字符,就是精确匹配。用\d
可以匹配一个数字,\w
可以匹配一个字母或数字,用.
可以匹配任意字符
*
表示任意个字符(包括0个),用+
表示至少一个字符,用?
表示0个或1个字符,用{n}
表示n个字符,用{n,m}
表示n-m个字符
\s
可以匹配一个空格(也包括Tab(/t)等空白符)
例如:要匹配'010-12345'
这样的号码,由于'-'
是特殊字符,在正则表达式中,要用'\'
转义,所以正则是\d{3}\-\d{3,8}
还能可以用[]
表示范围 :[a-zA-Z\_\$][0-9a-zA-Z\_\$]*
可以匹配由字母或下划线、$开头,后接任意个由一个数字、字母或者下划线、$组成的字符串,也就是JavaScript允许的变量名;
A|B
可以匹配A或B,所以(J|j)ava(S|s)cript
可以匹配'JavaScript'
、'Javascript'
、'javaScript'
或者'javascript'
。
^
表示行的开头,^\d
表示必须以数字开头。
$
表示行的结束,\d$
表示必须以数字结束。
5.RegExp。正则表达式。
写正则表达式的两种方法:
var re1 = /ABC\-001/; var re2 = new RegExp('ABC\\-001'); //注意是两\\,转义 re1; // /ABC\-001/ re2; // /ABC\-001/
RegExp对象的test()
方法用于测试给定的字符串是否符合条件:
var re = /^\d{3}\-\d{3,8}$/; re.test('010-12345'); // true re.test('010-1234x'); // false re.test('010 12345'); // false
正则表达式切分字符串十分好用:
'a b c'.split(' '); // ['a', 'b', '', '', 'c'] 不用正则的话 'a b c'.split(/\s+/); // ['a', 'b', 'c'] 用正则,把空格忽略掉 'a,b, c d'.split(/[\s\,]+/); // ['a', 'b', 'c', 'd'] 把空格和,忽略掉 'a,b;; c d'.split(/[\s\,\;]+/); // ['a', 'b', 'c', 'd'] 把空格和,和;都忽略掉
用()
表示要提取的分组,再用exec()
方法提取出子串:
var re = /^(\d{3})-(\d{3,8})$/; // 这里不再需要\-
re.exec('010-12345'); // ['010-12345', '010', '12345']
re.exec('010 12345'); // null 匹配失败返回null
贪婪匹配,匹配尽可能多的字符:
var re = /^(\d+)(0*)$/; re.exec('102300'); // ['102300', '102300', ''] \d+把数字全部匹配了,所以0*无法匹配到0
非贪婪匹配,也就是尽可能少匹配:
var re = /^(\d+?)(0*)$/; // 想要的非贪婪项后面加?号 re.exec('102300'); // ['102300', '1023', '00']
特殊的标志:g标志
,表示全局匹配。全局匹配类似搜索,因此不能使用/^...$/
,那样只会最多匹配一次。
i
标志,表示忽略大小写。m
标志,表示执行多行匹配。
var r1 = /test/g; // 等价于: var r2 = new RegExp('test', 'g');
var s = 'JavaScript,VBScript,JScript and ECMAScript'; var re=/[a-zA-Z]+Script/g; // 使用全局匹配: re.exec(s); // ['JavaScript'] 每次返回一个元素,与直接用exec,全部值一起返回不同。 re.lastIndex; // 10 最后所在的位置 re.exec(s); // ['VBScript'] re.lastIndex; // 19 re.exec(s); // ['JScript'] re.lastIndex; // 27 re.exec(s); // ['ECMAScript'] re.lastIndex; // 42 re.exec(s); // null,表示匹配结束了,全部符合条件的都已经找出来了,再调用就从第一个开始循环。
6.在JSON中,一共就这么几种数据类型:
- number:和JavaScript的
number
完全一致; - boolean:就是JavaScript的
true
或false
; - string:就是JavaScript的
string
; - null:就是JavaScript的
null
; - array:就是JavaScript的
Array
表示方式——[]
; - object:就是JavaScript的
{ ... }
表示方式。
JSON的字符串规定必须用双引号""
,Object的键也必须用双引号""
把对象序列化成JSON格式的字符串:
var xiaoming = { name: '小明', age: 14, gender: true, height: 1.65, grade: null, 'middle-school': '\"W3C\" Middle School', skills: ['JavaScript', 'Java', 'Python', 'Lisp'] }; JSON.stringify(xiaoming); // '{"name":"小明","age":14,"gender":true,"height":1.65,"grade":null,"middle-school":"\"W3C\" Middle School","skills":["JavaScript","Java","Python","Lisp"]}'
按缩进输出:
JSON.stringify(xiaoming, null, ' '); /*结果如下
{ "name": "小明", "age": 14, "gender": true, "height": 1.65, "grade": null, "middle-school": "\"W3C\" Middle School", "skills": [ "JavaScript", "Java", "Python", "Lisp" ] }
*/
指定属性输出:
JSON.stringify(xiaoming, ['name', 'skills'], ' '); /*结果如下 { "name": "小明", "skills": [ "JavaScript", "Java", "Python", "Lisp" ] } */
或者用toJSON()
的方法指定属性序列化输出:
var xiaoming = { name: '小明', age: 14, gender: true, height: 1.65, grade: null, 'middle-school': '\"W3C\" Middle School', skills: ['JavaScript', 'Java', 'Python', 'Lisp'], toJSON: function () { return { // 只输出name和age,并且改变了key: 'Name': this.name, 'Age': this.age }; } }; JSON.stringify(xiaoming); // '{"Name":"小明","Age":14}'
还可以传入一个函数作为参数:
function convert(key, value) { if (typeof value === 'string') { return value.toUpperCase(); } return value; } JSON.stringify(xiaoming, convert, ' '); /*结果如下,全部字符串变大写 { "name": "小明", "age": 14, "gender": true, "height": 1.65, "grade": null, "middle-school": "\"W3C\" MIDDLE SCHOOL", "skills": [ "JAVASCRIPT", "JAVA", "PYTHON", "LISP" ] } */
7.反序列化,把JSON格式的字符串还原成JavaScript对象:
JSON.parse('[1,2,3,true]'); // [1, 2, 3, true] JSON.parse('{"name":"小明","age":14}'); // Object {name: '小明', age: 14} JSON.parse('true'); // true JSON.parse('123.45'); // 123.45
JSON.parse()
还可以接收一个函数,用来转换解析出的属性
JSON.parse('{"name":"小明","age":14}', function (key, value) { // 把number * 2: if (key === 'name') { return value + '同学'; } return value; }); // Object {name: '小明同学', age: 14}