• js基础知识温习:js中的对象


    在JavaScript中对象是一个无序属性的集合,其属性可以包含基本值、对象或者函数。

    对象最简单的创建方式

    JavaScript中创建对象最简单的方式就是创建一个Object对象的实例,然后再添加属性和方法。

    var person = new Object();
    
    person.name = 'jenemy';
    person.age = 24;
    
    person.getName = function() {
      return this.name;
    }
    

    另一种写法是使用对象字面量语法,这种方式看起来更加简洁,而且更加通用。

    var person = {
      name: 'jenemy',
      age: 24,
      getName: function() {
        return this.name;
      }
    }
    

    然后可以通过person.name或者person['name']获取对象的属性。

    通过Object构造函数和对象字面量的创建的对象有以下特点

    • 可以任意修改其属性和方法
    • 可以通过delete删除其属性和方法

    对象的属性类型

    ESMAScript中有两种属性:数据属性和访问器属性

    数据属性

    数据属性包含一个值,例如前面的person对象name属性。数据属性有4个描述其行为的特性:

    • [[Configurable]]:默认值为true,表示能否通过 delete 删除属性从而重新定义属性、能否修改属性的特性,或者能否把属性修改为访问器属性。
    • [[Enumerable]]: 默认值为true,表示是否通过for-in循环返回属性。
    • [[Writable]]:默认值为undefined,表示是否能修改属性的值。
    • [[Value]]:默认值undefined,包含这个属性的数据值。

    要修改默认的属性值,必须使用ECMAScript5的Object.defineProperty()方法,这个方法接收三个参数:属性所在的对象、属性的名字和一个描述符对象。其中属性描述符必须是:configurable、enumerable、writable和value。

    var person = {};
    person.age = 25;
    Object.defineProperty(person, 'name', {
      configurable: false,
      enumerable: false,
      value: 'jenemy'
    });
    
    person.name; // jenemy
    person.name = 'xiaolu'; // name属性不可修改
    person.name; // jenemy
    delete person.name; // name属性不可以删除
    person.name; // jenemy
    
    // name属性不可以使用for..in返回属性
    for(var p in person) {
      console.log(p); // age
    }
    // 同样也不能使用Object.keys()返回
    Object.keys(person); // ["age"]
    
    // 一旦使用definedProperty()定义属性后就不可以再更改了
    // Uncaught TypeError: Cannot redefine property: name
    Object.defineProperty(person, 'name', {
      configurable: true,
    });
    

    如果需要同时设定多个属性值,可以使用Object.defineProperties()方法。

    var person = {};
    Object.defineProperties(person, {
      name: {
        value: 'jenemy'
      },
      age: {
        value: 25
      }
    });
    

    访问器属性

    访问器属性不包含数据值,它包含一对儿getter和setter函数。在读取访问器时,会调用getter函数,这个函数会返回有效的值。在写入访问器属性时,会调用setter函数并传入新值。访问器属性有4个特性:

    • [[Configurable]]:默认值为true,表示能否通过 delete 删除属性从而重新定义属性、能否修改属性的特性,或者能否把属性修改为访问器属性。
    • [[Enumerable]]: 默认值为true,表示是否通过for-in循环返回属性。
    • [[Get]]:默认值为undefined,在读取属性时调用的函数。
    • [[Set]]:默认值为undefined,在写入属性时调用的函数。

    访问器属性同样需要defineProperty()来定义

    var person = {
      _name: 'jenemy',
    };
    Object.defineProperty(person, 'name', {
      get: function() {
        return this._name
      },
      set: function(newValue) {
        this._name = '我的新名字:' + newValue;
      }
    });
    
    person.name; // jenemy
    person.name = 'xioalu';
    person.name; // 我的新名字:xioalu
    

    获取属性的特性

    使用ECMAScript中的Object.getOwnPropertyDescriptor()方法,可以取得指定属性的描述符。

    var person = {
      name: 'jenemy',
      age: 25
    }
    
    // {value: "jenemy",  writable: true, enumerable: true, configurable: true}
    Object.getOwnPropertyDescriptor(person, 'name');
    
    

    禁止修改对象

    对象和属性都有指导其内部属性行为的内部特征。其中,[[Extensible]]是一个布尔值,它指明该对象本身是否可以被修改。默认情况下,对象本身是可以被扩展的。

    设置[[Extensible]]为false,就可以禁止新属性的添加。有3中方式来实现对对象的锁定。

    禁止扩展

    第一种方式是使用Object.preventExtensions()创建一个不可扩展的对象。可以使用Object.isExtensible()来检查[[Extensible]]的值。

    var person = {
      name: 'jenemy'
    }
    
    Object.isExtensible(person); // true
    
    Object.preventExtensions(person);
    person.addr = 'shanghai';
    person.addr; // undefined
    Object.isExtensible(person); // false
    
    person.age = 23;
    person.age; // 23
    delete person.age;
    person.age; // undefined
    

    可以看出,虽然我们不能添加新的属性,但是可以修改和删除已有的属性。

    对象封印

    使用Object.seal()可以来封印一个对象。该方法被调用时,[[Extensible]]特征被设置为false,其所有属性的[[Configurable]]特征被转为false;可以使用Object.isSealed()判断一个对象是否被封印。

    var person = {
      name: 'jenemy'
    }
    Object.seal(person);
    Object.isSealed(person); // true
    
    person.addr = 'shanghai';
    person.addr; // undefined
    
    person.age = 23;
    person.age; // 23
    
    // {value: "jenemy", writable: true, enumerable: true, configurable: false}
    Object.getOwnPropertyDescriptor(person, 'name');
    
    delete person.name; // false
    

    可以看到我们依然可以修改已有对象的属性,但是对象被封印后其属性就不能使用delete操作符删除了。

    对象冻结

    使用Object.freeze()可以冻结一个对象,被冻结的对象将不能再添加或者删除属性,不能改变属性类型,也不能写入任何数据属性。同样有一个对应的Object.isFrozen()来判断一个对象是否被冻结。

    var person = {
      name: 'jenemy'
    }
    Object.freeze(person);
    Object.isFrozen(person); // true
    
    person.addr = 'shanghai';
    person.addr; // undefined
    
    person.age = 23;
    person.age; // 24, 不可以修改
    
    // {value: "jenemy", writable: false, enumerable: true, configurable: false}
    Object.getOwnPropertyDescriptor(person, 'name');
    
    delete person.name; // false
    

    现在这个对象完全不可以添加、删除、更改属性了。

    参考

    -《JavaScript高级程序设计》(第3版)
    -《JavaScript面向对象精要》
    -《Effective JavaScript》

  • 相关阅读:
    Linux之硬件资源管理
    Linux之vi 文本编辑命令
    [2]窗口程序的创建
    [1]cs辅助项目分解
    1.3 Windows操作系统
    (PYG)学习去除软件自效验
    CSUST 4006-你真的会树套树套树吗?(贪心|dp)
    CSUST 4003-你真的会泡面吗?(优先队列模拟)
    2020牛客暑期多校第八场I-Interesting Computer Game(离散化+并查集)
    2020牛客暑期多校K-Kabaleo Lite(贪心)
  • 原文地址:https://www.cnblogs.com/wujie520303/p/4918039.html
Copyright © 2020-2023  润新知