javascript-chapter11 标准库
1.set class
set是值的集合,set是无序的,且不能重复。一个值可以是或不是集合的成员。
let s=new Set();//空集
let t=new Set([1,s]);//有两个元素的集合。
let t=new Set(s);//新集合,元素来自于s
let unique=new Set("Mississippi");//M i s p四个元素
unique.size//4
Set不用在使用前初始化,你可以利用add(),delete(),clear()方法操作他。
(1)add方法,add方法接收一个参数,如果你传递一个数组,它会把数组本身加入Set中,add()会返回调用的集合,如果需要添加多个元素,可使用
s.add('a').add('b').add('c');
(2)delete方法一次只能删除一个元素。delete()返回一个boolean值,删除成功返回true,其他情况返回false.
(3)set使用===判断元素是否相等。所以使用delete删除对象时会无法成功删除,因为他们指向不同的引用。
实践中最常见的操作是判断一个值是否属于集合,而不是添加或移除。使用has()方法。
let oneDigitPrimes=new Set([2,3,5,7])
oneDigitPrimes.has(2);//true
oneDigitPrimes.has(3);//true
oneDigitPrimes.has(4);//false
oneDigitPrimes.has("5");//false "5"是字符串。
Set的has方法比Array的includes方法要快速许多。
Set是可迭代的,可以使用for/of循环
let sum=0;
for(let p of oneDigitPrimes){
sum+=p;
}
Set可迭代,可以使用...操作符
[...oneDigitPrimes]//=>[2,3,5,7]
Math.max(...oneDigitPrimes)//=》7
Set可使用foreach
let product=1;
oneDigitPrimes.forEach(n=>{product*=n;});
product//210
11.1.2 Map Class
Map对象是键值对构成的。map可以用任意值作为索引。Map处理速度很快,但比数组的索引查询慢。
let m=new Map();//空Map
let n=new Map(["one",1],["two",2]);//两个元素,从字符串映射到整数。
let copy =new Map(n);//拷贝Map到copy
let o={ x:1,y:2};//拥有两个属性的对象
let p=new Map(Objefct.entries(o));//map([["x",1],["y",2]]);
构造了Map对象后,可以使用get()获得值,set()添加新的键值对。如果set了一个已经存在的键,Map他会更改键值对。
has()方法判断是否存在键,delete()移除一个键值对,clear()移除所有Map的键值对。size属性返回Map的键值对数量。
add()方法也可链式使用
let m=new Map().set("one",1).set("two",2).set("three",3);
m.size//3
m.get("two")//2
Map允许任何键值对,包括null,undefined ,NaN,数组,对象。
let m=new Map();//empty map
m.set({},1);//空对象指向1
m.set({},2);//另一个空对象指向2
m.size//2
m.get({});//undefined
m.set(m,undefined)//Map the mapself to undefined
m.has(m)//true
m.get(m);//undefined
Map对象时可迭代的。每个迭代值返回一个两个元素的数组,第一个元素是key,第二个元素是value
let m=new Map([["x",1],["y",2]]);
[...m]//["x",1],["y",2]
for(let [key,value] of m){
//第一次迭代["x",1]
//第二次迭代["y",2]
}
迭代顺序是插入顺序。如果只想获得键或者值可以使用
[...m.keys()] //["x","y"]
[...m.values()]//[1,2]
[...m.entries()]//same with [...m]
可以使用ForEach
m.forEach((value,key)=>{});
11.1.3 WeakMap和WeakSet
WeakMap 是一种键值对的集合,其中的键必须是对象或非全局注册的符号,且值可以是任意的 JavaScript 类型,并且不会创建对它的键的强引用。换句话说,一个对象作为 WeakMap 的键存在,不会阻止该对象被垃圾回收。一旦一个对象作为键被回收,那么在 WeakMap 中相应的值便成为了进行垃圾回收的候选对象,只要它们没有其他的引用存在。唯一可以作为 WeakMap 的键的原始类型是非全局注册的符号,因为非全局注册的符号是保证唯一的,并且不能被重新创建。
WeakMap 允许将数据与对象相关联,而不阻止键对象被垃圾回收,即使值引用了键。然而,WeakMap 并不允许观察其键的生命周期,这就是为什么它不允许枚举;如果 WeakMap 提供了任何获得其键的列表的方法,那么这些列表将会依赖于垃圾回收的状态,这引入了不确定性。如果你想要可以获取键的列表,你应该使用 Map 而不是 WeakMap
Map是强引用,在Map生命周期都可以访问。WeakMap是弱引用,键值有可能不能被访问。
WeakMap与Map的区别
1.WeakMap的键必须是对象或者数组,原始类型数据因为不会被垃圾回收所以不能被用于作为键。
2.WeakMap只可以使用get(),set(),has(),delete()。WeakMap不能迭代,不能使用keys(),values(),foreach()
3.WeakMap不能使用size属性。因为它随时可能被垃圾回收,size是可变的。
WeakSet
1.不能使用基本数据类型作为WeakSet的成员
2.WeakSet值实现了add(),has(),delete(),不可迭代
3.WeakSet没有size属性
11.2Typed Arrays
1.typed Array的元素全部是number
2.你必须申明数组长度
3.typed Array初始化时所有值为0
| 类型 | 值范围 | 字节大小 | 描述 | Web IDL 类型 | 等价的 C 类型 |
|---|---|---|---|---|---|
| Int8Array | -128 到 127 | 1 | 8 位有符号整型(补码) | byte | int8_t |
| Uint8Array | 0 到 255 | 1 | 8 位无符号整型 | octet | uint8_t |
| Uint8ClampedArray | 0 到 255 | 1 | 8 位无符号整型(一定在 0 到 255 之间) | octet | uint8_t |
| Int16Array | -32768 到 32767 | 2 | 16 位有符号整型(补码) | short | int16_t |
| Uint16Array | 0 到 65535 | 2 | 16 位无符号整型 | unsigned short | uint16_t |
| Int32Array | -2147483648 到 2147483647 | 4 | 32 位有符号整型(补码) | long | int32_t |
| Uint32Array | 0 到 4294967295 | 4 | 32 位无符号整型 | unsigned long | uint32_t |
| Float32Array | -3.4E38 到 3.4E38 并且 1.2E-38 是最小的正数 | 4 | 32 位 IEEE 浮点数(7 位有效数字,例如 1.234567) | unrestricted float | float |
| Float64Array | -1.8E308 到 1.8E308 并且 5E-324 是最小的正数 | 8 | 64 位 IEEE 浮点数(16 位有效数字,例如 1.23456789012345) | unrestricted double | double |
| BigInt64Array | -263 到 263 - 1 | 8 | 64 位有符号整型(补码) | bigint | int64_t (signed long long) |
| BigUint64Array | 0 到 264 - 1 | 8 | 64 位无符号整型 | bigint | uint64_t (unsigned long long) |
11.2.2 创建typed Array
let bytes=new Uint8Array(1024);
let matrix=new Float64Array(9);//3*3
let point=newInt6Array(3);//A point in 3D space
let rgba=Uint8ClampedArray(4);//4-byte RGBA pixel value
let sudoku=new Int8Array(81);//9>9 sudoku board
from() of()方法
let white=Uint8ClampedArray.of(255,255,255,0);
let ints=Uint32Array.from(white);
typed array是定长数组,push(),pop(),unshift(),shift(),splice()不能使用,因为他们改变长度。sort(),reverse() fill()可以使用,
map() slice()返回与原数组同类型的新数组。
TypedArray.prototype.set()
https://developer.mozilla.org/zh-CN/docs/Web/JavaScript/Reference/Global_Objects/TypedArray/set
var buffer = new ArrayBuffer(8);
var uint8 = new Uint8Array(buffer);
uint8.set([1, 2, 3], 3);
console.log(uint8); // Uint8Array [ 0, 0, 0, 1, 2, 3, 0, 0 ]
TypedArray.slice();
https://developer.mozilla.org/zh-CN/docs/Web/JavaScript/Reference/Global_Objects/TypedArray/slice
TypedArray.prototype.subarray()
TypedArray 实例的 subarray() 返回一个新的、基于相同 ArrayBuffer、元素类型也相同的类型化数组。开始的索引将会被包括,而结束的索引将不会被包括。
const uint8 = new Uint8Array([10, 20, 30, 40, 50]);
console.log(uint8.subarray(1, 3));
// Expected output: Uint8Array [20, 30]
console.log(uint8.subarray(1));
// Expected output: Uint8Array [20, 30, 40, 50]
slice()会返回一个新数组,subarray()和原数组同用一片内存空间。
11.2.5DataView
DataView 视图是一个可以从二进制 ArrayBuffer 对象中读写多种数值类型的底层接口,使用它时,不用考虑不同平台的字节序问题。
let bytes=new UintArray(1024);
let view =new DataView(bytes.buffer,bytes.byteOffset,bytes.byteLength);
let int =view.getInt32(0);//read big-endian
int =view.getInt32(4,false);//big endian
int =view.getUint32(8,true);//little-endian
view.setUint32(8,int,false);//write back in big-endian format
方法
https://developer.mozilla.org/zh-CN/docs/Web/JavaScript/Reference/Global_Objects/DataView
11.3.1正则表达式
正则表达式对象由regExp()创建。
let pattern=/s$/;
let pattern=new RegExp("s$);
11.3.2正则表达式的字符串方法
search()
"JavaScript".search(/script/ui)//4
"Python".search(/script/ui)//-1
replace()
带g的正则表达式会替换所有符合的字符串,不带g则只替换第一次匹配的字符串
text.replace(/javascript/gi,"JavaScript");
//不分大小写的替换所有javascript到JavaScript
match()
会返回匹配的数组。
如果正则表达式不带g,则只会匹配一次。返回的数组a[0]表示匹配的字符串,a[1]包含匹配成功的子串。
"7 plus 8 equals 15".match(/\d+/g)//["7","8","15"]
matchall()
会返回一个迭代器。
例
const words=/\b\p{}Alphabetic}+\b/gu;
const text="This is a naive test of the matchAll() method.";
for(let word of text.matchAll(words)){
console.log('Found '${word[0]}' at index ${word.index}.`);
}
split()以正则表达式分隔字符串
"123,456,789".split(",")//["123","456","789"]
"1,2,3,\n4,5".split(/\s*,\s*/)["1","2","3","4","5"]
11.3.3正则表达式类
构造函数接收两个参数,第一个为正则表达式,第二个为g,i,m,s,u,y正则表达式标志
let zipcode=new RegExp("\\d{5}","g");
属性
source 只读属性,返回正则表达式去除//的部分
flags 只读属性,标志位
global 布尔值,则表达式是否包含g标志位
ignoreCase 布尔值,正则表达式是否包含i位
multiline 布尔值,是否包含m位
dotAll 布尔值,是否包含s位
unicode 布尔值,是否包含u位
sticky 布尔值,是否包含y位
lastIndex 搜索位置,下一次搜索的开始位置
test()
如果正则表达式匹配返回true,否则返回false
exec()
接收一个字符串参数,看是否与正则表达式匹配。如果匹配返回数组,类似于match()方法。exec方法会修改lastIndex的值,可以反复调用exec()完成对整个字符串的遍历。
例:
let pattern=/Java/g
let text="JavaScript >Java";
let match;
while((match=pattern.exec(text))!=null){
console.log('Matched ${match[0]} at ${match.index}`);
console.log('Next search begins at ${pattern.lastIndex}`);
}
11.4 Dates Times类
let now =new Date();//current time
let epoch=new Date(0);//从1970年起的毫秒数 Midnight,January 1st,1970,GMT
let century=new Date(2100,//year 2100
0, //January
1, //1st
2,3,4,5);//02:03:04:005,local time;
注意,月份从0开始(0-11),天从1开始(1-31)
let century =new Date(Date.UTC(2100,0,1));
UTC协调世界时(英语:Coordinated Universal Time,法语:Temps Universel Coordonné,简称UTC)是最主要的世界时间标准,其以原子时的秒长为基础,在时刻上尽量接近于格林尼治标准时间。
如果打印当前时区的时间,使用
console.log(century);
打印UTC使用
toUTCString() toISOString()
传递字符串给Date(),它会试图用字符串转换为时间
let century=new Date("2100-01-01T00:00:00Z");//ISO format date
当你获得了Date对象,就可以调用其中的get set方法了。
let d=new Date();
d.setFullYear(d.getFullYear()+1);
getDay(),getUTCDay()会返回一周内的天数。0Sunday 6 Saturday。只读,没有setDay()方法。
11.4.1时间戳
使用int表示自1970年起的时间。
getTime()获得整数值,setTime()可以设置时间
d.setTime(d.getTime()+30000);
Date.now()返回时间戳。
计算运行函数的时间
let startTime=Date.now();
reticulateSplines();//要计算的函数
let endTime=Date.now();
console.log(${endTime-startTime});
11.4.2时间运算
Date对象可以进行< <= >=的对比。
改变时间,使用get set方法
let d=new Date();
d.setMonth(d.getMonth()+3,d.getDate()+14);//3 months two weeks
11.4.3 格式化和时间字符串转化
let d=new Date(2020,0,1,17,10,30);//5:10:30pm 1.1.2020
d.toString();//Wed Jan 01 2020 17:10:30 GMT-0800
d.toUTCString();//Thu 02 Jan 2020 01:10:30 GMT
d.toLocalDateString();//"1/1/2020":'en-US' locale
d.toLocaleTimeString();//"5:10:30 PM": 'en-US' locale
d.toISOString();//2020-01-02T01:10:30.000Z
转换使用
Date.Parse("str");
11.6JSON序列化
使用JSON.stringify()和JSON.parse();
JSON支持基本数据类型,字符串,true false null
let o={s:"",n:0,a:[true,false,null]};
let s=JSON.stringify(o);//s'{"s":"","n":0,"a":[true,false,null]}'
letcopy=JSON.parse(s);//copy;
function deepcopy(o){
return JSON.parse(JSON.stringify(o));
}
11.6.1 JSON定制
如果使用JSON.stringify()串行化一个不支持JSON的对象,它会寻找toJSON()方法。
例如Date对象实现了toJSON();会返回一个toISOString();
如果你需要重建Date对象,你要传递一个"reviver"函数作为JSON.parse()的第二个参数。这个函数会被调用,含两个参数,。第一个参数是属性名,即被转换的对象或者数组名。第二个参数是对象的属性或者数组元素。reviver函数的返回值是已命名属性的新值。
例:重建Date()对象
let data=JSON.parse(text,function(key,value){
if(key[0]==="_")return undefined;//remove any values whose property name begins with an underscore;
//if the value is a string in ISO 8601 date format conver it to a Date.
if(typepef value="string"&&/^\d\d\d\d-\d\d-\d\dT\d\d:\d\d:\d\d.\d\ddZ$/.test(value){
return new Date(value);
}
//Otherwise return the value unchanged
return value;
});
11.7 Internationalization API
INtl.NumberFormat,INtl.DateTimeFormat,Intl.Collator
1.Intl.NumberFormat
format()两个参数,第二个参数是对象,用于说明如何转换。
第二个参数
style "decimal" "percent" "currency"
currency 属性是三个字符的ISO货币编码
currencyDisplay 显示货币的样式 "symbol" "code" ISO code "name" 货币名
useGrouping 如果不希望有千位分隔符,设置为false
minimumIntegerDigits 数字的整数部分最小位数,小于该值会左填充0 默认值为1 最大值为21
minimumFractionDigits,maximumFractionDigits 分数部分 分数部分位数小于最小值,会右填充0,比最大值大,分数部分会四舍五入
两者的合法值是0 到20 默认值最小值为0 最大值为3
minimumSignificantDigits,maximumSignificantDigits
科学记数法。合法值为1到21
const number = 123456.789;
console.log(
new Intl.NumberFormat('de-DE', { style: 'currency', currency: 'EUR' }).format(
number,
),
);
// Expected output: "123.456,79 €"
// The Japanese yen doesn't use a minor unit
console.log(
new Intl.NumberFormat('ja-JP', { style: 'currency', currency: 'JPY' }).format(
number,
),
);
// Expected output: "¥123,457"
// Limit to three significant digits
console.log(
new Intl.NumberFormat('en-IN', { maximumSignificantDigits: 3 }).format(
number,
),
);
// Expected output: "1,23,000"
let euros=Intl.NumberFormat("es",{style:"currency",currency:"EUR"});
euros.format(10);//10,00€
11.7.2 格式化日期,时间
Intl.DateTimeFormat
year:
"numeric" 四位年份,"2-digit" 两位年份
month:
"numeric" 可以是一位 如 1 "2-digit"至少两位,不够补0."long"月份的全称。"short" 月份缩写如Jan" "narrow"更缩写如"j",不保证唯一性。
day:
"numeric" 可以是一位,"2-digit"至少两位。
weekday:
"long" 全称如"Monday" "short" 缩写,"Mon" "narrow"高度缩写,同上。
era:
"long" "short" "narrow" 日本年历使用
hour,minute,second
"numeric" "2-digit" 同上
timeZone 时区
不填写是默认本地时区。
timeZoneName
"long" "short" 同上
hour12
布尔值,是否使用12小时时间
hourCycle
午夜设置为几点。"h11"午夜为0,11点为11pm "h12"午夜为12点 "h23"午夜为0,11点为23 "h24" 午夜为24
const date = new Date(Date.UTC(2020, 11, 20, 3, 23, 16, 738));
// Results below assume UTC timezone - your results may vary
// Specify default date formatting for language (locale)
console.log(new Intl.DateTimeFormat('en-US').format(date));
// Expected output: "12/20/2020"
// Specify default date formatting for language with a fallback language (in this case Indonesian)
console.log(new Intl.DateTimeFormat(['ban', 'id']).format(date));
// Expected output: "20/12/2020"
// Specify date and time format using "style" options (i.e. full, long, medium, short)
console.log(
new Intl.DateTimeFormat('en-GB', {
dateStyle: 'full',
timeStyle: 'long',
timeZone: 'Australia/Sydney',
}).format(date),
);
// Expected output: "Sunday, 20 December 2020 at 14:23:16 GMT+11"
11.7.3比照字符串
Intl.Collator() 两个参数,第一个参数是locale或者locale数组。第二个参数为对象,其中的属性为
usage:"sort","search" 排序和搜索。
sensitivity:"base"忽略大小写和重音。"accent"考虑重音忽略大小写 "variant" 严格比较重音和大小写。
usage是"sort" 时值默认为"variant" usage是"search"时默认值取决于locale
ignorePunctuation:布尔值,true 忽视空格和标点符号
numeric:布尔值,true用数字大小顺序排列,传递的字符串中含数字。
caseFirst:"upper" "A"在"a"前,"lower" "a"在"A"前。
定义完Intl.Collator()后,就可以使用compare()方法了。
该方法返回负数,第一个字符串小于第二个字符串。正数,第一个大于第二个。0表示相等
例
//basic compare
const collator=new Intl.Collator().compare;
["a","z","A","Z"].sort(collator)//["a","A","z","Z"]
//Filenames contain number
const filenameOrder=new Intl.Collator(undefined,{numric:true}).compare;
["page10","page9"].sort(filenameOrder);//["page9","page10"]
//find all strings loosely match a target string
const fuzzMatcher=new Intl.Collator(undefined,{
sensitivity:"base",
ignorePunction:true
}).compare;
let string=["food","fool","Foo Bar"];
string.findIndex(s=>fuzzMatcher(s,"footbar"===0)//2
11.8控制台api
console.log();
cosole.debug(),console.info,console.warn(),console.error()
error会输出流到stderr stream其他几个函数和log函数没区别。
console.assert()
The console.assert() static method writes an error message to the console if the assertion is false. If the assertion is true, nothing happens.
console.clear()
清除consle
console.table()打印表格,适合参数是对象或者数组。
console.trace()
输出stack trace
console.count() 接收一个string参数,会记录string参数的打印次数。
console.countReset() 重置string的计数器。
console.group()
The console.group() static method creates a new inline group in the Web console log, causing any subsequent console messages to be indented by an additional level, until console.groupEnd() is called.
https://developer.mozilla.org/en-US/docs/Web/API/console/group_static
console.groupCollapsed()
console.groupEnd(); 结束组缩进
console.time()
console.timeLog()
console.timeEnd()
The console.time() static method starts a timer you can use to track how long an operation takes. You give each timer a unique name, and may have up to 10,000 timers running on a given page. When you call console.timeEnd() with the same name, the browser will output the time, in milliseconds, that elapsed since the timer was started.
11.9 URL APIS
创建URL使用构造函数URL(),传递绝对路径字符串或是相对路径作为第一个参数,绝对路径为第二个参数
let url=new URL("https://example.com:8000/path/name?q=term#fragment");
url.href//"https://example.com:8000/path/name?q=term#fragment"
url.origin//"https://example.com:8000"
url.protocol//"https:"
url.host//"example.com:8000"
url.hostname//"example.com"
url.port//"8000"
url.parthname//"/path/name"
url.serach//"?q=term"
url.hash//"#fragment"
origin属性是协议和主机名端口的结合,只读。其他属性是可读可写的
let url=new URL("https://example.com:8000");
url.pathname="path with space";
url.search="q=foo#bar";
URL类会自动添加标点符号也会回避特殊字符。
改变href相当于调用url构造函数。
使用search 和searchParams
search可读可写,searchParams只读
let url=new URL("https://example.com/search");
url.search//"" no query yet
url.searchParams.append("q","term");//add a search parameter
url.search//"?q=term"
url.searchParams.set("q","x");//=>"?q=x"
url.search//"?q=x"
url.searchParams.get("q")//"x"
url.searchParams.has("q")//true
url.searchParams.has("p")//false
url.searchParams.append("opts","1");//add another parameter
url.search//="?q=x&opts=1"
url.searchParams.append("opts","&");//add another value for same name
url.search//=>"?q=x&opts=1&opts=%26":note escape
url.searchParams.get("opts")//"1" the first value
url.searchParams.getAll("opts")//["1","&"] all values
url.searchParams.sort();// order alphabetical
url.search //=>"opts=1&opts=%26&q=x"
url.searchParams.set("opts","y");//change the opts param
url.search//=>"?opts=y&q=x"
//searchParams is iterable
[...url.searchParams.delete("opts");//delete the opts param
url.search//=>"?q=x"
url.href//=>"https://example.com/search?q=x"
searchParams属性使一个URLSearchParams 对象
let url=new URL("http://example.com");
let params=new URLSearchParams();
params.append("q","term");
params.append("opts","exact");
params.toString()//=>"q=term&opts=exact"
url.search=params;
url.href//=?"http://example.com/?q=term&opts=exact"
11.9.1encodeURI() decodeURI()
encodeURI()接收一个字符串作为参数,返回一个新字符串。将非ASCII字符和特定的ASCII码字符(如空格)进行转义,decodeURI()反向操作。
字符会首先转换为UTF-8,接着被替换为%xx x为16进制数。函数不会转换/ ? #
encodeURIComponent() decodeURIComponent()
和上面函数相似,只不过会转换/ ? #
11.10 Timers
setTimeout();
setTimeout(()=>{console.log("Ready...");},1000);
setInterval()反复调用函数。
setTimeout() 和setInterval()返回一个值,可以用这个值进行clearTimeout() clearInteval()
let clock=setInterval(()=>{
console.clear();
console.log(new Date().toLocalTimeString());
},1000);
setTimeout(()=>{clearInterval(clock);},1000);
}

浙公网安备 33010602011771号