十五、Map和WeakMap
1、Map
用途:类似json,但是 json 的键(key)只能是字符串
map 的 key 可以是任意类型
使用:定义 let map = new Map();
设置 map.set(key,value); // 设置一个值
获取 map.get(key); //获取一个值
删除 map.delete(key); //删除一项
判断 map.has(key); //判断
清空 map.clear(); //清空
循环 for(let [key,value] of map){}
for(let key of map.keys()){}
for(let value of map.values()){}
for(let [k,v] of map.entries()){}
map.forEach((val,key)=>{
})
// 定义
let map = new Map();
let json = {
a: 1,
b: 2
};
// 设置
map.set('a', 'aaa');
map.set(json, 'aaa');
map.set('aaa', json);
console.log(map); //输出 Map(3) {"a" => "aaa", {…} => "aaa", "aaa" => {…}}
// 获取
console.log(map.get('a')); //输出 aaa
// 删除
map.delete('a');
console.log(map); //输出Map(2) {{…} => "aaa", "aaa" => {…}}
//判断
console.log(map.has('a')); //输出 false
//清空
map.clear();
console.log(map); // 输出 Map(0) {}
// for循环
//重新设置
map.set('a', 'aaa');
map.set(json, 'aaa');
map.set('aaa', json);
for (let [key, value] of map) {
console.log(key, value); //循环输出每一个键值对
}
map.forEach((value,key)=>{
console.log(value,key);
});
注意:map和set方法很多一样,除了map 多了一个get(key)方法。
2、WeakMap
注意:key只能是对象,但是用处不大
// 定义
let map = new WeakMap();
let json = {
a: 1,
b: 2
};
map.set(json,'1');
console.log(map); //输出 WeakMap {{…} => "1"}
let errmap = new WeakMap();
errmap.set('1','1');
console.log(errmap); // 输出 Uncaught TypeError
总结:Set 里面是数组,不重复,没有key,没有get方法
Map 对json功能增强,key可以是任意类型值
十六、数字变化和Math新增东西
1、数字(数值)变化
(1)进制
二进制(binary)
let a = 0b01010;
八进制 (Octal)
let b = 0c666;
十六进制
ccc
(2)Number方法
Number.isNaN() 等同于isNaN(),只是挂载到了Number身上
Number.isFinite() 判断是不是数字
Number.isInteger 判断是不是整数
.....
安全整数:-(253-1)~(253-1) 包含边界
Number.isSafeInteger() 判断是不是安全整数
Number.MAX_SAFE_INTEGER 最大安全整数
Number.MIN_SAFE_INTEGER 最小安全整数
2、Math
Math.abs()
Math.sqrt()
Math.sin()
Math.trunc() 截取,只保留整数部分
console.log(Math.trunc(4.5)); //输出 4
console.log(Math.trunc(-4.3)); //输出 -4
Math.sign() 判断一个数到底是正数、负数、0
console.log(Math.sign(-5)); //输出 -1
console.log(Math.sign(5)); //输出 1
console.log(Math.sign(0)); //输出 0
console.log(Math.sign(-0)); //输出 -0
console.log(Math.sign('abc'));//输出 NaN
Math.cbrt() 计算立方根
console.log(Math.cbrt(27)); //输出 3
十七、ES2018(ES9)新增东西
1、命名捕获
语法:(?<名字>)
一个例子:(日期拆分)
//以前的
let str = '2018-03-20';
let reg = /(\d{4})-(\d{2})-(\d{2})/;
let dataArr = str.match(reg);
console.log(dataArr);
let year = dataArr[1];
let month = dataArr[2];
let day = dataArr[3];
console.log(year,month,day); //输出 2018 03 20
//ES9
let str = '2018-03-20';
let reg = /(?<year>\d{4})-(?<month>\d{2})-(?<day>\d{2})/;
let {year,month,day} = str.match(reg).groups;
console.log(year, month, day); //输出 2018 03 20
反向引用: \1 \2 2
反向引用命名捕获: 语法:\k<名字>
let reg = /^(?<Strive>welcome)-\k<Strive>$/;
let str = 'a-a';
let str2 = 'Strive-Strive';
let str3 = 'welcome-welcome';
console.log(reg.test(str)); // false
console.log(reg.test(str2)); // false
console.log(reg.test(str3)); // true
替换:replace
let str = '2018-03-20';
let reg = /(?<year>\d{4})-(?<month>\d{2})-(?<day>\d{2})/;
str = str.replace(reg,'$<day>/$<month>/$<year>');
console.log(str); //输出 20/03/2018
let str = '2018-03-20';
let reg = /(?<year>\d{4})-(?<month>\d{2})-(?<day>\d{2})/;
str = str.replace(reg,(...args)=>{
console.log(args);
let {year,month,day} = args[args.length-1];
return `${day}/${month}/${year}'`;
});
console.log(str); //输出 20/03/2018
注意:return的时候用的是<>
2、dotAll模式
之前:'.'在正则里面表示匹配任意东西,但是不包括\n
let reg = /\w+/gims;
3、标签函数
function fn(){
}
fn() //这样调用就是普通函数
fnaaa
//注意用的是反斜杠
function fn(args){
return args[0].toUpperCase();
}
console.log(fn`welcome`); //输出 WELCOME
十八、Proxy的使用
作用:1、扩展(增强)对象、方法一些功能
2、比如Vue中的拦截
3、预警、上报、扩展、统计、增强对象等等
它是设计模式的一种,代理模式
语法:
new Proxy(target,handler);
let obj = new Proxy(被代理的对象,对代理的对象做什么操作)
handle{
set(){} //设置的时候干的事情
get(){} //获取干的事情
deleteProperty(){} //删除
has(){} //问你有没有这个东西 'xxx' in obj
apply() //调用函数处理,拦截方法
.......
}
例1:(增加一个代理对象,访问不是原对象属性时会抛出错误,这些是访问之前的操作)
let obj = {
name:'Strive'
}
let newObj = new Proxy(obj,{
get(target,property){
// 访问之前可以做的操作
console.log(`您访问了${property}属性`); //您访问了name属性
if(property in target){
return target[property];
}else{
throw new ReferenceError(`${property}属性不在此对象上`);
}
}
})
console.log(newObj.name); //Strive
console.log(newObj.age); //没加判断之前访问默认是 undefined,加了之后会
//显示Uncaught ReferenceError: age属性不在此对象上
例2:DOM.div() DOM.a(); DOM.ul()
const DOM = new Proxy({},{
get(target,property){
return function(attr={},...children){
const el = document.createElement(property);
// 添加属性
for(let key of Object.keys(attr)){
el.setAttribute(key,attr[key]);
}
// 添加子元素
for(let child of children){
if(typeof child == 'string'){
child = document.createTextNode(child);
}
el.appendChild(child);
}
return el;
}
}
});
let oDiv = DOM.div(
{id:'div1',class:'aaa'},'我是div','哈哈哈',
DOM.a({href:'http://www.baidu.com'},'访问官网'),
DOM.ul({},
DOM.li({},'1111'),
DOM.li({},'2222')
)
)
window.onload = function(){
document.body.appendChild(oDiv);
}
运行结果:
2.png例3:set(),设置拦截,设置一个年龄,保证是整数,且范围不超过200
let obj = new Proxy({},{
set(target,prop,value){
if(prop == 'age'){
if(!Number.isInteger(value)){
throw new TypeError('年龄必须为整数');
}
if(value>200){
throw new RangeError('年龄超标了,必须小于200岁');
}
}
target[prop] = value;
}
});
obj.a = 123;
obj.name = 'strive';
obj.age = 220;
console.log(obj); //输出 Uncaught RangeError: 年龄超标了,必须小于200岁
例3:deleteProperty()、has()
let json = {
a:1,
b:2
}
let newJson = new Proxy(json,{
deleteProperty(target,property){
console.log(`您要删除${property}属性`); //输出 您要删除a属性
delete target[property];
},
has(target,property){
console.log('判断是否存在调用has方法'); // 输出 判断是否存在调用has方法
return property in target;
}
});
console.log('a' in newJson);// 这里调用 has 方法,输出true
delete newJson.a; // 这里调用 delete 方法
console.log(newJson); // 输出 Proxy {b: 2}
例4:apply() :拦截
function fn(){
return '我是函数';
}
let newfn = new Proxy(fn,{
apply(){
return '函数吗?';
}
});
console.log(newfn()); //输出 函数吗?
注意:apply()上面的只是拦截到了,并没有执行完函数,需要和reflect配合使用
十九、Reflect的使用
反射。(相对于执行函数)
Reflect.apply(调用的函数,this指向,参数数组);
与fn.apply() 类似
Reflect :思想 通过Reflect对象身上直接拿到语言内部东西
//例1
function sum(a,b){
return a+b;
}
let newSum = new Proxy(sum,{
apply(target,context,args){
return Reflect.apply(...arguments); //反射调用
}
});
console.log(newSum(2,3)); //前面加了reflect,这里可以得到 5
//例2
function show(...args){
console.log(this);
console.log(args);
}
show(1,2,3,4); // 只有参数,this指向:window args:[1, 2, 3, 4]
show.call('abc',1,2,3,4);// this指向:String {"abc"} args:[1, 2, 3, 4]
show.apply('abcd',[2,3,3,2]);//this指向:String {"abcd"} args:[2, 3, 3, 2]
Reflect.apply(show,'aaaa',[1,2,3,4]);//this指向:String {"aaaa"} args:[1, 2, 3, 4]
//例3
console.log(Reflect.has(Object,'assign')); //输出true
//例3
let json = {a:1,b:2};
// delete json.a;
Reflect.deleteProperty(json,'a'); //等同于上面这句
console.log(json); //输出 {b: 2}
网友评论