JavaScript (标准对象篇)
\(update : 2022.1.31\)
学习原文
\(① : 标准对象\)
在 JavaScript 的世界里 , 一切都是对象.
一般我们用 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'
注意 null 的类型是 object , Array 的类型也是 object , {} 也是 object , 你用 typeof 是区分不来的.
包装对象 (没搞懂存在的意义)
number , boolean , string 都有包装对象 , 包装对象用 new 创建.
虽然包装对象看上去和原来的值一模一样 , 但他们的类型已经变成了 object 了.
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'
new String('str') === 'str'; // false
所以不要用包装对象 (所以这玩意存在的意义在哪)
如果不用 new 的话 , Number() , Boolean() , String() 被当成普通函数.
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()方法;
通常不必把任意类型转换为boolean再判断,因为可以直接写if (myVar) {...};
typeof操作符可以判断出number、boolean、string、function和undefined;
判断Array要使用Array.isArray(arr)
判断 null 请使用 myVar === null
判断某个全局变量是否存在用typeof window.myVar === 'undefined';
函数内部判断某个变量是否存在用typeof myVar === 'undefined'
\(② : Date\)
觉得会调用即可.
var date = new Date();//Tue Feb 01 2022 11:26:54 GMT+0800 (中国标准时间)
date.getFullYear();2022 , 年份.
date.getMonth();//1 , 注意月份的范围是 0~11.
date.getDate();1 , 表示1号.
date.getDay(); 2 , 表示星期二.
date.getHours();11 , 二十四小时制.
date.getMinutes();26,分钟.
date.getSeconds();54,秒.
date.getTime(); 时间戳.
创建一个指定的Date
var d = new Date(2015,5,19,20,15,30,123);
d//Fri Jun 19 2015 20:15:30 GMT+0800 (CST)
注意这里的 5 对应 6 月 , 并且参数不输入完也行.
第二种方法是解析一个符合ISO 8601格式的字符串.
var d = Date.parse('2015-06-24T19:49:22.875+08:00');
d; // 1435146562875 , 返回的 d 是时间戳.
//不能直接调用 //d.getMonth(); //d.getMonth is not a function.
var t = new Date(d);
t.getMonth(); //5 , 显示的数字为 5 , 对应的月份为 6.
时区转换
var d = new Date(1435146562875);
d.toLocaleString(); // '2015/6/24 下午7:49:22',本地时间(北京时区+8:00),显示的字符串与操作系统设定的格式有关
d.toUTCString(); // 'Wed, 24 Jun 2015 11:49:22 GMT',UTC时间,与本地时间相差8小时
\(③ : RegExp\)
主要讲述正则表达式 , 一种用字符匹配字符的规则.
首先能给出准确的字符就是精准匹配 , 例如 <> @ 等等 , 有的字符需要转义 , 例如 \.
\d 匹配一个数字 , \w 匹配一个字母 , \s匹配一个空格.
'00\d' 可以匹配 007 , 但无法匹配 00A ;
'\d\d\d' 可以匹配 010 ;
'\w\w' 可以匹配 'js' ;
. 号能匹配任意字符 , 'js.'能匹配jsp , js! (与转义的 \. 区别)
同时 * 表示任意个字符(包括 0 个) , + 表示至少一个字符 , ?表示 0 个或 1 个字符 , 用 {n} 表示 n 个字符 , {n,m}表示 n-m 个字符
例子 \d{3}\s+\d{3,8}.
\d{3} 表示匹配 3 个数字 , 例如'010'.
\s+ 表示起码一个空格.
\d{3,8}表示3-8个数字.
如果要匹配'010-12345' , '-'是特殊字符需要转义.
所以上面的正则是 \d{3}\-\d{3,8}.
进阶
做到更加精准的匹配 , 可以用 [] 表示范围.
[0-9a-zA-Z\_] 可以匹配一个数字 , 字母或者下划线 (注意是一个)
当然可以和 + 号 , * 号配合 [0-9a-zA-Z\_]+ (至少有一个 , 如'a100','0_Z','js2015') , [0-9a-zA-Z\_](数量任意).
可以玩组合 : [a-zA-Z\_\$][0-9a-zA-Z\_\$]{0, 19} (前面一个字符 + 后面最多19个字符).
A|B 可以匹配 A 或 B .
(J|j)ava(S|s)cript 就可以匹配四种组合.
^ 表示行的开头 , ^\d表示必须以数字开头.
$ 表示行的结束 , \d$表示必须以数字结束.
^js$ 就只能匹配 'js' 了.
在 JS 里面有两种方法创建一个正则表达式.
① :/正则表达式/ ; ② : new RegExp('正则表达式').
var re1 = /ABC\-001/;
var re2 = new RegExp('ABC\\-001');
var re = /^\d{3}\-\d{3,8}$/;
re.test('010-12345'); // true
re.test('010-1234x'); // false
re.test('010 12345'); // false
用 test 判断是否匹配.
切分字符串
正常 : 'a b c'.split(' '); // ['a', 'b', '', '', 'c'] (无法识别连续空格).
'a b c'.split(/\s+/); // ['a', 'b', 'c'] (配合正则表达式则 ok .)
分组
除了简单地判断是否匹配外 , 正则表达式还有提取子串的功能 , 用 () 表示要分的组.
var re = /^(\d{3})-(\d{3,8})$/;
re.exec('010-12345'); // ['010-12345', '010', '12345']
re.exec('010 12345'); // null
exec() 方法匹配成功后 , 会返回一个 Array ,第一个元素是匹配到的整个字符串 , 后面的字符串则表示子串.
exec() 匹配失败则返回 null.
贪婪匹配
正则匹配表示贪婪匹配 , 也就是匹配尽可能多的字符串 ;
var re = /^(\d+)(0*)$/;
re.exec('102300'); // ['102300', '102300', '']
加个 + 表示非贪婪匹配.
var re = /^(\d+?)(0*)$/;
re.exec('102300'); // ['102300', '1023', '00']
全局搜索
加个 g
var r1 = /test/g;
// 等价于:
var r2 = new RegExp('test', 'g');
作用是 exec() 进行多次匹配 , 更新lastIndex , 表示上次匹配的最后索引.
var s = 'JavaScript, VBScript, JScript and ECMAScript';
var re=/[a-zA-Z]+Script/g;
// 使用全局匹配:
re.exec(s); // ['JavaScript']
re.lastIndex; // 10
re.exec(s); // ['VBScript']
re.lastIndex; // 20
re.exec(s); // ['JScript']
re.lastIndex; // 29
re.exec(s); // ['ECMAScript']
re.lastIndex; // 44
re.exec(s); // null,直到结束仍没有匹配到
\(④ : JSON\)
暂且不知道这东西的具体用处.
作者描述 : "把任何JavaScript对象变成JSON,就是把这个对象序列化成一个JSON格式的字符串,才能够通过网络传递给其他计算机"
如果我们收到一个JSON格式的字符串,只需要把它反序列化成一个JavaScript对象,就可以在JavaScript中直接使用这个对象了.
序列化
把小明这个对象化为JSON的字符串.
'use strict';
var xiaoming = {
name: '小明',
age: 14,
gender: true,
height: 1.65,
grade: null,
'middle-school': '\"W3C\" Middle School',
skills: ['JavaScript', 'Java', 'Python', 'Lisp']
};
var s = JSON.stringify(xiaoming,null,' ');
console.log(s);
效果是 :
{
"name": "小明",
"age": 14,
"gender": true,
"height": 1.65,
"grade": null,
"middle-school": "\"W3C\" Middle School",
"skills": [
"JavaScript",
"Java",
"Python",
"Lisp"
]
}
第二个参数用于筛选对象的键值 , 可以传入Array
JSON.stringify(xiaoming, ['name', 'skills'], ' ');
效果 :
{
"name": "小明",
"skills": [
"JavaScript",
"Java",
"Python",
"Lisp"
]
}
第二维还可以放个函数 (貌似只能放在第二维)
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"
]
}
还可以给 xiaoming 定义一个 toJSON() 的方法 , 直接返回 JSON 应该序列化的数据.
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}'
反序列化.
拿到一个JSON格式的字符串,我们直接用JSON.parse()把它变成一个JavaScript对象:
JSON.parse('[1,2,3,true]'); // [1, 2, 3, true]
JSON.parse('{"name":"小明","age":14}'); // Object {name: '小明', age: 14}
JSON.parse()还可以接受一个函数.
var obj = JSON.parse('{"name":"小明","age":14}', function (key, value) {
if (key === 'name') {
return value + '同学';
}
return value;
});
console.log(JSON.stringify(obj)); // {name: '小明同学', age: 14}
注意 JSON 里面的字符串必须用双引号引用.