es6语法
原 javascript读完大概需要27分钟
- 发布时间:2017-11-28 10:38 星期二
- 刘伟波
- 857
- 更新于: 2018-02-09 15:44 星期五
let const
let 不能重复定义
let a=1;
let a=2; // Uncaught SyntaxError: Identifier 'a' has already been declared
function test() {
for(let i=0;i<4;i++){
console.log(i);
}
console.log(i); // 默认开启严格模式,会报错
}
const 常量 必须赋值
const PI=3.14;
PI=8;
console.log(PI); // Uncaught TypeError: Assignment to constant variable.
对象 可以修改的 引用类型 指针不变的
结构赋值
应用场景:
1.变量交换
2.function f() {
return [1,2,3,4,5]
}
let a,b,c,d;
[a,,,b]=f();
console.log(a,b);// 1 4
3.function f() {
return [1,2,3,4,5]
}
let a,b,c,d;
[a,...b]=f();
console.log(a,b);// 1 [2, 3, 4, 5]
数组结构赋值
let a,b,reset;
[a,b,...reset]=[1,2,3,4,5,6,7];
console.log(a,reset); // 1 [3, 4, 5, 6, 7]
对象结构赋值
let a,b;
({a,b}={a:1,b:2})
console.log(a,b); // 1 2
let {a,b}={a:1,b:2}
console.log(a,b); // 1 2
let metaData = {
title: 'abc',
test: [
{
title: 'test1',
desc: 'description1'
}
]
};
let {title: esTitle, test: [{title: cnTitle}]} = metaData;
console.log(esTitle, cnTitle); // abc test1
Symbal
let a1=Symbol.for('abc');
let b={
'aa':123,
'bb':234,
[a1]:345
};
console.log(b); // {aa: 123, bb: 234, Symbol(abc): 345}
for(let i in b){
console.log(i,b[i]); // aa 123 bb 234
}
console.log(Object.getOwnPropertySymbols(b)); // 返回的是数组
Object.getOwnPropertySymbols(b).forEach(function (item) {
console.log(item,b[item]); // Symbol(abc) 345
})
// 遍历出所有
Reflect.ownKeys(b).forEach(function (item) {
console.log(item,b[item]); // aa 123 bb 234 Symbol(abc) 345
})
promise.all
一种场景,当所有的图片加载完毕,才进行加载到dom元素中
function loadImg(src) {
return new Promise((resolve,reject)=>{
let img=document.createElement('img');
img.src=src;
img.onload=function () {
resolve(img)
};
img.onerror=function () {
reject(img)
}
})
}
function showImg(imgs) {
imgs.forEach(function (img) {
document.body.appendChild(img)
})
}
Promise.all([
loadImg('http://www.liuweibo.cn/img/server.png'),
loadImg('http://www.liuweibo.cn/img/node.png'),
loadImg('http://www.liuweibo.cn/img/h5.png'),
]).then(showImg)
Promise.race
另外一种场景,只需要加载一张图片,哪张网络好先加载那张
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 showImg(img) {
let p=document.createElement('p');
p.appendChild(img);
document.body.appendChild(p)
}
Promise.race([
loadImg('http://www.liuweibo.cn/img/server.png'),
loadImg('http://www.liuweibo.cn/img/node.png'),
loadImg('http://www.liuweibo.cn/img/h5.png'),
]).then(showImg)
iterator for...of...
let arr=['hello','world'];
let map=arr[Symbol.iterator]();
console.log(map.next()); // {value: "hello", done: false}
console.log(map.next()); // {value: "world", done: false}
console.log(map.next()); // {value: undefined", done: true}
自定义 iterator 接口方法
let obj={
start:[1,3,2],
end:[3,5,4],
[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); // 1 3 2 3 5 4
}
generator
eg1
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());
// {value: "a", done: false} {value: "b", done: false} {value: "c", done: true} {value: undefined, done: true}
eg2
let obj={};
obj[Symbol.iterator]=function *() {
yield 1;
yield 2;
yield 3;
}
for(let val of obj){
console.log(val); // 1 2 3
}
eg3
let state=function *() {
while (1){
yield 'A';
yield 'B';
yield 'C';
}
}
let status=state();
console.log(status.next()); //{value: "A", done: false}
console.log(status.next()); //{value: "B", done: false}
console.log(status.next()); //{value: "C", done: false}
console.log(status.next()); //{value: "A", done: false}
console.log(status.next()); //{value: "B", done: false}
eg4 抽奖
let draw=function (count) {
// 具体抽奖逻辑
console.log(`剩余${count}次`);
}
let residue=function* (count) {
while(count>0){
count--;
yield draw(count)
}
}
let start=residue(5);
let btn=document.createElement('button');
btn.id='start';
btn.textContent='点击抽奖';
document.body.appendChild(btn);
document.getElementById('start').addEventListener('click',function () {
start.next(); // 剩余4次 3 2 1 0
},false)
长轮询
let ajax=function *() {
yield new Promise(function (resolve,reject) {
setTimeout(function(){
resolve({code:0}) // 根据后端返回的值
},200)
})
}
let pull=function () {
let generator=ajax();
let step=generator.next();
step.value.then(function (d) {
if(d.code!=0){ // 继续查询
setTimeout(function(){
console.log('wait...');
pull()
},1000)
}else {
console.log(d);
}
})
}
pull()
正则扩展
y:exec 匹配到了返回数组,否则为null,g和y都是全局匹配,y的下一步会紧跟着 _ ,g则不会紧跟着。
let s='bbb_bb_b';
let s1=/b+/g;
let s2=/b+/y;
console.log('one',s1.exec(s),s2.exec(s));
console.log('two',s1.exec(s),s2.exec(s));
console.log(s1.sticky,s2.sticky); // 是否开启了y模式
u:能识别Unicode,两个字符的要加u,比如正则的点(.)匹配任何字符,前提是一个字符。
let s='𠮷'; // 两个字节 ,其他字可能都是一个字符,这个字很特殊
console.log('u',/^.$/.test(s)); // false
console.log('u-2',/^.$/u.test(s)); // true
console.log(/\u{61}/.test('a')); // false
console.log(/\u{61}/u.test('a')); // true
类和对象
class Parent{
constructor(name='muorenzhi'){
this.name=name;
}
}
let v_parent=new Parent('test');
console.log(v_parent); // {name: "test"}
继承
class Parent{
constructor(name='muorenzhi'){
this.name=name;
}
}
class Child extends Parent{
constructor(name='child'){
super (name);
this.type='child'
}
}
console.log('继承',new Child('测试继承')); // {name: "测试继承", type: "child"}
get和set
class Parent{
constructor(name='muorenzhi'){
this.name=name;
}
get longName(){
return 'mk'+this.name
}
set longName(value){
this.name=value;
}
}
let v=new Parent();
console.log(v.longName); // mkmuorenzhi
v.longName='hello';
console.log(v.longName); // mkhello
static
// 静态方法
class Parent{
constructor(name='muorenzhi'){
this.name=name;
}
static tell(){
console.log('tell');
}
}
Parent.tell();// tell
// 静态属性
class Parent{
constructor(name='muorenzhi'){
this.name=name;
}
static tell(){
console.log('tell');
}
}
Parent.type='test';
console.log(Parent.type); // test
字符串
'a'.codePointAt(0) // 取码值 97
String.fromCharCode(97) // 'a' es5
String.fromCodePoint(97) // 'a' es6 大于两个字符的字符
遍历
let s='𠮷abc';
for(let code of s){
console.log(code); // 𠮷 a b c
}
字符串查找
let s='string';
console.log(s.includes('i'));// true
console.log(s.startsWith('str'));// true
console.log(s.endsWith('ng'));// true
字符串复制
let s='string';
console.log(s.repeat(2)); // stringstring
字符串补0
console.log('1'.padStart(2,'0')); // 01 console.log('1'.padEnd(2,'0')); // 10
标签字符串
多语言场景下
let obj={
list:'hello',
list2:'world'
}
console.log(abc`i am ${obj.list},${obj.list2}`);
function abc(s,v1,v2) {
console.log(s,v1,v2);
return s+v1+v2;
}
String.raw 不会转义
console.log(String.raw`HI\n${1+2}`);// HI\n3 不会转义
console.log(`HI\n${1+2}`);
数值扩展
判断是否为整数
console.log(Number.isInteger(24)); // true
console.log(Number.isInteger(24.0)); // true
安全值
console.log(Number.MAX_SAFE_INTEGER,Number.MIN_SAFE_INTEGER); // 9007199254740991 -9007199254740991 2的53次方
console.log(Number.isSafeInteger(234)); // 是否为安全值
取整数部分
console.log(Math.trunc(4.3)); // 4
是否为正负数和0
console.log(Math.sign(4.2)); // 1
console.log(Math.sign(0)); // 0
console.log(Math.sign(-2)); // -1
console.log(Math.sign('23')); // 1
console.log(Math.sign('-23')); // -1
console.log(Math.sign('a')); // NAN
数组扩展
Array.from([],funcation(){}) 类数组继承数组的其他方法
let p=document.querySelectorAll('p');
let newArr=Array.from(p)
newArr.push(2)
console.log(Array.from([1,3,5],function (item) {
return item*2;
})); // [2, 6, 10]
一个类数组对象必须要有length,他们的元素属性名必须是数值或者可以转换成数值的字符。
注意:属性名代表了数组的索引号,如果没有这个索引号,转出来的数组中对应的元素就为空。
console.log('%s', Array.from({ 0: '0', 1: '1', 3: '3', length:4 }))
结果:
0,1,,3
如果对象不带length属性,那么转出来就是空数组。
console.log('%s', Array.from({ 0: 0, 1: 1 }))
结果就是空数组。
对象的属性名不能转换成索引号时。
console.log('%s', Array.from({ a: '1', b: '2', length:2 }))
结果也是空数组
应用:
const chunk = (arr, size) => Array.from({length: Math.ceil(arr.length / size)}, (v, i) => arr.slice(i * size, i * size + size)); // chunk([1,2,3,4,5], 2) -> [[1,2],[3,4],[5]] |
Array.reduce()
语法
array.reduce(function(total, currentValue, currentIndex, arr), initialValue)
参数 | 描述 |
---|---|
total | 必需。初始值, 或者计算结束后的返回值。 |
currentValue | 必需。当前元素 |
currentIndex | 可选。当前元素的索引 |
arr | 可选。当前元素所属的数组对象。 |
const countOccurrences = (arr, value) => arr.reduce((a, v) => v === value ? a + 1 : a + 0, 0); // countOccurrences([1,1,2,1,2,3], 1) -> 3 |
var testdata = {0: {test_id: 80, id: 3}, 1: {test_id: 80, id: 2}, 3: {test_id: 95, id: 3}, 4: {test_id: 95, id: 4}};
var result = {
80:[{test_id:80,id:3},{test_id:80,id:2}],
95:[{test_id:95,id:3}, {test_id:95,id:4}]
}
var res = Object.keys(testdata).reduce((res, next) => {
let item = testdata[next];
let { test_id } = item;
if (res[test_id]) {
res[test_id].push(item);
} else {
res[test_id] = [item];
}
return res;
}, {});
console.log(res);
Array.fill(),第一个参数替换的数,第二三个是替换的起始位置和结束位置
console.log([1,3,4,5,6].fill(88)); // [88, 88, 88, 88, 88]
console.log([1,3,4,5,6].fill(88,2,4)); // [1, 3, 88, 88, 6]
Array.keys() Array.valueOf() Array.entries()
for(let index of [1,2,3,4].keys()){
console.log(index); // 输出了数组的下标
}
for(let index of [1,2,3,4].valueOf()){
console.log(index); // 输出了数组的值
}
for(let index of [1,2,3,4].entries()){
console.log(index); // 输出了数组的值和value
}
Array.copyWithin() (三个参数) 从哪个位置开始修改,找到第二个参数和第三个参数之间的数替换
console.log(['a','b','c','d','e'].copyWithin(1,2,4)); // ["a", "c", "d", "d", "e"]
Array.find(callback) Array.findIndex(callback)
console.log([1,2,3,4,5,6].find(function (item) {
return item>3
})); // 4 只找到对应的值就停止
console.log([1,2,3,4,5,6].findIndex(function (item) {
return item>3
})); // 3 只找到对应的下标就停止
Array.includes() 返回值 布尔值
console.log([1,2,3,4,5,6,NaN].includes(NaN)) // true
函数
作用域内有的,默认值为函数内部,没有否则为外部
let x = 'test';
function abc(c, y = x) {
console.log(c, y);
}
abc(2); // 2 "test"
function abc2(x, y = x) {
console.log(x, y);
}
abc2(2); // 2 2
不确定参数
function abc(...arg) {
console.log(arg); // [1, 2, 3, 4]
for(let v of arg){
console.log(v);
}
}
abc(1,2,3,4)
伪调用,提升性能(递归)
function tail(a) {
console.log(a);
}
function tt(a) {
return tail(a)
}
tt(123) ; // 123
对象
1.变量为key值
let k='b';
let es5={
k:'a',
b:'a'
};
let es6={
[k]:'a'
}
console.log(es5,es6);
2.新增API
console.log(Object.is([],[]),[]===[]); // false false
console.log(Object.assign({a:'a'},{b:'b'})); // {a: "a", b: "b"} 浅拷贝
let test={k:123,o:456};
for(let [key,value] of Object.entries(test)){
console.log([key,value]); // ["k", 123] ["o", 456]
}
扩展运算符
let {a,b,...c}={a:'test',b:'aaa',c:'bbb',d:'ccc'}
//其实 c就是一个对象 现在es6还不支持的很好
console.log(c); //{c: "bbb", d: "ccc"}
set map数据结构
set
特性:不会重复
去重
let test=new Set([1,2,3,4,2,3])Array.from(new Set(test))
console.log(test);
test.add(); // 增加 test.has(); // 返回true/false test.size; // 返回几个 test.delete() ; // 删除 test.clear();// 清空
遍历
let test=new Set([1,2,3,4,2,3])
for(let k of test){ // test.keys() test.values() test 值是一样的
console.log(k); // 1 2 3 4
}
let test=new Set(['a','b','c'])
test.forEach(function (item) {
console.log(item);
})
map
特性:key值key为任意
let map=new Map();
let arr=['123'];
map.set(arr,456);
console.log(map,map.get(arr)); // Map(1) {Array(1) => 456} 456
proxy和reflect
let obj={
time:'2017-11-12',
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'){ // 志云去改变name的值
return target[key]=value;
}else {
return target[key];
}
}
});
console.log('get',monitor.time); // 2018-11-12
monitor.time=2019;
monitor.name='mukewang';
console.log('get',monitor.time); // 2018-11-12
console.log('set',monitor);
发表评论: