Structure-study-es6(Reflect、Symbol)

261 阅读2分钟

Reflect

对象上的一些方法,在reflect上实现了一遍

1、get / set

    const obj = {};
    Reflect.set(obj,'name','xx')
    Reflect.get(obj,'name')

2、has

    console.log('a' in {a:1})
    console.log(Reflect.has({a:1},'a'))

3、defineProperty

    const obj = {a:1}
    Reflect.defineProperty(obj,'a',{
        value:100
    })

4、getOwnPropertyDescriptor

    const obj = {a:1};
    console.log(Reflect.getOwnPropertyDescriptor(obj,'a'));

5、ownKeys

获取keys 包括symbol

    let obj = {
        a:1,
        [Symbol()]:1
    };
    console.log(Object.getOwnPropertyNames(obj)); // ["a"]
    console.log(Object.getOwnPropertySymbols(obj)); // [Symbol()]
    console.log(Reflect.ownKeys(obj)) // ["a", Symbol()]

6、原型相关

    Reflect.setPrototypeOf 
    Reflect.getPrototypeOf

7、函数的apply方法

    const fn = function(a,b){ // apply 支持多个参数传参
        console.log(this,a,b);
    }
    // Function.prototype.apply.call(fn,1,[2,3]);
    Reflect.apply(fn,1,[2,3]); // 用原型上的apply方法

8、construct

   class XXX{
        constructor(name){
            this.name = name
        }
    }
    let xxx =  Reflect.construct(XXX,['xx']);
    console.log(xxx);  // XXX {name: "xx"}

9、其他

   Reflect.deleteProperty // delete obj.a

   let obj = {}; // 扩展不能添加属性
   Reflect.preventExtensions(obj) 
   obj.a = 1
   console.log(Reflect.isExtensible(obj));

Symbol

创建独一无二的值 用作常量

1、Symbol

    const s1 = Symbol('xx')
    const s2 = Symbol('xx')
    console.log(s1 === s2) // false

2、Symbol.for / Symbol.keyFor

如果symbol已经有值了 就将这个值返回即可 没有就创建一个

    let s1 = Symbol.for('xx')
    let s2 = Symbol.for('xx')
    console.log(s1 === s2) // true
    console.log(Symbol.keyFor(s2)) // xx

元编程

可以改变js源代码的功能 改变js原有的功能

3、Symbol.hasInstance

可以判断某个人是否是谁的实例

    let o = {
        name:1
    }

    let obj = {
        [Symbol.hasInstance](){
            return "name" in o
        }
    }
    console.log(o instanceof obj) // true

4、Symbol.iterator

类似数组迭代的时候 默认就会调用此方法

5、Symbol.toPrimitive

   let obj = {
    [Symbol.toPrimitive](value) {
        console.log(value); // Number
        return "hello";
    },
    a: 1
    }; 
    console.log(obj * 1); // NaN

6、Symbol.toStringTag

   const obj = {
    get [Symbol.toStringTag]() {
        return "123";
    }
    };
    // Object.prototype.toString
    console.log(obj.toString()); // [object 123]

7、Symbol.species

   class MyArray extends Array {
    constructor(...args) {
        super(...args);
    }
    static get [Symbol.species]() {
        return Array; // 控制衍生对象的类的构造函数
    }
    }
    let myarr = new MyArray(1, 2, 3);
    let newArr = myarr.map(item => item * 2); // 衍生出来的结果是当前的实例
    console.log(newArr instanceof MyArray);  // false
    console.log(newArr instanceof Array)  // true

8、Symbol.unscopables

指用于指定对象值,其对象自身和继承的从关联对象的 with 环境绑定中排除的属性名称 我们可以声明一些属性 不在with中使用

    console.log(Array.prototype[Symbol.unscopables])
    with (Array.prototype) {
        fill(1,2,3)
    }

    class My{
        eat(){}
        get [Symbol.unscopables](){
            return {eat:true};
        }
    }
    with(My.prototype){
        console.log(eat);
    }

9、Symbol.isConcatSpreadable

属性等于一个布尔值。表示该对象使用Array.prototype.concat()时,是否可以展开

   let arr = [1,2,3];
    arr[Symbol.isConcatSpreadable] = false;
    console.log(arr.concat(4,5,6));  // [[1,2,3],4,5,6]

es5-class

es5没有类的概念 是用构造函数模拟类 各种继承方式 new Object.create的原理等