js对象

作者: Super曲江龙Kimi | 来源:发表于2019-08-12 22:50 被阅读0次

    对象和原型

    对象

    若干属性的集合就是对象,一切引用类型都是对象,都是属性的集合

    let arr = [1,2]
    arr.name = 'kimi';
    console.log(arr.length) // 2
    console.log(arr.name) // 'kimi'
    

    属性描述符

    let obj = {
      a: 2
    };
    Object.getOwnPropertyDescriptor(obj, 'a');
    // {
    //  value: 2,
    //  writable: true,
    //  enumerable: true,
    //  configurable: true
    // }
    

    <1> [[writable]]

    表示是否能修改属性的值,默认值是true

    let obj = {};
    Object.defineProperty(obj, 'a', {
      value: 2,
      writable: false, // 不可写
      configurable: true,
      enumerable: true,
    })
    obj.a = 3; // 严格模式下会报错,非严格模式下会忽略
    obj.a // 2
    

    <2> [[configurable]] 默认值true

    是否可以通过defineProperty来配置对象

    let obj = {};
    Object.defineProperty(obj, 'a', {
      value: 2,
      writable: true, 
      configurable: false, // 不可配置
      enumerable: true,
    })
    obj.a = 3; // 仍然可以修改属性值
    obj.a // 3
    
    Object.defineProperty(obj, 'a', {
      value: 2,
      writable: true, 
      configurable: true, // 不管什么模式都会报错
      enumerable: true,
    })
    

    如果使用Object.defineProperty创建新属性但是不填写配置,writable、configurable、enumerable默认都是false。

    let obj = {};
    Object.defineProperty(obj, 'a', {})
    Object.getOwnPropertyDescriptor(obj, 'a');
    // {
    //  value: undefined,
    //  writable: false,
    //  enumerable: false,
    //  configurable: false
    // }
    

    如果设置了configurable是false。仍然可以将writable的值从true设置为false,但是不可以从false设置为true。
    如果设置了configurable是false,不可以使用delete删除属性

    <3> [[value]] 默认值undefined

    包含这个属性的数据值

    <4> [[enumerable]] 默认值true

    是否可以for in、object.keys、 JSON.stringify递归出来

    访问描述符

    [[get]] [[set]]

    let obj = {};
    Object.defineProperty(obj, 'a', {
      get: function() {
        return this._a;  
      },
      set: function(val) {
        this._a = val;
      } 
    })
    
    let obj = {
      get a() {
         return this._a;  
      },
      set a(val) {
        this._a = val
      }
    }
    

    以上两种都会在对象中创建一个不包含值的属性,自动调用get、set函数。如果设置了set、get则会忽略value和enumerable配置

    不变性

    <1> 设置writable、configurable为false

    设置writable、configurable为false就可以创建一个真正的常量属性,不可修改、重定义、删除

    <2> Object.preventExtensions() 不可扩展

    let obj = {
      a: 2
    };
    Object.preventExtensions(obj) ; // 不可以添加新属性,并且保留已有属性
    obj.b = 3 ;
    obj.b // undefined 
    

    <3> Object.seal() 密封

    会在现有对象身上调用Object.preventExtensions,并把所有属性标记为configurable为false

    不能添加新属性,也不能重新配置或者删除现有属性。可以修改现有的值

    <4> Object.freeze() 冻结

    会在现有对象身上调用Object.seal,并且把所有属性标记为writable为false

    不能添加新属性,也不能重新配置或者删除现有属性。不可以修改现有的值

    存在性

    let obj = {
      a: undefined
    }
    obj.a // undefined
    obj.b // undefined
    都是undefined,如何来区分哪个为obj的属性呢?
    

    hasOwnProperty()

    hasOwnProperty只会判断自身是否有属性。in 操作符会检查属性是否存在原型中。

    2 in [1,2]  // false 判断的是key 数组的key是下标 0,1
    

    new操作符

    1. 创建一个空的简单JavaScript对象(即{});
    2. 链接该对象(即设置该对象的构造函数)到另一个对象;
    3. 将步骤1新创建的对象作为this的上下文 ;
    4. 如果该函数没有返回对象,则返回this。
    function _new(fun) {
      return function() {
        // 创建一个空的简单JavaScript对象
        let obj = {};
        // 链接该对象(即设置该对象的构造函数)到另一个对象
        obj.__proto__: fun.prototype;
        // 将步骤1新创建的对象作为this的上下文
        let returnObj  = fun.apply(obj, arguments)
        // 如果该函数没有返回对象,则返回this
        if(typeof returnObj === 'object'){
            return returnObj
        }else{
            return obj
        }
      }
    }
    

    Object.create()

    Object.create()方法创建一个新对象,并使用现有的对象来提供新创建的对象的proto

    Object.create =  function (o) {
        var F = function () {};
        F.prototype = o;
        var newObj=new F();
        return newObj;
    };
    

    使用{}和Object.create(null)创建对象的区别。
    Object.create(null)创建的对象proto为null。没有继承的方法例如toString()是一个完全空的对象。而{}继承于Object

    相关文章

      网友评论

          本文标题:js对象

          本文链接:https://www.haomeiwen.com/subject/ojxzrctx.html