可枚举属性

  • Post author:
  • Post category:其他


一般方法:(能/不能)能获取不可枚举属性,(能/不能)能获取symbol属性、(能/不能)获取原型链属性

<!DOCTYPE html>
<html lang="zh">
<script>
    class Person {
        constructor(name, age) {
            this.name = name;
            this.age = age;
        }
        /**
         * 注意ES6的class语法
         * 方法都是不可枚举的
         * 等价于
         Object.defineProperty(Person.prototype, 'toString', {
              configurable:true,
              writable:true,
              value() {
                    return '[object Person]';
              },
         });
         */
        toString() {
            return '[object Person]';
        }
    }
    console.log(Object.getOwnPropertyDescriptor(Person.prototype, 'toString')); // configurable:true,writable:true,enumerable:false,
    Person.prototype.toString2 = Person.prototype.toString;
    const person = new Person('小白', 18);
    Object.defineProperty(person, 'brief', {
        value: 'hello',
    });
    const hiSymbol = Symbol('hi');
    person[hiSymbol] = 'hi';
    /**
     * for...in...
     * 1、只能获取可枚举属性
     * 2、可以获取原型链上的属性
     * 3、不能获取Symbol属性
     */
    (function () {
        const properties = [];
        for (let i in person) {
            properties.push(i);
        }
        console.log(properties); //  ["name", "age", "toString2"] 原型链上的 toString2 也被遍历出来了
    })();
    /**
     * Object.keys()
     * 1、只能获取可枚举属性
     * 2、只获取自身属性,不获取原型链的属性
     * 3、不能获取Symbol属性
     */
    (function () {
        console.log(Object.keys(person)); // ["name", "age"] 
    })();


    // 其实还有个规律,一般带有own的方法,都是获取自身的属性,不获取原型链上的属性
    /**
     * Object.getOwnPropertyNames()
     * 1、获取所有属性,包括不可枚举属性
     * 2、不获取原型链上的属性
     * 3、不能获取Symbol属性
     */
    (function () {
        console.log(Object.getOwnPropertyNames(person)); // ["name", "age", "brief"] 可以看到brief这个属性也出来了
    })();
    /**
     * Object.getOwnPropertyDescriptor()、Object.getOwnPropertyDescriptors()
     * 1、获取所有属性,包括不可枚举属性
     * 2、不获取原型链上的属性
     * 3、不能获取Symbol属性(但是这里有点意思)
     */
    (function () {
        console.log(Object.getOwnPropertyDescriptor(person, 'brief')); // {value: "hello", writable: false, enumerable: false, configurable: false} 可以获取不可枚举属性brief
        const propertyDescriptors = Object.getOwnPropertyDescriptors(person);
        console.log(Object.keys(propertyDescriptors)); // ["name", "age", "brief"] 可以获取不可枚举属性brief
        /* 关于Symbol */
        console.log(propertyDescriptors); // 可以在控制台看到,propertyDescriptors对象里有 Symbol(hi) 属性,但是只能看看,并不能访问到
    })();
    /**
     * 关于symbol属性,总结
     * 目前只能使用 Object.getOwnPropertySymbols()获取所以symbol属性
     * Object.getOwnPropertySymbols() 类似与 Object.getOwnPropertyNames(),都是返回数组,我感觉改名为 getOwnPropertySymbolNames 更合适...
     * 
     * 不能在 for...in...、for...of...、Object.keys()、Object.getOwnPropertyNames()中获取
     * 因为Object.getOwnPropertyDescriptor()、Object.getOwnPropertyDescriptors()这两个方法并不是获取属性的,它们的使用方式应该是,先获取属性名,然后才调用...
     */
    (function () {
        const symbolProperties = Object.getOwnPropertySymbols(person);
        console.log(symbolProperties);
        symbolProperties.forEach(item => {
            // 这时候使用 Object.getOwnPropertyDescriptor()
            console.log(Object.getOwnPropertyDescriptor(person, item)); // {value: "hi", writable: true, enumerable: true, configurable: true}
        });
    })();


    // 其他
    /**
     * Object.assign()
     * 1、只复制可枚举属性
     * 2、只复制自身属性,不复制原型链的属性
     * 3、可以复制symbol属性
     */
    (function () {
        const clone = Object.assign({}, person);;
        console.log(clone === person); // false
        console.log(clone.toString2); // undefined 没有复制person.prototype.toString2
        console.log(clone.brief); // undefined 没有复制不可枚举属性
        console.log(clone[hiSymbol]); // 'hi' 复制了symbol属性
    })();
</script>

</html>



版权声明:本文为qq_39571197原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。