对象新解

64 阅读8分钟

对象新解

    //对象 会自动带有一个__proto__的属性,这个属性中包含了constructor构造函数,
       就是这个对象生成类名(Object),这可是算是最基本的原型链
   // Object.create(源对象) 根据源对象作为原型创建一个新的对象,这个新的对象的原型(原型链)就是源对象

   // 新对象将会继承源对象的所有属性和方法
         var o={a:1};
         // 对象中的原型结构叫做原型链
         //o是源对象也是o1的原型链(原型) 就在  [[Prototype]]Object 里面
         var o1=Object.create(o);

         o1.b=2;

        console.log(o1.a);
       //__proto__ 可以查找原型链
       console.log(o1.__proto__===o);true
   
    // 一个对象有两种属性,一种属性时对象的对象属性,一种属性是对象的原型链属性
    
    // 当获取对象的属性时,先查看是否有对象属性,如果没有向下查找其原型链上的属性,
       然后找到距离对象最近的这个属性和方法
    // 设置对象属性时,对象的属性无法通过对象方法,改变原形链的属性,原型链的属性,
    也无法通过对象方法改变对象属性。

         // 使用null作为原型创建,这个对象将不能使用所有对象方法和属性

         var o=Object.create(null);

         o.a=1;

      console.log(o.__proto__);//undefined 没有最根本的原型,不能使用所有对象方法和属性

设置和获取原型链

    // 设置原型链  Object.setPrototypeOf(目标对象,原型对象); 将原型对象设置在目标对象的原型链中
    var o = { a: 1 }
    var o1 = { b: 2 }
     Object.setPrototypeOf(o1, o)//o就是o1的原型(原型链)
    console.log(o1);

获取原型链

    var o = { a: 1 }
    var o1 = { b: 2 }
    Object.setPrototypeOf(o1, o) 
    // 获取对象的原型 等同于 对象.__proto__
    Object.getPrototypeOf(目标对象); 获取目标对象的原型链
    var o2 = Object.getPrototypeOf(o1)
    console.log(o2); o: { a: 1 }
    

判断当前属性是不是对象的对象属性

    var o = { a: 1 }
    var o1 = Object.getPrototypeOf(o)
    o1.b = 2
    for in 除了遍历对象,还会遍历对象的原型链
     for (let key in o) {
         console.log(key);
     }
    也可以判断出当前对象的原型链属性   有就是true 没有就是flase
    console.log("a" in o1); false
    console.log("b" in o1); true
    
    
    var o = { a: 1 }
    var o1 = Object.getPrototypeOf(o)
    o1.b = 2
     Object.hasOwn(对象,属性名)  判断这个属性名是不是对象的对象属性,
     如果是原型链属性或者不是该对象的属性就会返回false

    console.log(Object.hasOwn(o1, "a")); false
    console.log(Object.hasOwn(o1, "b")); true
    // 原型链属性的属性名
    console.log(Object.hasOwn(o, "b")) ;  false

     for(var key in o1){
        if(Object.hasOwn(o1,key)) console.log(key);
    }

  // 对象.hasOwnProperty(属性名) 判断这个属性名是不是该对象的对象属性

      console.log(o1.hasOwnProperty("a")); false
      console.log(o1.hasOwnProperty("b")) ;true

Object.assign(目标对象,源对象1,源对象2...)

        不可枚举的属性 : 不能遍历,读取的属性
        合并对象到目标对象中  浅复制
        将源对象1、源对象2...上所有的对象属性,复制到目标对象中,并且返回目标对象,
                                               其中不能复制不可枚举的属性
        源对象中如果有相同的属性,后面的将会覆盖前面的
       

    var o = { a: 1, b: 2 };
    var o1 = { c: 3, d: 4 };
    var o2 = { e: 5, d: 6 };
    Object.assign(o,o1,o2)
    console.log(o); //{a: 1, b: 2, c: 3, d: 6, e: 5}

     创造新数组
    var o1={a:1,b:2};
    var o2={c:3,d:4};
    var o3=Object.assign({},o1,o2);
    console.log(o3) // {a: 1, b: 2, c: 3, d: 4}
    

冻结、密封、禁止扩展(增加新元素)

    Object.freeze(对象) // 冻结对象,对象冻结后不能修改,不是删除,不能添加
    var obj = { a: 1, b: 2, c: 3 };
    Object.freeze(obj) //冻结 不可改变
    obj.a = 10
    //  console.log(obj.a); // 等于1
    obj.d = 10;  // 给d赋值无效
    delete obj.a; // 删除无效
    console.log(obj)  // {a: 1, b: 2, c: 3}

密封

    Object.seal(对象) 密封对象,对象密封后,可以修改属性,但是不能删除和添加属性
    var obj = { a: 1, b: 2, c: 3 }
    Object.seal(obj)
    obj.a = 100
    //console.log(obj); //100
    delete obj.a  //无法删除
    obj.d = 100 // 无法增加
    console.log(obj);

Object.preventExtensions(对象);

    禁止扩展 对象可以修改属性,可以删除属性,但是不能添加新的属性和方法

    var obj = { a: 1, b: 2, c: 3 };
    Object.preventExtensions(obj);
    obj.c = "dsccd" // 可改变
    delete obj.a; // 可删除
    obj.d = 100;  // 无法增加属性
    console.log(obj); //{b: 2, c: 'dsccd'}

三个判断属性 :冻结与密封 是 就是true 不是就是false

    var obj={a:1,b:2,c:3};
    Object.freeze(obj) // 冻结
    console.log(Object.isFrozen(obj));//obj是否被冻结
    console.log(Object.isSealed(obj)) //obj是否被密封 还可以检查冻结
     // 判断对象是否可以被扩展,如果禁止扩展,就会false,否则是true
    console.log(Object.isExtensible(obj)) //obj是否可以扩展

entries,fromEntries 二维数组,map,对象之间的转换

     var obj={a:1,b:2}
     // 将对象转换为一个二维数组,元素是数组,每个元素数组中有两个元素,分别是key和value
      var o=Object.entries(obj)
      console.log( o); // [['a', 1] ['b', 2]]

      // 将对象转换为Map

       var m = new Map(o)
       console.log(m); // Map(2) {'a' => 1, 'b' => 2}


    // 将一个二维数组转换为一个对象,[[key1,value1],[key2,value2]...]转换为对象
     var arr= [["c",3],["d",4]];
     var o=Object.fromEntries(arr)

     console.log(o);// {c: 3, d: 4}

    // 将map转换为对象类型
      var m = new Map()
      m.set("a",1)
      m.set("b",2)
     // console.log(m); // Map(2) {'a' => 1, 'b' => 2}
     var o= Object.fromEntries(m)
     console.log(o);// {a: 1, b: 2}
     

is、keys、values

// 和===类似  判断相等
    var a = 1
    var b = 2
    var c = NaN
 
    console.log(Object.is(a, b)); false
    console.log(Object.is(a, 1)); true
    console.log(Object.is(c, NaN)); true



    Object.keys(对象) 获取对象的所有key属性名组成的数组
      var obj={a:1,b:2,c:3};
     console.log(Object.keys(obj)) // ['a', 'b', 'c']

    并不会获取原型链([[Prototype]] Object)中属性和方法名

    var o = { a: 1, b: 2 };
    var o1 = Object.create(o);
    o1.c = 3;
    o1.d = 4;

     console.log(Object.keys(o1)) // ['c', 'd'] 不能获取 a,b
     把对象转为数组判断,是否为空对象
    var obj={a:1,b:2,c:3};
    console.log(Object.keys(obj).length===0) // false



    Object.values(对象)获取对象的所有value属性值组成的数组
    var obj = { a: 1, b: 2, c: 3 };
    console.log(Object.values(obj)); // [1, 2, 3]

定义属性新的写法

    // 普通写法
     var obj = { a: 1, b: 2 };
    obj.c=3;
    // 进阶写法
    Object.defineProperty(obj,"c",{
        configurable:true,
        writable:true,
        enumerable:true,
        value:3
    })

     console.log(obj.c); // 3

    // 进阶写法2 第二种写法
    Object.defineProperty(obj,"c",{
        configurable:true,
        enumerable:true,
        set(value){

        },
        get(){
            return 1;
        }
    })

     无法 枚举 就是无法遍历
      Object.defineProperty(目标对象,属性名,属性的描述对象)
     属性的描述对象 {}
     {   // true是可以 ,false是不可以
     要是不写下来 configurable  writable enumerable 默认是false
        configurable:true,  是否可以删除该属性,或者是否可以修改该属性的描述对象
        writable:true,  是否可以修改该属性的值
        enumerable:true, 是否可以枚举该属性
        value:3  当前属性的值
     }



    var obj = { a: 1, b: 2 }
    Object.defineProperty(obj, "c", {
        configurable: false,
        enumerable: true,
        writable: true,
        value: 3
    })
    //   configurable: false 可以改变
    // obj.c = 6

    delete obj.b // b,可以删除
      delete obj.c //不行
    console.log(obj);

    Object.defineProperty(obj, "c", {
        // 不能重新定义该描述对象
        configurable: true,
        enumerable: true,
        writable: true,
        value: 4
    })
    //   configurable: false 情况下无法定义(已经有进阶方法定义过的)属性,会出错
    console.log(obj);

是否枚举 不能被枚举就是无法遍历到他,但他就是存在

    var obj = { a: 1, b: 2 }
    Object.defineProperty(obj, "c", {
        configurable: true,
        enumerable: false,
        writable: true,
        value: 3
    })
    // console.log(obj.c); // 3 可以打印
    //  c属性不能遍历
    for (var key in obj) {
        console.log(key); //a , b
    }

     c属性在Object.keys()不能获取
     console.log(Object.keys(obj)) // ) ['a', 'b']

       c是这个对象的属性,但是不能被枚举
    console.log("c" in obj); // turn 确实存在
    console.log("12" in obj) //false 属性不存在


       Object.assign()//不能复制不可枚举属性
        var o1 = Object.assign({}, obj)
         console.log(o1);// {a: 1, b: 2}
        var arr = ["a", "b", "c", "d", "e"];
        for (var key in arr) {
            console.log(key) // 数组下标 0,1,2,3,4
        }
        console.log(arr); //['a', 'b', 'c', 'd', 'e']

c属性设置为只读属性 ,值无法改变

      var obj = { a: 1, b: 2 } 
     Object.defineProperty(obj,"c",{
        configurable:true,
        enumerable:true,
        writable:false,
        value:3
    })

     obj.c=100;
     console.log(obj) // {a: 1, b: 2, c: 3}

value如果是一个值就是属性,但如果是一个函数,就是一个方法

    var obj = { a: 1, b: 2 }

    Object.defineProperty(obj, "c", {
        configurable: true,
        enumerable: true,
        writable: true,
        value: function () {

        }
    })
    console.log(obj) //{a: 1, b: 2, c: ƒ} c就是方法
    
    

可以给对象定义多个属性的描述对象

        Object.defineProperties(对象,对象的所有属性描述对象)

        var obj={}

        Object.defineProperties(obj,{

            a:{

                configurable:true,

                value:1

            },

            b:{

                configurable:true,

                writable:true,

                value:2,

            },

            c:{

                configurable:true,

                enumerable:true,

                value:3

            }

        })

        console.log(obj);{c: 3, a: 1, b: 2}

获取对象的属性 的要点

   keys这个方法 不能获取到不能枚举的属性、也不能获取Symbol定义的属性
    var obj = { a: 1, b: 2 };
    var s=Symbol("d");
    Object.defineProperties(obj, {
        c: {
            configurable: true,
            writable: true,

            value: 3
        },
        [s]: {
            configurable: true,
            writable: true,
            enumerable: true,
            value: 4
        }
    })

    var keys=Object.keys(obj);
    console.log(keys); //  ['a', 'b']
    
     获取对象的所有可枚举和不可枚举的字符串属性名组成的数组
    Object.getOwnPropertyNames(对象)
    var arr = Object.getOwnPropertyNames(obj);
    console.log(arr); // ['a', 'b', 'c']

    获取对象的所有可枚举和不可枚举的Symbol属性名组成的数组
    var arr1 = Object.getOwnPropertySymbols(obj);
    console.log(arr1); //[Symbol(d)]

    // 组合方法1
    var arr=Object.getOwnPropertyNames(obj).concat(Object.getOwnPropertySymbols(obj));
    // 组合方法2
    var arr=[...Object.getOwnPropertyNames(obj),...Object.getOwnPropertySymbols(obj)];
    console.log(arr);  ['a', 'b', 'c', Symbol(d)]

    // Reflact 对象的映射方法集
     获取对象的所有可枚举或者不可枚举的所有属性名组成 的 数组
       var list=Reflect.ownKeys(obj);
       console.log(list);//  ['a', 'b', 'c', Symbol(d)]
       
    // 不包含不可枚举属性,判断是否是空对象
         console.log(Object.keys(list).length===0) false

     //  判断是否完全就是空对象
        console.log(Reflect.ownKeys(list).length===0)false

Object.getOwnPropertyDescriptor(对象,属性)

       var o={a:1,b:2};

        Object.defineProperties(o,{

            c:{

                value:3

            },

            d:{

                writable:true,

                value:4

            },

            [Symbol("ab")]:{

                value:4

            }

        })




        Object.getOwnPropertyDescriptor(对象,属性) 获取对象中这个属性的描述对象

        var desc=Object.getOwnPropertyDescriptor(o,"d");获取d的所有元素  {configurable:    
                                   false,enumerable: false,value: 4,writable: true}

        console.log(desc)  
        
        

获取对象的所有属性的描述对象 (包括不可枚举的那些属性)

    用法: Object.getOwnPropertyDescriptors(对象)
        
         var o={a:1,b:2};

        Object.defineProperties(o,{

            c:{

                value:3

            },

            d:{

                writable:true,

                value:4

            },

            [Symbol("ab")]:{

                value:4

            }

        })


        var list=Object.getOwnPropertyDescriptors(o);

        console.log(list)



        遍历所有属性,包括无法遍历的,依次打印
        for(var key in Object.getOwnPropertyDescriptors(o)){

            console.log(key,Object.getOwnPropertyDescriptors(o)[key])

        }
       

对象的实例化方法

    var obj = { a: 1, b: 2, c: 3 };
    var o = Object.create(obj);
    o.d = 4;
    o.e = 5;
    var o1 = Object.create(o);
    o1.f = 6;
    o1.g = 7;
    console.log(o);// 能看到 o,obj ,无法打印o1
    console.log(o1) // 打印全部
    console.log(obj);// 只能打印 obj
     判断obj是否是o对象的原型链中的一环
   1. 父级对象.isPrototypeOf(子级对象)
     另一种说法 对象1.isPrototypeOf(对象2)

         判断对象1是否是对象2的原型对象
    console.log(obj.isPrototypeOf(o)) // true
    console.log(obj.isPrototypeOf(o1)) // true
    console.log(obj.isPrototypeOf(o)) // true
    console.log(o.isPrototypeOf(o1)) // true
    
   2. 判断当前属性是否是可枚举的属性

        对象.propertyIsEnumerable(属性名)

        var o={a:1};

        Object.defineProperty(o,"b",{

            value:2

        })

        console.log(o.propertyIsEnumerable("a"));true//可枚举

        console.log(o.propertyIsEnumerable("b"));false//不可枚举