基本引用类型
一、Date
date api基本上是参考java来的。
console.log("startTime: "+ Date.now()); // 时间戳
let currentDate = new Date();
let currentTime = Date.now();
console.log(currentDate.getTime()==currentTime); // true
let date21 = new Date("May 23,2019");
let date22 = new Date(Date.parse("May 23,2019"));
console.log(date21.getTime()==date22.getTime());// true
let date41 = new Date(Date.UTC(2000,1));
let date42 = new Date(2000,1); // 跟本机时间有关 向后偏移8小时
console.log(date41.getMonth());// 1 时间是2月份
console.log(date42.getMonth());// 1 时间是2月份
console.log(date41.getTime());// 949363200000
console.log(date42.getTime());// 949334400000
let date = new Date(2023,10,10,1,2,3);
console.log(date.getMonth());// 10
console.log(date.getSeconds()); // 3
console.log(date.getMilliseconds());// 0
console.log(date.getUTCMilliseconds());// 0
console.log("endTime: "+ Date.now()); // 时间戳
let date = new Date(2023,10,10,1,2,3);
console.log(date.valueOf()); // 1699549323000
console.log(date.toString());// Fri Nov 10 2023 01:02:03 GMT+0800 (中国标准时间)
console.log(date.toLocaleString());// 2023/11/10 01:02:03
这里date.valueOf()返回的是毫秒时,所以操作符(> <)可以用来比较date的大小。
let date = new Date();
console.log(date.toUTCString());// 没有做时区偏移 Tue, 26 Sep 2023 00:35:57 GMT
二、RegExp
2.1 概述
类Perl的简洁语法来创建的,let expression = /pattern/flags;
pattern可以是字符串等,flags可以是多个标记。例如:let expression = /.at/gi; 表示所有以at结尾的三字符组合,忽略大小写。
g:global 查找全部字符串内容,而不是找到第一个就结束
i:不区分大小写
m:多行模式,查找到一行文本末尾会继续查找
y:粘附模式,表示只从lastIndex开始及以后的字符串
u:启动Unicode匹配
s:dotAll,表示元字符,匹配任何字符(包括\n或\r)
let pattern1 = /[bc]a/i;
let pattern2 = new RegExp("[bc]a","i");
let text = "bcaeeebafffcaggg";
let matches1 = pattern1.exec(text);
let matches2 = pattern2.exec(text);
console.log(matches1); // ca
console.log(matches2); // ca
let pattern3 = /[bc]a/gi;
let matches3 = pattern3.exec(text);
console.log(matches3[0]); // ca
console.log(matches3.lastIndex); // ca
console.log(matches3.index); // ca
let matches4 = pattern3.exec(text);
console.log(matches4.lastIndex); // ba
let matches5 = pattern3.exec(text);
console.log(matches5[0]); // ca
pattern加不加g是有区别的,含有g继续执行exec就是会在字符串中向前搜索下一个匹配项,不加g每次只会返回第一个匹配的信息。
2.2 RegExp的构造属性
这些属性是静态属性,会根据最后执行的正则表达式操作而变化。
let pattern = /(.)hort/g;
let text = "this has been a short summber";
if (pattern.test(text)) {
console.log(RegExp.input); // this has been a short summber
console.log(RegExp.leftContext);// this has been a
console.log(RegExp.rightContext);// summber
console.log(RegExp.lastMatch);// short
console.log(RegExp.lastParen);// s
}
let pattern2 = /(..)or(.)/g;
let text2 = "this has been a short summber";
if (pattern2.test(text2)) {
console.log(RegExp.$1); // sh
console.log(RegExp.$2);// t
}
这里的(..)和(.)就表示两个捕获组。在生产环境中不要使用这些静态属性,因为没有任何Web标准出处。
三、原始值包装类型
Number(number的包装类型)、 Boolean(boolean包装类型) 、String(string的包装类型)
let s1 = "some text";
let s2 = new String(s1);
console.log(typeof s1);// string
console.log(typeof s2);// object
console.log(s2 instanceof String);// true
console.log(s1 instanceof string); // ReferenceError: string is not defined
按理说,s1只是一个原始值(字符串值),不应该有方法能调用,但是这里它能调用,其实是做了String转换的,在第二行执行完后,这个对象就置null,消失了。
let a = 1000;
console.log(a.toFixed(2)); // 1000.00
console.log(a.toPrecision(1));// 1e+3
console.log(a.toPrecision(4));// 1000
console.log(a.toExponential(2));// 1.00e+3
console.log(Number.isInteger(a));// true
toExponential 科学计数法表示。toFixed表示返回几位小数。
let s = "a😊b";
console.log(s.length); // 4
console.log(s.charAt(0)); // a
console.log(s.charAt(1)); // ?
console.log(s.charAt(2));// ?
console.log(s.charAt(3));// b
console.log(s.charCodeAt(0)); // 97
console.log(s.charCodeAt(1)); // 55357
console.log(s.charCodeAt(2));// 56842
console.log(s.charCodeAt(3));// 98
console.log(s.codePointAt(0)); // 97
console.log(s.codePointAt(1)); // 128522
console.log(s.codePointAt(2));// 56842
console.log(s.codePointAt(3));// 98
console.log(String.fromCharCode(97,55357,56842,98)); // a😊b
console.log(String.fromCodePoint(97,128522,98));// a😊b
charAt 和 charCodeAt 表示的字符有一定的范围,超出范围就不行了。
这里的表情符号😊使用两个码元(charCode),组成一个代理对,可以用一个码点codePoint表示。
有些字符可以用一个BMP字符表示,也可以用一个代理对表示。
String的api
let s1 = "helloworld";
console.log(s1.concat("xxx","yyy","zzz")); // helloworldxxxyyyzzz
console.log(s1.slice(-3));// rld
console.log(s1.slice(3,-4));//low
console.log(s1.substr(-3));//rld
console.log(s1.substr(3,-4));// ""空串
console.log(s1.substring(-3));// helloworld
console.log(s1.substring(3,-4));//hel
console.log(s1.indexOf("o"));// 4
console.log(s1.lastIndexOf("o"));// 6
console.log(s1.startsWith("hel"));// true
console.log(s1.includes("hel"));// true
console.log(s1.endsWith("ld"));// true
console.log(s1.trim());// helloworld
console.log(s1.repeat(2)+"man");// helloworldhelloworldman
console.log(s1.padStart(2, "."));// helloworld
console.log(s1[Symbol.iterator]().next());// {value: 'h', done: false}
console.log(s1[Symbol.iterator]().next());// {value: 'h', done: false}
console.log(s1[Symbol.iterator]().next());// {value: 'h', done: false}
console.log([...s1]);//['h', 'e', 'l', 'l', 'o', 'w', 'o', 'r', 'l', 'd']
console.log(s1.toUpperCase());// HELLOWORLD
console.log(s1.toLowerCase());// helloworld
let text = "cat,bat,sat";
let pattern = /.at/;
let matches = text.match(pattern);
console.log(matches.index);// 0
console.log(matches[0]);// cat
console.log(matches[1]);// undefined
console.log(pattern.lastIndex);// 0
console.log(text.replace("at","ond"));// cond,bat,sat
console.log(text.replace(/(.at)/g,"word($1)"));// word(cat),word(bat),word(sat)
console.log(text.replace(/(.at)/g,"word($2)"));// word($2),word($2),word($2)
console.log(text.replace(/(.at)/g,"word($3)"));// word($3),word($3),word($3)
let s2 = "yellow";
console.log(s2.localeCompare("brick"));// 1
ps: 正则中的捕获组2,来自openAi的解释:
在正则表达式中,括号 ( ) 用来创建捕获组(capturing group)。捕获组允许你在匹配中提取和操作子字符串。
在正则表达式中,你可以使用多个捕获组,每个捕获组用括号 ( ) 定义。当你使用多个捕获组时,可以通过 $1、$2、$3 等来引用这些捕获组中匹配到的内容。
let text = "apple123,banana456,orange789";
let regex = /([a-zA-Z]+)(\d+)/g;
let matches = text.match(regex);
for (let i = 0; i < matches.length; i++) {
console.log(matches[i]); // 输出每个匹配的字符串
console.log(matches[i].replace(regex, "word($1)($2)")); // 使用捕获组替换
}
在这个例子中,正则表达式 ([a-zA-Z]+)(\d+) 包含两个捕获组。第一个捕获组 ([a-zA-Z]+) 匹配一个或多个字母,第二个捕获组 (\d+) 匹配一个或多个数字。
在 matches[i].replace(regex, "word($1)($2)") 中,$1 表示第一个捕获组(匹配字母),$2 表示第二个捕获组(匹配数字)。替换操作会将匹配到的字符串中的字母和数字分别用括号括起来,形成类似 "word(apple)(123)"、"word(banana)(456)"、"word(orange)(789)" 的结果。
四、单例内置对象
4.1、Global
在全局作用域中定义的变量和函数都会变成global的对象的属性。window对象实现为Global对象的代理。
let uri = "http://www.baidu.com/hha 90"
console.log(encodeURI(uri));// http://www.baidu.com/hha%2090
console.log(encodeURIComponent(uri));// http%3A%2F%2Fwww.baidu.com%2Fhha%2090
console.log(decodeURI(encodeURI(uri)));// http://www.baidu.com/hha 90
console.log(decodeURIComponent(encodeURIComponent(uri)));// http://www.baidu.com/hha 90
encodeURI不会编码属于URL组件的特殊字符,比如// : ?等,而encodeURIComponent编码所有遇到的非标准字符。
神奇的eval() 方法,就是一个完整的ECMAScript的解释器。
eval("console.log('aaaa')"); // aaaa
eval("function sayHi(){ console.log('bbb')};");
sayHi(); // bbb
eval("let msg = 'hello'");
console.log(msg);// Uncaught ReferenceError: msg is not defined
这里因为eval中定义的函数和变量都不会被提升,所以msg会报错。
4.2、Math对象
let values = [1,2,3];
console.log(Math.max(...values));// 3
console.log(Math.min(...values)); // 1
console.log(Math.ceil(25.1));// 26
console.log(Math.floor(25.9));// 25
console.log(Math.round(25.9));// 26
console.log(Math.fround(25.9));// 25.899999618530273
console.log(Math.floor(Math.random() *10) + 1); // 1
console.log(Math.pow(2,3)); // 8
fround: 返回数值最接近的单精度浮点值表示。
random: 返回的是0~1之间的值,包含0但不包含1。