loading...

1

es6语法

javascript读完大概需要27分钟

  • 发布时间:2017-11-28 10:38 星期二
  • 刘伟波
  • 323
  • 更新于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);


你可能感兴趣的文章

    发表评论

    评论支持markdown,评论内容不能超过500字符,如果内容过多或者要及时回复,建议去 segmentfault平台, 也可以来我的直播间来提问。
    关于技术问题或者有啥不懂的都可以留言, 我会定期回复答疑, 也可以来 我的直播间 提问, 推荐最新仓库 前端知识体系, 感謝支持!