ES6 基础语法

61 阅读3分钟

ES6 基础语法学习

数组扩展

{
    let arr = Array.of(1,2,3);
    console.log('arry=',arr);
    
    let empty =  Array.of();
    console.log(empty)
}

{
    let arr =  Array.from([1,2,3],function (item){
            return item *2;
        })
        console.log(arr);
}


{
    console.log('fill-8',[1,'a',undefined].fill(8));
    console.log('fill,pos',['a','b','c'].fill(7,0,2));
}

{
    for(let index of [1,2,3,].keys()){
        console.log('keys',index)
    }


    for(let index of [1,2,3,].values()){
        console.log('values',index)
    }

    for(let [index,value] of [1,2,3,4].entries()){
        console.log(index +": " + value)
    }
}


{
        console.log([1,2,3,4].find(function (item){
                return item >2 ;
        }))
        console.log([1,2,3,4].findIndex(function (item){
            return item >2 ;
        }))
}

{
    console.log('num',[1,2,3,4].includes(1));
    console.log('NaN',[1,2,3,NaN].includes(NaN));

}

解构

{
    let a,b,c ;
    // 解构 赋值
    // [a,b] = [1,2]
    //es5 原来赋值
    a = 1 ,b = 2
    console.log(a,b)
}


{
    let a,b,c;
    // 扩展运算符   数组解构
    [a,b,...c] = [1,2,3,4,5,6]
    console.log(a,b,c)
}

// 对象 解构
{
    let a,b;
    ({a,b} = {a:1,b:2} )
    console.log(a,b)
}


// 解构赋值 默认值
{
    let a,b,c ;
    // 解构 赋值
    [a,b,c=3] = [1,2,5]
    console.log(a,b,c)
}

//数据交换
{
    let a = 1,b = 2;
    [a,b] = [b,a]
    console.log(a,b)
}

{
    function f(){
        return [1,2];
    }

    [a,b] = f();
    console.log(a,b)
}

{
    function f(){
        return [1,2,3,4,5];
    }

    [a,,,b] = f();
    console.log(a,b)
}

{
    function f(){
        return [1,2,3,4,5,6]
    }

    [a,b,...c] = f();  
        
    console.log(a,b,c)
}

// 对象解构   
{
    let obj = {a:123,b:321}
    let {b,a} = obj
    console.log(b,a)
}


//json 解构

{
    let dataJson = {
        title: 'abc',
        data: [{
            dataTitle: 'dataTitle',
            name: 'dataName'
        }]
    }
    let {title:newTitle,data: [{dataTitle:title2}]} = dataJson;
    console.log(newTitle,title2)
}                               

对象扩展

{
    console.log('字符串',Object.is('abc','abc'),'abc' === 'abc')
    console.log('拷贝',Object.assign({a:1},{b:'b'}));

    let test = { key:123, o:466};
    for( let [k,v] of Object.entries(test)){
        console.log(k,v)
    }
}

//扩展运算符
{
    let {a,b,...c} = {a:'test',b:'bbb',c:'ddd',e:'eee'}
    console.log(a,b,c)
}

函数扩展

{
    function test(x,y = 'world'){
        console.log(x,y)
    }
    test('hello');
}

{
    let x =  'test';
    function test2(x,y=x){
        console.log('作用域',x,y)
    }
    test2();
    test2('kill')
}

{
    // 转换成数组
    function test3(...args){
        for(let v of args ){
            console.log('rest',v)
        }
    }
    test3(1,2,3,4);
}


{
    // 扩展运算符
    console.log(...[1,2,3,4])
}


// 箭头函数
{
    let arrow = v => v*2;
    let arrow2 = () => 5;
    let a = arrow(3);
    console.log(a)
    console.log(arrow2());
}

// 伪调用 
{
    function tail(x){
        console.log('tail',x);
    }

    function fx(x){
        return tail(x);
    }
    fx(123);
}

类与对象

    // 类的概念
// 基本定义和生成实例 
{
    class Parent{
        constructor(name='mukewang'){
            this.name = name;
        }
    }
    let v_parent = new Parent();
    console.log(v_parent)
}

// 继承 
{
    class Parent{
        constructor(name='mukewang'){
            this.name = name;
        }
    }
   

    class Child extends Parent {
        constructor(name='child'){
            super(name);
            this.type= '123';
        }
    }
    console.log(new Child());
}

{
    class Parent{
        constructor(name='mukewang'){
            this.name = name;
        }

        get getName(){
            return 'mk' + this.name;
        }

        set setName(value){
            this.name = value;
        }
    }

    let v = new Parent();
    console.log(v.getName);
    v.setName = '123';
    console.log(v.getName);


}

// 静态方法
{
    class Parent{
        constructor(name='mukewang'){
            this.name = name;
        }

        static tell(){
            console.log('tell');
        }
    }

    console.log(Parent.tell)
    
}
// 静态属性
{
    class Parent{
        constructor(name='mukewang'){
            this.name = name;
        }

        static tell(){
            console.log('tell');
        }

    }
    Parent.type = 'test';
    console.log('静态属性:',Parent.type)
}

generator

    // 基本概念

{
    //generator 的基本定义 
    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())

}

// generator 函数的应用 
{
    let obj ={};
    obj[Symbol.iterator]=function*(){
        yield 1;
        yield 2;
        yield 3;
    };

    for(let i of obj){
        console.log(i)
    }
}

{
    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.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();
//     },false)
// }

//next 函数的用法


//yield*的语法

// generator 实现长沦陷
{
    //长轮询
    let ajax = function*(){
        yield new Promise(function(resoleve,reject){
            setTimeout(function(){
                resoleve({code:1})
            },200)
        })
    }

    let pull = function(){
        let generator = ajax();
        let step = generator.next();
        step.value.then(function(d){
            if(d.code != 0 ){   //改为1
                setTimeout(function(){
                    console.log('wait');
                    pull();
                },1000)
            }else{
                console.log(d)
            }
        })
    }
    pull();
}

Iterator

// Iterator 和 for of 循环
 {
    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)
    }

 }

js-call-apply-bind 用法

/**
 * javascript 中 call()、apply()、bind() 的用法 
 * 
 */
//call 方法使用一个指定的this值和单独给出一个或多个参数来调用一个函数
/**
 *  语法
 * thisArg: 可选,在function 函数运行时使用的this值
 * arg1,arg2 可选:指定的参数列表
 * function.call(thisArg,arg1,arg2)
 */
// 示例
let person1 = {
    firstName: 'zhang',
    lastName: 'fan',
    fullName: function(arg1,arg2){
        return this.firstName + " " + this.lastName + " " + arg1 + " " + arg2;
    }
}

let person2 = {
    firstName: 'tom',
    lastName: 'join'
}

let result = person1.fullName.call(person1,'a','b');
console.log(result)

/**
 * apply 
 * apply() 方法调用一个具有给定this值的函数,以及以一个数组的形式提供的参数。
 * call()接受一个参数列表,而apply() 接受一个参数的单数组
 *
 */

// 语法
/**
 * //thisArg: 在func 函数运行时 使用this 值
 * argsArray: 可选,一个数组或者类数组对象,其中的数组元素将作为单独的参数传给func函数。
 * apply(thisArg,argsArray)
 */
{
    let person1 = {
        firstName: 'zhang',
        lastName: 'fan',
        fullName: function(args){
            return this.firstName + " " + this.lastName + " " + args[0] + " " + args[1]; 
        }
    }

    let person2 = {
        firstName: 'tom',
        lastName: 'join'
    }

    let result = person1.fullName.apply(person2,['a','b']);
    console.log(result)
}

//bind
{
    let  person1 = {
        firstName: 'zhang',
        lastName: 'fan',
        fullName:function(arg1,arg2){
            return this.firstName + this.lastName + arg1 + arg2;
        },
        getFullName:function(args){
            return this.firstName + this.lastName + args[0] + args[1];
        }
    };
    let person2 = {
        firstName: 'tom',
        lastName: 'liming'
    }

    let result1 = person1.fullName.bind(person2,'a','b')()
    let result2 = person1.getFullName.bind(person2,['a','b'])()
    console.log(result1)
    console.log(result2)

}

{
   console.log(Math.max.apply(null,[1,2,3]))
   console.log(Math.max.apply(" ",[1,2,3]))
   console.log(Math.max.apply(0,[1,2,3]))
}

{
    (function(){
        var x='hello';
        console.log(x)
    })();
}

{
    const x = (x,y) => x*y;
    console.log( x(2,3));

    const y = (x,y) => {return x*y};
    console.log(y(3,4))
}

{
    function findMax(){
        var max = -Infinity;
        
        for(var i=0;i<arguments.length;i++){
            if(arguments[i]>0){
                max = arguments[i];
            }
            return max;
        }
    }
    console.log(findMax(99,11,33))
}

{
    function sumAll(){
        let i,sum = 0;
        for(i=0;i<arguments.length;i++){
            sum += arguments[i];
        }
        return sum;
    }
    console.log(sumAll(1,2,3,4))
  
}

{
    var add = (function(){
        var count = 0;
        return function (){
            return count +=1;
        }
    })();

    console.log(add());
    console.log(add());

}

map-set 与数组对象的比较

// 数据结构
// Map 与Array 的对比

{
    let map = new Map();
    let array  = [];
    // 增
    map.set('t',1);
    array.push({t:1})
    console.log('map-array',map,array)

    // 查
    let map_exist = map.has('t');

    let array_exist = array.find(item=>item.t)
    console.log(map_exist,array_exist)

    // 改
    map.set('t',2);
    array.forEach(v=> v.t ? v.t = 2 : '');
    console.log(map,array)


    //删除
    map.delete('t');
    
    let index = array.findIndex(v=>v.t)
    array.splice(index);
    console.log(map,array)

}
// Set 与 Array 的对比
{
    let set = new Set();
    let array = [];
    // 增
    set.add({'t':1});
    array.push({'t':1});
    console.log('set-array',set,array)

    // 查
    let set_exist = set.has('t');
    let array_exist = array.find(v=>v.t);
    console.log(set_exist,array_exist);

    // 改
    set.forEach(i=> i.t ? i.t = 2 : '');
    array.forEach(i => i.t ? i.t = 2 : '');
    console.log(set,array)

    //删
     set.forEach(v=>v.t ? set.delete(v):"");
     let index =  array.findIndex(v=>v.t);
     array.splice(index);
     console.log(set,array)
}


// Map 与 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.log('map->set->obj',map,set,obj)

    console.log({
        map_exist: map.has('t'),
        set_exist: set.has(item),
        obj_exist: 't' in obj
    })

    // 改
    map.set('t',2);
    // set 引用类型,直接修改 引用值
    item.t = 2;
    obj['t'] = 2;
    console.log(map,set,obj)

    //删
     map.delete('t');
     set.delete(item);
     delete obj['t']
     console.log(map,set,obj)
      
}

// set 与 Object 对比
{

}

Promise 用法

//Promise
{
    // 基本定义
    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 (resole,reject){
            setTimeout(function(){
                resole();
            },1000)
        })
    }

    ajax().then(function (){
        console.log('promise','timeout2')
    })
}

{
    let ajax = function(){
        console.log('执行3')
        return new Promise(function (resole,reject){
            setTimeout(function(){
                resole();
            },1000)
        })
    }
    ajax()
     .then(function(){
        return new Promise(function(resole,reject){
            setTimeout(function(){
                resole();
            },2000)
        })
    }).then(function(){
        console.log('timeout3')
    })
}

{
    //所有图片加载完在添加到页面
    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(imags){
        imags.forEach(img=>{
            document.body.appendChild(img);
        })
    }

    Promise.all([
        loadImg('1.jpg'),
        loadImg('2.jpg')
    ]).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.createComment('p');
        p.appendChild(img);
        document.body.appendChild(p)
    }

    // 有一个改变,就会显示出来
    Promise.race([
        loadImg('1.jpg'),
        loadImg('2.jpg')
    ]).then(showImgs);
}

Proxy 和 Reflect 用法

//Proxy 和 Reflect 的概念

{
    let  obj  = {
        name: 'aa',
        title: '标题',
        _r: '_r',
        time: '2022-09-16'
    }
 
    // 代理对象, Proxy  新声 一个对象
    let monitor = new Proxy(obj,{
        // 拦截对象属性的读取 
        get(target,key){
            return target[key].replace('2022','2023');
        },
        // 拦截对象设置属性
        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(monitor.time);
    monitor.time = '2024';
    console.log(monitor.time)
    monitor.name = 'test';
    console.log(monitor)
    console.log('has','name' in monitor)
    console.log('has','time' in monitor)

    delete monitor.time;
    console.log('delete',monitor)
    delete monitor._r;
    console.log('delete',monitor)


    console.log('ownKeys',Object.keys(monitor))
}


//Proxy 和 Reflect 的适用场景
{

    let  obj  = {
        name: 'aa',
        title: '标题',
        _r: '_r',
        time: '2022-09-16'
    }

    console.log('reflect get =>',Reflect.get(obj,'time'))
    Reflect.set(obj,'name','test');
    console.log(obj)
    console.log(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 personValidator = {
        name(val){
            return typeof val === 'string'
        },
        age(val){
            return typeof val === 'number' && val > 18;
        },
        mobile(val){
            return typeof val === 'number' && val.length == 11;
        }
    }

    class Person{
        constructor(name,age){
            this.name = name;
            this.age = age;
            this.mobile = 12345678912;
            return validator(this,personValidator);
        }
    }

    const person = new Person(1,1);
    // person.name = 2;    // Error: 不能设置name 到 2
    person.mobile = 12345678912;
    console.log(person)
}

set-map 数据结构

// Set 用法  WeakSet的用法  Map的用法   WeakMap 的用法
{
    // set 增加 用 add ,获取长度使用size
    let list = new Set();
    list.add(3);
    list.add(5);
    console.log(list.size)
}

{
    let arr = [1,2,3,4];
    let list = new Set(arr);
    console.log(list.size)
}


{
    // 去重  
    let list = new Set();
    list.add(1)
    list.add(2)
    list.add(3)
    list.add(1)
    console.log(list.size)
}


{
    let arr = ['add','update','delete','has'];
    let list = new Set(arr);
    console.log(list.size)
    for(let [k,v] of list.entries()){
        console.log(k,v)
    }

    for(let k of list.keys()){
        console.log(k)
    }

    list.forEach(v=>console.log(v))
}


// weakList 只能添加对象
{
    let weakList = new WeakSet();
    let obj = {};
    weakList.add(obj);
    // weakList.add(1); // 报错
    console.log(weakList)
}


{
    let map = new Map();
    let arr = ['123'];
    map.set(arr,456);
    console.log(map,map.get(arr))
}


{
    let map = new Map([['a',123],['b',456]]);
    console.log(map) 
    console.log(map.size) 
    console.log(map.delete('a'),map)
}

{
    let weakmap = new WeakMap();
    let obj = {};
    weakmap.set(obj,123);
    console.log(weakmap.get(obj))
}

Symbol 作用概念

// Symbol 的概念
// Symbol 的作用
 
{
    // 声明 
    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
    }
     
    // 遍历拿不到 Symbol 声明的属性 
    for( let [k,v] of Object.entries(obj)){
        console.log(k,v)
    }

    // 拿到 Symbol 的属性
    Object.getOwnPropertySymbols(obj).forEach(v=>{
        console.log(obj[v])
    })

    Reflect.ownKeys(obj).forEach(v=>{
        console.log(obj[v])
    })
}