let const 存在块作用域的概念
必须先声明后使用,且不能重复声明
const 只能声明常量。这个常量对于引用型来说只是指针不能变。
左边一种结构,右边一种结构,左右一一对应,完成赋值。
分类:
数组解构赋值、对象解构赋值、字符串解构赋值、布尔值解构赋值、函数参数解构赋值、数值解构赋值
{
let a,b,reset;
[a,b] = [1,2]
console.log(a,b)
}
{
let a,b,reset;
[a,b,...reset] = [1,3,2,4,5,6];
console.log(a,b,reset)
}
{
let a,b;
({a,b} = {a:1,b:3});
console.log(a,b)
}
{
//如果未找到配对值,就是undefined,默认值就是为了解决这个问题的
let a,b,c;
({a,b,c=3} = {a:1,b:3});
console.log(a,b)
}
{
// 变量交换or获取函数返回值
let a = 1,b = 2;
[a,b] = [b,a];
console.log(a,b)
}
{
//选择性接受想要的值
function f() {
return [1,2,3,4,5]
}
let a,b;
[a,,...b] = f();
console.log(a,b);
}
{
//选择性接受想要的值
function f() {
return [1,2,3,4,5]
}
let a,b;
[a,...b] = f();
console.log(a,b);
}
{
let o = {p:12,q:'ewe'};
let {p,q,z = 2} = o;
console.log(p,q,z);
}
{
let metaData = {
title:'abc',
test:[{
title:'test',
desc:'description'
}]
}
let {title:esTitle,test:[{title:cnTitle}]} = metaData
console.log(esTitle,cnTitle)
}
{
// #构造函数#
let regex = new RegExp('xyz', 'i'); //第一个参数是字符串,第二个是修饰符
let regex2 = new RegExp(/xyz/i); //第一个参数是正则表达式,不接受第二个参数,否则会报错
console.log(regex.test('xyz123'), regex2.test('xyz123'));
console.log(regex.test('xyZ123'), regex2.test('xyZ123'));
let regex3 = new RegExp(/abc/ig, 'i');
console.log(regex3.flags); //原有正则对象的修饰符是ig,它会被第二个参数i覆盖
}
// 字符串对象的4个使用正则表达式的方法: match(),replace(),search(),split()这四个方法全部调用RegExp的实例的方法。
{
let regex = new RegExp('xyz', 'ig');
console.log(regex.test('xyz0XYZ1xyz2'), regex.exec('xyz0XYZ1xyz2'));
}
{
// y修饰符
let s = 'bbbb_bbb_bb_b';
var a1 = /b+/g;
var a2 = /b+/y;
console.log(a1.exec(s), a2.exec(s)); // ["bbbb"],["bbbb"]
console.log(a1.exec(s), a2.exec(s)); // ["bbb"],null
console.log(a1.sticky, a2.sticky); //表示是否开启了粘连模式
}
{
console.log('u修饰符',/^\uD83D/.test('\uD83D\uDC2A')); // true
console.log('u修饰符',/^\uD83D/u.test('\uD83D\uDC2A')); // false
// 大括号表示Unicode字符,只有加上u才能识别
console.log(/\u{61}/.test('a')); // false
console.log(/\u{61}/u.test('a')); // true
console.log(/\u{20BB7}/u.test('𠮷')); // true
// 点(.)字符不能识别码点大于0xFFFF的Unicode字符,必须加上u修饰符。
let s = '𠮷';
console.log('大于0xFFFF的Unicode字符',/^.$/.test(s)); // false
console.log('使用u字符',/^.$/u.test(s)); // true
// 使用u修饰符后,所有量词都会正确识别大于码点大于0xFFFF的Unicode字符。
console.log('量词',/a{2}/.test('aa')); // true
console.log('量词',/a{2}/u.test('aa')); // true
console.log('量词',/𠮷{2}/.test('𠮷𠮷')); // false
console.log('量词',/𠮷{2}/u.test('𠮷𠮷')); // true
}
{
// #正则表达式中,点(.)是一个特殊字符,代表任意的单个字符,但是行终止符(line terminator character)除外
// U+000A 换行符(\n)
// U+000D 回车符(\r)
// U+2028 行分隔符(line separator)
// U+2029 段分隔符(paragraph separator)
// 只是一个提案目前还不支持
// let reg=/test.go/s;
// console.log(reg.test('test\ngo'));
// console.log(reg.test('test\ngo'));
console.log('s变通方法',/foo.bar/.test('foo\nbar'));
console.log('s变通方法',/foo[^]bar/.test('foo\nbar'));
}
字符串中处理Unicode方法,遍历接口,模板字符串,新增方法(10个)
{
console.log('a',`\u0061`);
console.log('s',`\u20BB7`);
console.log('s',`\u{20BB7}`);
}
{
let s='𠮷';
console.log('length',s.length);
console.log('0',s.charAt(0));
console.log('1',s.charAt(1));
console.log('at0',s.charCodeAt(0));
console.log('at1',s.charCodeAt(1));
let s1='𠮷a';
console.log('length',s1.length);
console.log('code0',s1.codePointAt(0));
console.log('code0',s1.codePointAt(0).toString(16));
console.log('code1',s1.codePointAt(1));
console.log('code2',s1.codePointAt(2));
}
{
console.log(String.fromCharCode("0x20bb7"));
console.log(String.fromCodePoint("0x20bb7"));
}
{
let str='\u{20bb7}abc';
for(let i=0;i<str.length;i++){
console.log('es5',str[i]);
}
for(let code of str){
console.log('es6',code);
}
}
{
let str="string";
console.log('includes',str.includes("c"));
console.log('start',str.startsWith('str'));
console.log('end',str.endsWith('ng'));
}
{
let str="abc";
console.log(str.repeat(2));
}
{
let name="list";
let info="hello world";
let m=`i am ${name},${info}`;
console.log(m);
}
{
console.log('1'.padStart(2,'0'));
console.log('1'.padEnd(2,'0'));
}
{
let user={
name:'list',
info:'hello world'
};
console.log(abc`i am ${user.name},${user.info}`);
function abc(s,v1,v2){
console.log(s,v1,v2);
return s+v1+v2
}
}
{
console.log(String.raw`Hi\n${1+2}`);
console.log(`Hi\n${1+2}`);
}
{
console.log('B',0B111110111);
console.log(0o767);
}
{
console.log('15',Number.isFinite(15));
console.log('NaN',Number.isFinite(NaN));
console.log('1/0',Number.isFinite('true'/0));
console.log('NaN',Number.isNaN(NaN));
console.log('0',Number.isNaN(0));
}
{
console.log('25',Number.isInteger(25));
console.log('25.0',Number.isInteger(25.0));
console.log('25.1',Number.isInteger(25.1));
console.log('25.1',Number.isInteger('25'));
}
{
console.log(Number.MAX_SAFE_INTEGER,Number.MIN_SAFE_INTEGER);
console.log('10',Number.isSafeInteger(10));
console.log('a',Number.isSafeInteger('a'));
}
{
console.log(4.1,Math.trunc(4.1));
console.log(4.9,Math.trunc(4.9));
}
{
console.log('-5',Math.sign(-5));
console.log('0',Math.sign(0));
console.log('5',Math.sign(5));
console.log('50',Math.sign('50'));
console.log('foo',Math.sign('foo'));
}
{
console.log('-1',Math.cbrt(-1));
console.log('8',Math.cbrt(8));
}
{
let arr = Array.of(3,4,7,9,11);
console.log('arr=',arr);
let empty=Array.of();
console.log('empty',empty);
}
{
let p=document.querySelectorAll('p');
let pArr=Array.from(p);
pArr.forEach(function(item){
console.log(item.textContent);
});
console.log(Array.from([1,3,5],function(item){return item*2}));
}
{
console.log('fill-7',[1,'a',undefined].fill(7));
console.log('fill,pos',['a','b','c'].fill(7,1,3));
}
{
for(let index of ['1','c','ks'].keys()){
console.log('keys',index);
}
for(let value of ['1','c','ks'].values()){
console.log('values',value);
}
for(let [index,value] of ['1','c','ks'].entries()){
console.log('values',index,value);
}
}
{
console.log([1,2,3,4,5].copyWithin(0,3,4));
}
{
console.log([1,2,3,4,5,6].find(function(item){return item>3}));
console.log([1,2,3,4,5,6].findIndex(function(item){return item>3}));
}
{
console.log('number',[1,2,NaN].includes(1));
console.log('number',[1,2,NaN].includes(NaN));
}
{
// 默认值后面不能没有默认值的变量
function test(x, y = 'world'){
console.log('默认值',x,y);
}
test('hello');
test('hello','kill');
}
{
// y获取的是传入的形参的x,如果前面没有x,那么y取test的那个x
let x='test';
function test2(x,y=x){
console.log('作用域',x,y);
}
test2('kill');
}
{
// 都转为数组,类似于arguments
function test3(...arg){
for(let v of arg){
console.log('rest',v);
}
}
test3(1,2,3,4,'a');
}
{
// 扩展运算符 数组展开符
console.log(...[1,2,4]);
console.log('a',...[1,2,4]);
}
{
let arrow = v => v*2;
let arrow2 = () => 5;
console.log('arrow',arrow(3));
console.log(arrow2());
}
{
function tail(x){
console.log('tail',x);
}
function fx(x){
return tail(x)
}
fx(123)
}
{
// 简洁表示法
let o=1;
let k=2;
let es5={
o:o,
k:k
};
let es6={
o,
k
};
console.log(es5,es6);
let es5_method={
hello:function(){
console.log('hello');
}
};
let es6_method={
hello(){
console.log('hello');
}
};
console.log(es5_method.hello(),es6_method.hello());
}
{
// 属性表达式
let a='b';
let es5_obj={
a:'c',
b:'c'
};
let es6_obj={
[a]:'c'
}
console.log(es5_obj,es6_obj);
}
{
// 新增API
console.log('字符串',Object.is('abc','abc'),'abc'==='abc');
console.log('数组',Object.is([],[]),[]===[]);
console.log('拷贝',Object.assign({a:'a'},{b:'b'}));
let test={k:123,o:456};
for(let [key,value] of Object.entries(test)){
console.log([key,value]);
}
}
{
// 扩展运算符
// let {a,b,...c}={a:'test',b:'kill',c:'ddd',d:'ccc'};
// c={
// c:'ddd',
// d:'ccc'
// }
}
声明不重复不相等的变量,保证唯一性
{
// 声明
let a1=Symbol();
let a2=Symbol();
console.log(a1===a2);
let a3=Symbol.for('a3');
let a4=Symbol.for('a3');
console.log(a3===a4);
}
{
let a1=Symbol.for('abc');
let obj={
[a1]:'123',
'abc':345,
'c':456
};
console.log('obj',obj);
for(let [key,value] of Object.entries(obj)){
console.log('let of',key,value);
}
Object.getOwnPropertySymbols(obj).forEach(function(item){
console.log(obj[item]);
})
Reflect.ownKeys(obj).forEach(function(item){
console.log('ownkeys',item,obj[item]);
})
}
{
let list = new Set();
list.add(5);
list.add(7);
console.log('size',list.size);
}
{
let arr = [1,2,3,4,5];
let list = new Set(arr);
console.log('size',list.size);
}
{
let list = new Set();
list.add(1);
list.add(2);
list.add(1);
console.log('list',list);
let arr=[1,2,3,1,'2'];
let list2=new Set(arr);
console.log('unique',list2);
}
{
let arr=['add','delete','clear','has'];
let list=new Set(arr);
console.log('has',list.has('add'));
console.log('delete',list.delete('add'),list);
list.clear();
console.log('list',list);
}
{
let arr=['add','delete','clear','has'];
let list=new Set(arr);
for(let key of list.keys()){
console.log('keys',key);
}
for(let value of list.values()){
console.log('value',value);
}
for(let [key,value] of list.entries()){
console.log('entries',key,value);
}
list.forEach(function(item){console.log(item);})
}
{
let weakList=new WeakSet();
let arg={};
weakList.add(arg);
// weakList.add(2);
console.log('weakList',weakList);
}
{
let map = new Map();
let arr=['123'];
map.set(arr,456);
console.log('map',map,map.get(arr));
}
{
let map = new Map([['a',123],['b',456]]);
console.log('map args',map);
console.log('size',map.size);
console.log('delete',map.delete('a'),map);
console.log('clear',map.clear(),map);
}
{
let weakmap=new WeakMap();
let o={};
weakmap.set(o,123);
console.log(weakmap.get(o));
}
{
// 数据结构横向对比,增,查,改,删
let map=new Map();
let array=[];
// 增
map.set('t',1);
array.push({t:1});
console.info('map-array',map,array);
// 查
let map_exist=map.has('t');
let array_exist=array.find(item=>item.t);
console.info('map-array',map_exist,array_exist);
// 改
map.set('t',2);
array.forEach(item=>item.t?item.t=2:'');
console.info('map-array-modify',map,array);
// 删
map.delete('t');
let index=array.findIndex(item=>item.t);
array.splice(index,1);
console.info('map-array-empty',map,array);
}
{
// set和array的对比
let set=new Set();
let array=[];
// 增
set.add({t:1});
array.push({t:1});
console.info('set-array',set,array);
// 查
let set_exist=set.has({t:1});
let array_exist=array.find(item=>item.t);
console.info('set-array',set_exist,array_exist);
// 改
set.forEach(item=>item.t?item.t=2:'');
array.forEach(item=>item.t?item.t=2:'');
console.info('set-array-modify',set,array);
// 删
set.forEach(item=>item.t?set.delete(item):'');
let index=array.findIndex(item=>item.t);
array.splice(index,1);
console.info('set-array-empty',set,array);
}
{
// map,set,object对比
let item={t:1};
let map=new Map();
let set=new Set();
let obj={};
// 增
map.set('t',1);
set.add(item);
obj['t']=1;
console.info('map-set-obj',obj,map,set);
// 查
console.info({
map_exist:map.has('t'),
set_exist:set.has(item),
obj_exist:'t' in obj
})
// 改
map.set('t',2);
item.t=2;
obj['t']=2;
console.info('map-set-obj-modify',obj,map,set);
// 删除
map.delete('t');
set.delete(item);
delete obj['t'];
console.info('map-set-obj-empty',obj,map,set);
}
与业务解耦
{
let obj={
time:'2017-03-11',
name:'net',
_r:123
};
let monitor=new Proxy(obj,{
// 拦截对象属性的读取
get(target,key){
return target[key].replace('2017','2018')
},
// 拦截对象设置属性
set(target,key,value){
if(key==='name'){
return target[key]=value;
}else{
return target[key];
}
},
// 拦截key in object操作
has(target,key){
if(key==='name'){
return target[key]
}else{
return false;
}
},
// 拦截delete
deleteProperty(target,key){
if(key.indexOf('_')>-1){
delete target[key];
return true;
}else{
return target[key]
}
},
// 拦截Object.keys,Object.getOwnPropertySymbols,Object.getOwnPropertyNames
ownKeys(target){
return Object.keys(target).filter(item=>item!='time')
}
});
console.log('get',monitor.time);
monitor.time='2018';
monitor.name='mukewang';
console.log('set',monitor.time,monitor);
console.log('has','name' in monitor,'time' in monitor);
// delete monitor.time;
// console.log('delete',monitor);
//
// delete monitor._r;
// console.log('delete',monitor);
console.log('ownKeys',Object.keys(monitor));
}
{
let obj={
time:'2017-03-11',
name:'net',
_r:123
};
console.log('Reflect get',Reflect.get(obj,'time'));
Reflect.set(obj,'name','mukewang');
console.log(obj);
console.log('has',Reflect.has(obj,'name'));
}
{
function validator(target,validator){
return new Proxy(target,{
_validator:validator,
set(target,key,value,proxy){
if(target.hasOwnProperty(key)){
let va=this._validator[key];
if(!!va(value)){
return Reflect.set(target,key,value,proxy)
}else{
throw Error(`不能设置${key}到${value}`)
}
}else{
throw Error(`${key} 不存在`)
}
}
})
}
const personValidators={
name(val){
return typeof val==='string'
},
age(val){
return typeof val === 'number' && val>18
},
mobile(val){
}
}
class Person{
constructor(name,age){
this.name=name;
this.age=age;
this.mobile='1111';
return validator(this,personValidators)
}
}
const person=new Person('lilei',30);
console.info(person);
person.name='Han mei mei';
console.info(person);
}
{
// 基本定义和生成实例
class Parent{
constructor(name='mukewang'){
this.name=name;
}
}
let v_parent=new Parent('v');
console.log('构造函数和实例',v_parent);
}
{
// 继承
class Parent{
constructor(name='mukewang'){
this.name=name;
}
}
class Child extends Parent{
}
console.log('继承',new Child());
}
{
// 继承传递参数
class Parent{
constructor(name='mukewang'){
this.name=name;
}
}
class Child extends Parent{
constructor(name='child'){
super(name);
this.type='child';
}
}
console.log('继承传递参数',new Child('hello'));
}
{
// getter,setter
class Parent{
constructor(name='mukewang'){
this.name=name;
}
get longName(){
return 'mk'+this.name
}
set longName(value){
this.name=value;
}
}
let v=new Parent();
console.log('getter',v.longName);
v.longName='hello';
console.log('setter',v.longName);
}
{
// 静态方法
class Parent{
constructor(name='mukewang'){
this.name=name;
}
static tell(){
console.log('tell');
}
}
Parent.tell();
}
{
// 静态属性
class Parent{
constructor(name='mukewang'){
this.name=name;
}
static tell(){
console.log('tell');
}
}
Parent.type='test';
console.log('静态属性',Parent.type);
}
{
// 基本定义
let ajax=function(callback){
console.log('执行');
setTimeout(function () {
callback&&callback.call()
}, 1000);
};
ajax(function(){
console.log('timeout1');
})
}
{
let ajax=function(){
console.log('执行2');
return new Promise(function(resolve,reject){
setTimeout(function () {
resolve()
}, 1000);
})
};
ajax().then(function(){
console.log('promise','timeout2');
})
}
{
let ajax=function(){
console.log('执行3');
return new Promise(function(resolve,reject){
setTimeout(function () {
resolve()
}, 1000);
})
};
ajax()
.then(function(){
return new Promise(function(resolve,reject){
setTimeout(function () {
resolve()
}, 2000);
});
})
.then(function(){
console.log('timeout3');
})
}
{
let ajax=function(num){
console.log('执行4');
return new Promise(function(resolve,reject){
if(num>5){
resolve()
}else{
throw new Error('出错了')
}
})
}
ajax(6).then(function(){
console.log('log',6);
}).catch(function(err){
console.log('catch',err);
});
ajax(3).then(function(){
console.log('log',3);
}).catch(function(err){
console.log('catch',err);
});
}
{
// 所有图片加载完再添加到页面
function loadImg(src){
return new Promise((resolve,reject)=>{
let img=document.createElement('img');
img.src=src;
img.onload=function(){
resolve(img);
}
img.onerror=function(err){
reject(err);
}
})
}
function showImgs(imgs){
imgs.forEach(function(img){
document.body.appendChild(img);
})
}
Promise.all([
loadImg('http://i4.buimg.com/567571/df1ef0720bea6832.png'),
loadImg('http://i4.buimg.com/567751/2b07ee25b08930ba.png'),
loadImg('http://i2.muimg.com/567751/5eb8190d6b2a1c9c.png')
]).then(showImgs)
}
{
// 有一个图片加载完就添加到页面
function loadImg(src){
return new Promise((resolve,reject)=>{
let img=document.createElement('img');
img.src=src;
img.onload=function(){
resolve(img);
}
img.onerror=function(err){
reject(err);
}
})
}
function showImgs(img){
let p=document.createElement('p');
p.appendChild(img);
document.body.appendChild(p)
}
Promise.race([
loadImg('http://i4.buimg.com/567571/df1ef0720bea6832.png'),
loadImg('http://i4.buimg.com/567751/2b07ee25b08930ba.png'),
loadImg('http://i2.muimg.com/567751/5eb8190d6b2a1c9c.png')
]).then(showImgs)
}
{
let arr=['hello','world'];
let map=arr[Symbol.iterator]();
console.log(map.next());
console.log(map.next());
console.log(map.next());
}
{
let obj={
start:[1,3,2],
end:[7,9,8],
[Symbol.iterator](){
let self=this;
let index=0;
let arr=self.start.concat(self.end);
let len=arr.length;
return {
next(){
if(index<len){
return {
value:arr[index++],
done:false
}
}else{
return {
value:arr[index++],
done:true
}
}
}
}
}
}
for(let key of obj){
console.log(key);
}
}
{
let arr=['hello','world'];
for(let value of arr){
console.log('value',value);
}
}
异步编程的一种解决方案
{
// genertaor基本定义
let tell=function* (){
yield 'a';
yield 'b';
return 'c'
};
let k=tell();
console.log(k.next());
console.log(k.next());
console.log(k.next());
console.log(k.next());
}
{
let obj={};
obj[Symbol.iterator]=function* (){
yield 1;
yield 2;
yield 3;
}
for(let value of obj){
console.log('value',value);
}
}
{
let state=function* (){
while(1){
yield 'A';
yield 'B';
yield 'C';
}
}
let status=state();
console.log(status.next());
console.log(status.next());
console.log(status.next());
console.log(status.next());
console.log(status.next());
}
// {
// let state=async function (){
// while(1){
// await 'A';
// await 'B';
// await 'C';
// }
// }
// let status=state();
// console.log(status.next());
// console.log(status.next());
// console.log(status.next());
// console.log(status.next());
// console.log(status.next());
// }
//
{
let draw=function(count){
//具体抽奖逻辑
console.info(`剩余${count}次`)
}
let residue=function* (count){
while (count>0) {
count--;
yield draw(count);
}
}
let star=residue(5);
let btn=document.createElement('button');
btn.id='start';
btn.textContent='抽奖';
document.body.appendChild(btn);
document.getElementById('start').addEventListener('click',function(){
star.next();
},false)
}
{
// 长轮询
let ajax=function* (){
yield new Promise(function(resolve,reject){
setTimeout(function () {
resolve({code:0})
}, 200);
})
}
let pull=function(){
let genertaor=ajax();
let step=genertaor.next();
step.value.then(function(d){
if(d.code!=0){
setTimeout(function () {
console.info('wait');
pull()
}, 1000);
}else{
console.info(d);
}
})
}
pull();
}
是一个函数,修改类的行为,扩展类的功能,只在类的范畴中有用
{
let readonly=function(target,name,descriptor){
descriptor.writable=false;
return descriptor
};
class Test{
@readonly
time(){
return '2017-03-11'
}
}
let test=new Test();
// test.time=function(){
// console.log('reset time');
// };
console.log(test.time());
}
{
let typename=function(target,name,descriptor){
target.myname='hello';
}
@typename
class Test{
}
console.log('类修饰符',Test.myname);
// 第三方库修饰器的js库:core-decorators; npm install core-decorators
}
{
let log=(type)=>{
return function(target,name,descriptor){
let src_method=descriptor.value;
descriptor.value=(...arg)=>{
src_method.apply(target,arg);
console.info(`log ${type}`);
}
}
}
class AD{
@log('show')
show(){
console.info('ad is show')
}
@log('click')
click(){
console.info('ad is click');
}
}
let ad=new AD();
ad.show();
ad.click();
}
// export let A=123;
//
// export function test(){
// console.log('test');
// }
//
// export class Hello{
// test(){
// console.log('class');
// }
// }
let A=123;
let test=function(){
console.log('test');
}
class Hello{
test(){
console.log('class');
}
}
export default {
A,
test,
Hello
}