• es6总结


    es6阮一峰

    基本数据类型

    1. 数字、字符串、布尔、symbol、bigInt、undefined、null
    2. object

    Set用法

    类似于数组,但是成员的值都是唯一的,没有重复的值。
    
    只有NaN=== 不一样  其他都是一样做比较的
    var set = new Set(NaN)
    set.add(NaN);
    set // Set {NaN}
    set.size //1
    set.delete() //删除某个值 返回值表示是否删除成功
    set.has() // 返回布尔值 表示是否有某个值
    set.clear() // 清空所有项 没有返回值
    [...new Set('ababbc')] // ['a','b','c']
    
    也可以使用Array.from解开Set实例
    let set = new Set(['red', 'green', 'blue']);
    for (let item of set.keys()) {  console.log(item);}// red  green blue
    for (let item of set.values()) {  console.log(item);}// red  green blue
    for (let item of set.entries()) {  console.log(item);}// ["red", "red"]  ["green", "green"]  ["blue", "blue"]
    
    
    Set.prototype[Symbol.iterator] === Set.prototype.values // true  所以可以用for...of循环得到每一项值
    for (let i of set) {
      console.log(i);//获取set内部的每一项
    }
    
    set.forEach((value, key) => console.log(key + ' : ' + value)) // key和value  值一样
    
    可以把Set实例看做数组 进行map和filter操作 和数组用法类似
    
    
    
    const p = [item,item,...] // item必须是对象也可以是数组 否则报错
    const set = new WeakSet(b);
    set.add(value)
    set.delete(value)
    set.has(value) 
    
    set.size // undefined  没有size和forEach
    set.forEach // undefined
    
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39

    Map用法

    DOM 节点作为对象data的键,但是由于对象只接受字符串作为键名,所以element被自动转为字符串[object HTMLDivElement]。

    const data = {};
    const element = document.getElementById('myDiv');
    data[element] = 'metadata';
    data['[object HTMLDivElement]'] // "metadata"
    
    • 1
    • 2
    • 3
    • 4

    为了解决这个问题,ES6 提供了 Map 数据结构。它类似于对象

    var obj = {}
    var map = new Map([
        [obj, '111'],
        ['key2', '222']
    ]);
    map.get(obj) //111
    //有这些方法  has get set delete    clear size forEach keys values entries
    for...map.keys() =>  第一项是obj     也可以使用 [...map.keys()]
    for...map.values() =>  第一项是"111"     也可以使用 [...map.values()]
    for...map.entries() =>  第一项是[obj,'111']   也可以使用 [...map.entries()]
    for...map.forEach(value, key) =>  第一项  value为'111'  key为obj    
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11

    WeakMap只接受对象作为键名
    WeakMap 里面对element的引用就是弱引用,不会被计入垃圾回收机制。

    只有这些方法 has get set delete
    const wm1 = new WeakMap();
    
    • 1
    • 2

    Promise

     //请求某个table数据
        function requestTableList(){
            var p = new Promise((resolve, reject) => {
                   //去后台请求数据,这里可以是ajax,可以是axios,可以是fetch 
                    resolve(res);
            });
            return p;
        }
      //延时函数,用于给请求计时 10s
          function timeout(){
              var p = new Promise((resolve, reject) => {
                  setTimeout(() => {
                      reject('请求超时');
                  }, 10000);
              });
              return p;
          }
          Promise.race([requestTableList(), timeout()]).then((data) =>{
            //进行成功回调处理
            console.log(data);
          }).catch((err) => {
            // 失败回调处理
              console.log(err);
          });
    
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    function promiseClick1(){
    		let p = new Promise(function(resolve, reject){
    			setTimeout(function(){
    				var num = Math.ceil(Math.random()*20); //生成1-10的随机数
    				console.log('随机数生成的值:',num)
    				if(num<=10){
    					resolve(num);
    				}
    				else{
    					reject('数字太于10了即将执行失败回调');
    				}
    			}, 2000);
    		   })
    		   return p
    	   }
    	   function promiseClick2(){
    		let p = new Promise(function(resolve, reject){
    			setTimeout(function(){
    				var num = Math.ceil(Math.random()*20); //生成1-10的随机数
    				console.log('随机数生成的值:',num)
    				if(num<=10){
    					resolve(num);
    				}
    				else{
    					reject('数字太于10了即将执行失败回调');
    				}
    			}, 2000);
    		   })
    		   return p
    	   }
    	   function promiseClick3(){
    		let p = new Promise(function(resolve, reject){
    			setTimeout(function(){
    				var num = Math.ceil(Math.random()*20); //生成1-10的随机数
    				console.log('随机数生成的值:',num)
    				if(num<=10){
    					resolve(num);
    				}
    				else{
    					reject('数字太于10了即将执行失败回调');
    				}
    			}, 2000);
    		   })
    		   return p
    	   }
     
    	Promise
    		.all([promiseClick3(), promiseClick2(), promiseClick1()])
    		.then(function(results){
    			console.log(results);
    		})
    
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42
    • 43
    • 44
    • 45
    • 46
    • 47
    • 48
    • 49
    • 50
    • 51
    • 52

    class继承

    父辈为超类  子辈为子类   子类继承超类 调用super其实是调用超类的构造函数方法
    class A {
        constructor(a) {
            this.a = a;
        }
    }
    class B extends A {
        constructor(a, b) {
            super(a);
            this.b = b;
        }
    }
    class C extends B {
        constructor(a, b, c) {
            super(a, b);
            this.c = c;
        }
    }
    console.log(new C(1, 2, 3))//C { a: 1, b: 2, c: 3 }
    
    
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21

    [外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-1K66PnzH-1656645685958)(https://p3-juejin.byteimg.com/tos-cn-i-k3u1fbpfcp/3eda935987e44040b5f12a095e093bb7~tplv-k3u1fbpfcp-zoom-1.image)]

    Promise并行和串行,以及await底层实现

    前提代码

    var query = function (value) {
        return new Promise(function (resolve, reject) {
            setTimeout(function () {
                resolve(value)
            }, value)
        })
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7

    并行 方式一 1秒后输出1000,再过1秒输出2000,再过1秒输出3000

    query(1000).then(v => {
        console.log(v)
    })
    query(2000).then(v => {
        console.log(v)
    })
    query(3000).then(v => {
        console.log(v)
    })
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9

    并行 方式二 三秒后输出 [1000, 2000, 3000]

    Promise.all([query(1000),query(2000),query(3000)]).then(v=>{
        console.log(v)
    })
    
    
    • 1
    • 2
    • 3
    • 4

    串行 方式一 输出为 1秒后输出1000,再过2秒输出2000,再过3秒输出3000

    query(1000).then(v => {
        console.log(v)
        return query(2000)
    }).then(v => {
        console.log(v)
        return query(3000)
    }).then(v => {
        console.log(v)
    })
    
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10

    串行 方式二 输出为 1秒后输出1000,再过2秒输出2000,再过3秒输出3000

    let itor = generator()
    itor.next().value.then(value => {
        itor.next(value).value.then(value => {
            itor.next(value).value.then(value => {
                itor.next(value)
            })
        })
    })
    
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9

    await底层实现

    const isPromise = function (v) {
        if (v !== null && /^(object|function)$/i.test(typeof v)) {
            let then;
            try {
                then = x.then
            } catch (err) {
                return false
            }
            if (typeof then === 'function') return true
        }
        return false
    }
    
    function AsyncFunction(generator, ...params) {
        return new Promise((resolve, reject) => {
            let itor = generator(...params);
            const next = v => {
                let {
                    value,
                    done
                } = itor.next(v)
                if (done) {
                    resolve(value)
                    return
                }
                if (!isPromise(value)) value = Promise.resolve(value)
                value.then(v => {
                    next(v)
                }).catch(reason => {
                    reject(reason)
                    itor.throw(reason)
                })
            }
            next()
        })
    }
    
    AsyncFunction(function* generator() {
        let value;
        y1 = yield query(1000)
        console.log(y1)
        y2 = yield query(2000)
        console.log(y2)
        y3 = yield query(3000)
        console.log(y3)
        return 'zanlan'
    }).then(v => {
        console.log('所有请求都成功', v)
    }).catch(reason => {
        console.log('某个请求失败', reason)
    })
    
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42
    • 43
    • 44
    • 45
    • 46
    • 47
    • 48
    • 49
    • 50
    • 51
    • 52

    一般函数实现

        /* 真实项目 基于async/awai可以直接实现*/
        /* 我们上面基于promise + generator + AsyncFunction函数,实现的就是async/await处理机制 */
        /* async/awai是promise + generator的语法糖 */
        (async function () {
            let value;
            try {
                value = await Promise.reject('xxx')
                console.log('第一个请求成功', value)
            } catch (err) {
                console.log(err)
            }
            value = await query(2000)
            console.log('第二个请求成功', value)
            value = await query(3000)
            console.log('第三个请求成功', value)
        })()
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16

    generator原理

    把一个函数当做普通函数执行,是否可以创造它这个类的一个实例?

    	jquery.fn()  // 工厂设计模式  实现  
    
    	function* fn() {  // generator 实现  ,itor 是fn的实例对象 fn内部代码没有执行
    	    console.log(this)
    	    return 10
    	}
    	let itor = fn()
    	console.log(itor)
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8

    输出 window,在输出 { value:10 , done:true }

    function* fn() {
        console.log(this)
        return 10
    }
    let itor = fn()
    console.log(itor.next())
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6

    输出 如下

    [外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-CghJhoeC-1656645685966)(https://p3-juejin.byteimg.com/tos-cn-i-k3u1fbpfcp/2fabd05724794427a96733e4f03229c2~tplv-k3u1fbpfcp-zoom-1.image)]

    function* generator() {
        console.log(1)
        yield 2
        console.log(3)
        yield 4
        console.log(5)
        yield 6
        console.log(7)
        return 8
    }
    let itor = generator()
    console.log(itor.next())
    console.log(itor.next())
    console.log(itor.next())
    console.log(itor.next())
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15

    输出 如下

    [外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-KdJYJRJQ-1656645685968)(https://p3-juejin.byteimg.com/tos-cn-i-k3u1fbpfcp/14d36e9a5602412f960b520747896c65~tplv-k3u1fbpfcp-zoom-1.image)]

    function* generator() {
        console.log(1)
        let y2 = yield 2
        console.log(y2)
        console.log(3)
        let y4 = yield 4
        console.log(y4)
        console.log(5)
        let y6 = yield 6
        console.log(y6)
        console.log(7)
        return 8
    }
    
    let itor = generator()
    console.log(itor.next('aa'))
    console.log(itor.next('bb'))
    console.log(itor.next('cc'))
    console.log(itor.next('dd'))
    
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20

    输出如下

    [外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-8zIlIQvg-1656645685970)(https://p3-juejin.byteimg.com/tos-cn-i-k3u1fbpfcp/491da2d576424606bc08c302903c3d14~tplv-k3u1fbpfcp-zoom-1.image)]

    function* generator1() {
        yield 2;
        yield 3;
        return 4
    }
    
    function* generator2() {
        yield 1;
        yield* generator1();
        yield 5;
        return 6;
    }
    
    let itor = generator2();
    console.log(itor.next())
    console.log(itor.next())
    console.log(itor.next())
    console.log(itor.next())
    console.log(itor.next())
    
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20

    Iterator 源码

    class Iterator {
        constructor(assemble) {
            let self = this;
            self.assemble = assemble;
            self.index = 0;
        }
        next() {
            let self = this;
            let assemble = self.assemble;
            if (self.index > assemble.length - 1) {
                return {
                    done: true,
                    value: undefined
                }
            }
            return {
                done: false,
                value: assemble[self.index++]
            }
        }
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21

    一般应用

    let itor = new Iterator([10, 20, 30, 40])
    console.log(itor.next())
    console.log(itor.next())
    console.log(itor.next())
    console.log(itor.next())
    console.log(itor.next())
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6

    下面代码可以使得一般对象使用for of 循环

    Object.prototype[Symbol.iterator] = function () {
        let self = this
        let keys = Object.keys(self).concat(Object.getOwnPropertySymbols(self))
        let index = 0
        return {
            next() {
                if (keys.length - 1 < index) {
                    return {
                        done: true,
                        value: undefined
                    }
                }
                return {
                    value: self[keys[index++]],
                    done: false
                }
            }
        }
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19

    针对类数组,则直接借用真数组自带的Symbol.iterator函数

    var obj = {
        0: 'a',
        1: 'b',
        length: 2
    }
    obj[Symbol.iterator] = Array.prototype[Symbol.iterator]
    
    for (var value of obj) {
        console.log(value)
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10

    jquery是类数组,下面是jquery源码实现

    jQuery.fn[Symbol.iterator] = [][Symbol.iterator];
    
    • 1

    async && await 面试题

    已知两个函数,分别提问,得出结果

        var f1 = function f1() {
            console.log(1)
            return new Promise(resolve => {
                setTimeout(() => {
                    resolve(6)
                    console.log(5)
                }, 2000);
            })
        }
        var f2 = function f2() {
            console.log(2)
            return new Promise(resolve => {
                setTimeout(() => {
                    resolve(4)
                    console.log(3)
                }, 1000);
            })
        }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18

    问题1 输出结果为 :1 5 6 2 3 4

       	var f = async function () {
            console.log(await f1())
            console.log(await f2())
        }
        f()
    
    • 1
    • 2
    • 3
    • 4
    • 5

    问题2 输出结果为 :1 2 3 5

        Promise.all([
            f1(),
            f2(),
        ])
    
    • 1
    • 2
    • 3
    • 4

    问题3 输出结果为 :1 2 3 4 5 6

        Promise.all([
            (async () => { console.log(await f1()) })(),
            (async () => { console.log(await f2()) })(),
        ])
    
    • 1
    • 2
    • 3
    • 4

    class继承

    父辈为超类  子辈为子类   子类继承超类 调用super其实是调用超类的构造函数方法
    class A {
        constructor(a) {
            this.a = a;
        }
    }
    class B extends A {
        constructor(a, b) {
            super(a);
            this.b = b;
        }
    }
    class C extends B {
        constructor(a, b, c) {
            super(a, b);
            this.c = c;
        }
    }
    console.log(new C(1, 2, 3))//C { a: 1, b: 2, c: 3 }
    
    
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21

    ES5和ES6的模块化导入导出

    //不接收对象 
    require:require('s.css'); //(es5)
    improt  's.css' //(es6)
    
    //接收对象
    var o = require('s.js'); //es(5)
    import o form s.js    //(es6)
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    导出一个模块对象(es5):
    module.exports={
        add:add,
        sub:sub
    }
    导出一个模块对象(es6):
    module.exports={
        add,
        sub
    }
    注意:这种写法属性名和属性值变量是同一个,否则要分开写
    module.exprots={
        addFn:add,
        sub
    }  
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    //es5
    module.exports={
        addFun:function(x,y){
            return x+y;
        }
    }
    //es6
    module.exports={
        addFun(x,y){
            return x+y;
        }
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    calc.js中有两个函数:
    function add(){}
    function sub(){}
    //写法一
    es5写法:
    module.exports.add = add;
    module.exports.sub = sub;
    使用:
    var calc = require('./calc.js');
    es6写法:
    exprot function add(){}
    exprot function sub(){}
    
    //写法二
    es5:
    module.exports = {add:add,sub:sub};
    es6:
    exprot default{
        add,sub
    }
     //表示取得calc.js中所有暴露出来的对象(es6)
    import calc from './calc.js'
    
    //只获取到calc.js中的add方法(按需获取)
    import {add} from './calc.js'
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    1、如果模块中是使用 export default {} 方式导出的对象
        只能通过  import 对象名称 from '模块路径'
        不能通过  import {对象名称} from '模块路径'
    
    2、如果就想要import {对象名称} from '模块路径'通过这种方式来按需导入对象中的某个属性
        那么应该使用 export 跟着要导出的对象或者方法名称
        export function add(){}
        export function substrct(){}
    
        那么就可以使用:
        import {add,substrct} from '模块路径'
        只需要直接使用 add()方法即可
        注意这里不能直接使用:  import cacl from '模块路径' 这种方式导入,会报错
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13

    class继承

    ```typescript
    父辈为超类  子辈为子类   子类继承超类 调用super其实是调用超类的构造函数方法
    class A {
        constructor(a) {
            this.a = a;
        }
    }
    class B extends A {
        constructor(a, b) {
            super(a);
            this.b = b;
        }
    }
    class C extends B {
        constructor(a, b, c) {
            super(a, b);
            this.c = c;
        }
    }
    console.log(new C(1, 2, 3))//C { a: 1, b: 2, c: 3 }
    
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21

    ES5 和 ES6 及Object用到过的方法

    es6的prototype不可以枚举

    class Person {
        constructor(x, y) {}
        toString() {}
    }
    console.log(Object.keys(Person.prototype)); //[]
    console.log(Object.getOwnPropertyNames(Person.prototype)); //["constructor", "toString"]
    
    function Person1() {}
    Person1.prototype.toString = function () {};
    console.log(Object.keys(Person1.prototype)); //["toString"]
    console.log(Object.getOwnPropertyNames(Person1.prototype)); //["constructor", "toString"]
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11

    自动添加constructor函数

    
    class Person {
        
    }
    等 价
    class Person {
        constructor(x, y) {}
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8

    constructor默认return 实例化对象this,但可以自定义
    class函数必须要new才能调用,es5不需要new也可以调用

    class Foo{
    	constructor(){
    		return Object.create(null);
    	}
    }
    new Foo() instanceof Foo //false
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6

    修改一个实例__proto__的方法,其他的实例也会牵连

    class Person {
        constructor(x, y) {
            this.x = x;
            this.y = y;
        }
        toString() {
            return this.x + '--' + this.y;
        }
    }
    let p = new Person(1, 2);
    
    console.log(p.hasOwnProperty('x')); //true
    console.log(p.hasOwnProperty('y')); //true
    console.log(p.hasOwnProperty('constructor')); //false
    console.log(p.hasOwnProperty('toString')); //false
    console.log(p.__proto__.hasOwnProperty('constructor')); //true
    console.log(p.__proto__.hasOwnProperty('toString')); //true
    
    let p1 = new Person(2, 3);
    p1.__proto__.toString = function () {
        return 'what fuck?';
    };
    let p2 = new Person(3, 4);
    console.log(p1.toString());//what fuck?
    console.log(p2.toString());//what fuck?
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25

    class可以自定义变量,Person只对构造函数内部有效,而clafun则用于外部调用

    let clafun = class Person {
        constructor(x, y) {
            this.x = x;
        }
        toString() {
            return this.x + '--' + Person.name;
        }
    };
    let p = new clafun(1);
    console.log(p.toString());//1--Person
    // var p1 = new Person(1);//Person is not defined
    
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    //如果没有用到clafun则可以简写为
    //如果没有用到clafun则可以简写为
    let p = new class Person {
        constructor(x, y) {
            this.x = x;
        }
        toString() {
            return this.x + '--' + Person.name;
        }
    }(1);
    console.log(p.toString());//1--Person
    // var p1 = new Person(1);//Person is not defined
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12

    class不存在变量提升,let不会变量提升,假设class存在变量提升,则为报错Foo 是undefined ,而实际上没有报错,说明class不会变量提升

    {
        let Foo=class {};
        class Bar extends Foo{
            
        }
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6

    this的指向问题,默认指向实例化对象,但是通过解构出来的方法,则函数内部的this是指向环境的因为es6默认是用严格模式的,所以是指向undefined,解决方法有三种

    1. bind改变this的指向
    2. 箭头函数
    3. proxy
    console.log(this); //Window {postMessage: ƒ, blur: ƒ, focus: ƒ, close: ƒ, parent: Window, …}
    class Person {
        constructor() {
            // this.fun1 = this.fun1.bind(this); //方法一
            // this.fun1 = () => {
            //     //方法二
            //     return this.fun2() + '-------------';
            // };
        }
        fun1() {
            console.log(this); //实例化调用则指向实例化  解构出来则指向环境,es6默认是严格模式,所以为undefined
            return this.fun2() + '--------';
        }
        fun2() {
            return 'what';
        }
    }
    
    let p = new Person();
    console.log(p.fun1()); //what--------
    const { fun1 } = p;
    console.log(fun1()); //fun1内部的this指向运行的环境   Cannot read property 'fun2' of undefined
    
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23

    proxy添加this

    function selfish(target) {
        const cache = new WeakMap();
        const handler = {
            get(target, key) {
                const value = Reflect.get(target, key);
                if (typeof value !== 'function') {
                    return value;
                }
                if (!cache.has(value)) {
                    cache.set(value, value.bind(target));
                }
                return cache.get(value);
            },
        };
        const proxy = new Proxy(target, handler);
        return proxy;
    }
    const p = selfish(new Person());
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18

    class继承static方法 es6只有静态方法没有静态属性

    class Foo {
        static fun1() {
            return '111';
        }
    }
    class Bar extends Foo {
        static fun2() {
            return super.fun1() + '222';
        }
    }
    console.log(Bar.fun1());//111
    console.log(Bar.fun2());//111222
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12

    class声明实例化属性和方法

    class Foo {
       constructor() {
            this.state1 = {};
        }
        state = { name: 1 };
        fun1() {
            return 11111;
        }
    }
    console.log(new Foo().hasOwnProperty('state1')); //true
    console.log(new Foo().hasOwnProperty('state')); //true
    console.log(new Foo().__proto__.hasOwnProperty('fun1')); //true
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12

    ES5和ES6的get和set方法的比较

    ES5

    var obj = {};
    Object.defineProperty(obj, 'name', {
        get: function () {
            console.log('正在访问name');
            return this._name;
        },
        set: function (val) {
            console.log('正在修改name');
            this._name = val;
        },
    });
    
    obj.name = 10;
    console.log(obj);
    console.log(obj.name);
    // 正在修改name
    // { _name: 10 }
    // 正在访问name
    // 10
    
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20

    ES6

    class Person{
    	constructor(){
    		this._name = '';
    	}
    	get name(){
    		console.log("正在访问name属性");
    		return `我的名字是${this._name}`;
    	}
    	set name(val){
    		console.log("正在修改name属性");
    		this._name = val;
    	}
    }
    
    const person = new Person();
    person.name = "德玛-压缩";
    console.log(person.name); //先访问set 再访问get
    
    // 正在修改name
    // 正在访问name
    // 我的名字是德玛-压缩
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21

    es7

    在这里插入图片描述

    let a = 7 ** 12
    let b = 2 ** 7
    console.log(a === Math.pow(7,12)) // true    7的12次方
    console.log(b === Math.pow(2,7)) 
    
    • 1
    • 2
    • 3
    • 4
  • 相关阅读:
    AutoCAD2014第一章 快速入门
    定时器的编码器接口
    sql语句 (增删改查)
    GEE——利用map函数获取指定时间范围内年份月份日期内的所有影像并求降水平均值
    史上最难618,TCL夺得电视行业京东和天猫份额双第一
    .NET中Invoke和BeginInvoke
    UI设计需要学会哪些软件?优漫动游
    代码随想录算法训练营第六十天 | 单调栈 part 1 | 739. 每日温度、496.下一个更大元素 I
    java计算机毕业设计商店管理系统源码+数据库+系统+lw文档+mybatis+运行部署
    高版本tensorflow部分模块缺失
  • 原文地址:https://blog.csdn.net/formylovetm/article/details/125555393