• ECMAScript Obejct 属性操作API


    Object

    创建对象

    我们有很多种方法创建一个对象,Object.create, Object.assign

    Object.create

    //字面量
    var o = {};
    // 等同于
    var o = Object.create(Object.prototype)
    
    // 字面量创建对象,建立属性
    var obj = {name: "hello"};
    // 等同于
    var obj = Object.create(Object.prototype, {
    	name: {writable:true, configurable:true, value: "hello" }
    })
    
    // 构造器创建对象
    var Obj = function() {
      this.name = "hello";
    }
    var obj = new Obj;
    // 等同于使用Obj的原型链创建
    var obj = Object.create(Obj.prototype, {
    	name: {writable:true, configurable:true, value: "hello" }
    })
    
    obj.__proto__ == Obj.prototype // true
    

    Object.assign

    Object.assign 方法只会拷贝源对象自身的并且可枚举的属性到目标对象身上,该方法使用源对象的 [ [ Get ] ] 和目标对象的 [ [ Set ] ],所以它会调用相关 getter 和 setter。因此,它分配属性而不是复制或定义新的属性。

    语法

    Object.assign(target, ...sources)
    

    测试

    var o1 = { a: 1 };
    var o2 = { b: 2 };
    var o3 = { c: 3 };
    
    var obj = Object.assign(o1, o2, o3);
    console.log(obj); // { a: 1, b: 2, c: 3 }
    console.log(o1);  // { a: 1, b: 2, c: 3 }, 注意目标对象自身也会改变。
    

    所以对待浅拷贝我们一般使用这样的形式

    var obj = Object.assign({}, o1, o2, o3);
    

    继承属性和不可枚举属性是不能拷贝的

    var obj = Object.create({foo: 1}, { // foo 是个继承属性。
        bar: {
            value: 2  // bar 是个不可枚举属性。
        },
        baz: {
            value: 3,
            enumerable: true  // baz 是个自身可枚举属性。
        }
    });
    
    var copy = Object.assign({}, obj);
    console.log(copy); // { baz: 3 }
    

    对象属性增删改

    属性有几个特性:

    • configurable : 当且仅当该属性的 configurable 为 true 时,该属性描述符才能够被改变,也能够被删除。默认为 false。configurable 特性表示对象的属性是否可以被删除,以及除 writable 特性外的其他特性是否可以被修改。
    • enumerable: 当且仅当该属性的 enumerable 为 true 时,该属性才能够出现在对象的枚举属性中。默认为 false。
    • value : 该属性对应的值。可以是任何有效的 JavaScript 值(数值,对象,函数等)。默认为 undefined
    • writable: 当且仅当该属性的 writable 为 true 时,该属性才能被赋值运算符改变。默认为 false
    • get:一个给属性提供 getter 的方法,如果没有 getter 则为 undefined。该方法返回值被用作属性值。默认为 undefined
    • set :一个给属性提供 setter 的方法,如果没有 setter 则为 undefined。该方法将接受唯一参数,并将该参数的新值分配给该属性。默认为 undefined

    创建属性 Object.defineProperty

    var o = {};
    
    Object.defineProperty(o, "a", {
      value : 37,
      writable : true,
      enumerable : true,
      configurable : true
    });
    
    // 数据描述符和存取描述符不能混合使用
    Object.defineProperty(o, "conflict", {
      value: 0x9f91102, 
      get: function() { 
        return 0xdeadbeef; 
      } 
    });
    

    修改属性 Object.defineProperty

    如果描述符的 configurable 特性false(即该特性为non-configurable),那么除了 writable 外,其他特性都不能被修改,并且数据和存取描述符也不能相互切换。

    var o = {};
    
    Object.defineProperty(o, "a", {
      value : 37,
      writable : true,
      enumerable : true,
      configurable : false
    });
    
    Object.defineProperty(o, "a", {enumerable : false}) //TypeError: Cannot redefine property: a
    

    设置多个属性 Object.defineProperties

    使用 Object.defineProperties 设置多个属性

    var obj = {};
    Object.defineProperties(obj, {
      "property1": {
        value: true,
        writable: true
      },
      "property2": {
        value: "Hello",
        writable: false
      }
      // 等等.
    });
    

    冻结对象 Object.freeze

    Object.freeze() 方法可以冻结一个对象,浅冻结,冻结指的是不能向这个对象添加新的属性,不能修改其已有属性的值,不能删除已有属性,以及不能修改该对象已有属性的可枚举性、可配置性、可写性。也就是说,这个对象永远是不可变的。该方法返回被冻结的对象。

    冻结对象的所有自身属性都不可能以任何方式被修改。任何尝试修改该对象的操作都会失败,可能是静默失败,也可能会抛出异常(严格模式中)。

    var obj = {name:"hello"}
    
    Object.isFrozen(obj) // false
    Object.freeze(obj)
    Object.isFrozen(obj) // true
    
    obj.name = "hello2" // 严格模式抛错
    obj.name = "hello" // freeze
    

    浅冻结

    冻结的属性是不能修改的,但是引用的对象是可以修改的。冻结只是冻结对象的属性

    var obj = {
      name:"hello", 
      internal: {
        name: "internal"
      }, 
      internalFunc: function(){
        console.log("internal function")
      }
    }
    
    Object.freeze(obj)
    obj.internal.name = "after freeze"
    obj.internalFunc = function() {
      console.log("after freeze")
    }
    
    console.log(obj.internal.name) // after freeze
    obj.internalFunc() // internal function
    

    对象属性遍历

    for...in 循环只遍历可枚举属性。像 Array 和 Object 使用内置构造函数所创建的对象都会继承自 Object.prototype 和 String.prototype 的不可枚举属性,例如 String indexOf() 方法或者 Object 的 toString 方法。

    var obj = Object.create({
      name: "kk",
      nick: "kkj"
    }, {
      age: {writable:true, configurable:true, value: 27, enumerable: true }
    });
    
    for(let key in obj){
      console.log(key); // age, name, nick
    }
    

    hasOwnProperty

    可以使用对象的原型链上的hasOwnProperty 方法判断对象是否具有指定的属性作为自身(不继承)属性。

    var obj = Object.create({
      name: "kk",
      nick: "kkj"
    }, {
      age: {writable:true, configurable:true, value: 27, enumerable: true },
      sex: {writable:true, configurable:true, value: 'male', enumerable: false}
    });
    
    for(let key in obj){
      if(obj.hasOwnProperty(key)){
        console.log(key); // age
      }
    }
    

    这里因为 sex 不可枚举,所以在 for…in 中没有遍历出来,如果

    obj.hasOwnProperty("sex") // true
    

    getOwnPropertyNames

    返回一个由指定对象的所有自身属性的属性名(包括不可枚举属性)组成的数组。

    var obj = Object.create({
      name: "kk",
      nick: "kkj"
    }, {
      age: {writable:true, configurable:true, value: 27, enumerable: true },
      sex: {writable:true, configurable:true, value: 'male', enumerable: false}
    });
    
    Object.getOwnPropertyNames(obj) // ["age", "sex"]
    

    Object.key

    返回一个由给定对象的自身 可枚举属性 组成的数组

    var obj = Object.create({
      name: "kk",
      nick: "kkj"
    }, {
      age: {writable:true, configurable:true, value: 27, enumerable: true },
      sex: {writable:true, configurable:true, value: 'male', enumerable: false}
    });
    
    Object.keys(obj) // ["age"]
    

    Object.values

    返回一个给定对象自己的所有可枚举属性值的数组

    var obj = Object.create({
      name: "kk",
      nick: "kkj"
    }, {
      age: {writable:true, configurable:true, value: 27, enumerable: true },
      sex: {writable:true, configurable:true, value: 'male', enumerable: false}
    });
    
    Object.values(obj) // [27]
    

    getOwnPropertyDescriptor

    返回指定对象上一个自有属性对应的属性描述符。

    var obj = Object.create({
      name: "kk",
      nick: "kkj"
    }, {
      age: {writable:true, configurable:true, value: 27, enumerable: true },
      sex: {writable:true, configurable:true, value: 'male', enumerable: false}
    });
    
    Object.getOwnPropertyDescriptor(obj, "name") // undefined
    Object.getOwnPropertyDescriptor(obj, "nick") // undefined
    Object.getOwnPropertyDescriptor(obj, "age") //  {value: 27, writable: true, enumerable: true, configurable: true}
    Object.getOwnPropertyDescriptor(obj, "sex") //  {value: "male", writable: true, enumerable: false, configurable: true}
    

    getOwnPropertyDescriptors

    用来获取一个对象的所有自身属性的描述符。

    var obj = Object.create({
      name: "kk",
      nick: "kkj"
    }, {
      age: {writable:true, configurable:true, value: 27, enumerable: true },
      sex: {writable:true, configurable:true, value: 'male', enumerable: false}
    });
    
    Object.getOwnPropertyDescriptors(obj)
    
    {
      "age": {
        "value": 27,
        "writable": true,
        "enumerable": true,
        "configurable": true
      },
      "sex": {
        "value": "male",
        "writable": true,
        "enumerable": false,
        "configurable": true
      }
    }
    

    原型

    getPrototypeOf

    返回指定对象的原型

    let proto = {};
    let obj = Object.create(proto);
    
    Object.getPrototypeOf(obj) === proto; // true
    

    isPrototypeOf

    isPrototypeOf 和 instanceof operator 是不一样的。在表达式 object instanceof AFunction 中,检测的是AFunction.prototype 是否在object 的原型链中,而不是检测 AFunction 自身。

    let proto = {};
    let obj = Object.create(proto);
    
    proto.isPrototypeOf(obj) // ture
    
  • 相关阅读:
    最大流
    CF Round #634
    CF Round #633
    Sunday
    Pikachu——RCE(远程系统命令、代码执行)
    Pikachu——SQL Inject
    Pikachu——CSRF(跨站请求伪造)
    Pikachu——XSS(反射型,存储型,DOM型,盲打,过滤,htmlspecialchars(),href输出,js输出)
    Pikachu暴力破解——token防爆破?
    Pikachu暴力破解——验证码绕过(on client)
  • 原文地址:https://www.cnblogs.com/xiaoniuzai/p/6822319.html
Copyright © 2020-2023  润新知