• JS面向对象设计-理解对象


    不同于其他面向对象语言(OO,Object-Oriented),JS的ECMAScript没有类的概念,
    它把对象定义为"无序属性(基本值、对象、函数)的集合",类似于散列表.
    每个对象都是基于一个引用类型(原生类型、自定义类型)创建的.

    1. 理解对象

    创建自定义对象(Object构造函数、对象字面量).

    // Object构造函数:创建一个Object实例,再为实例添加属性和方法.
    var person = new Object();
    person.name = "xiao";
    person.getName = function() {
        console.log(this.name)      // 被解析为person.name
    }
    
    // 对象字面量: 属性在创建时带有一些特征值,JS通过特征值来定义它们的行为.
    var person = {
        name: "xiao";
        getName: function() {
            console.log(this.name)
        }
    }
    

    1.1 属性类型(数据属性、访问器属性)

    [[ ]]: 内部值(内部才用的特性)实现JS引擎,描述属性各种特征,JS不能直接访问.

    1.1.1 数据属性

    • [[Configurable]]可用delete删除属性从而重新定义属性,修改属性特性、改为访问器属性.
    • [[Enumberable]]可用for-in循环返回属性.
    • [[Writable]]可修改属性值.
    • [[Value]]属性的数据值,默认为undefined.

    ps. 直接在对象上定义的属性,他们的Configurable,Enumberable,Writable特性都为true.

    修改属性默认的特性:Object.defineProperty()

    /*
    * 参数
    * 1.属性所在对象
    * 2.属性名字
    * 3.一个描述符对象,描述符对象的属性必须是(configurable、enumerable、writable、value)
    */
    var person = {};
    Object.defineProperty(person, "name", {
        writable: false,        // 属性只读
        value: "xiao"
    })
    console.log(person.name);   // "xiao"
    person.name = "da";         // 非严格模式下被忽视,严格模式下报错
    console.log(person.name);   // "xiao"
    
    // 一旦属性定义为不可配置,将不能再把它变回可配置.
    Object.defineProperty(person, "name", {
        configurable: false,    // 属性不可配置
        value: "xiao"
    })
    

    ps. 用Object.defineproperty()方法创建新属性,如果不指定,Configurable,Enumberable,Writable特性默认为false.

    1.1.2 访问器属性

    不包含数据值,包含一对getter、setter函数(都不是必需的)

    • [[Configurable]]可用delete删除属性从而重新定义属性,修改属性特性、改为数据属性.
    • [[Enumberable]]可用for-in循环返回属性.
    • [[Get]]读取属性时调用的函数,默认为undefined.
    • [[Set]]写入属性时调用的函数,默认为undefined.

    ps. 访问器属性不能直接定义,必须使用Object.defineProperty()

    // 常见使用方式:设置一个属性的值会导致其他属性发生变化
    var book = {
        _year: 2018,            // 只能通过对象方法访问的属性
        edition: 1
    };
    
    Object.defineProperty(book, "year", {
        get: function() {           // __definGetter__
            return this._year;
        },
        set: function(newValue) {   // __definSetter__
            if (newValue > 2018) {
                this._year = newValue;
                this.edition += newValue - 2018;
            }
        }
    });
    
    book.year = 2019;           // 修改year属性会导致_year变成2019
    console.log(book.edition);  // edition变成2
    

    在不支持Object.definProperty()方法的浏览器中不能修改[[Configurable]]和[[Enumberable]]

    1.2 定义多个属性

    Object.defineProperties()一次定义多个属性

    /*
    * 参数
    * 1.要添加或修改其属性的对象
    * 2.第二个对象的属性与第一个对象要添加或修改的属性一一对应
    */
    var book = {};
    Object.defineProperties(book, {
        _year: {
            writable: true,
            value: 2018
        },
        edition: {
            writable: true,
            value: 1
        },
        year: {
            get: function() {
                return this._year;
            },
            set: function(newValue) {
                if (newValue > 2018) {
                    this._year = newValue;
                    this.edition += newValue - 2018;
                }
            }
        }
    })
    

    1.3 读取属性特性

    Object.getOwnPropertyDescriptor()取得给定属性的描述符,返回值是一个对象(属性特有的特性)。

    /*
    * 参数
    * 1.属性所在对象
    * 2.要读取其描述符的属性名称
    */
    var descriptor = Object.getOwnPropertyDescriptor(book, "_year");
    console.log(descriptor.value);             // 2018
    console.log(descriptor.configurable);      // false
    console.log(descriptor.get);               // "undefined",是数据属性,不是访问器属性
    
    var descriptor = Object.getOwnPropertyDescriptor(book, "year");
    console.log(descriptor.value);             // undefined,是访问器属性,不是数据属性
    console.log(descriptor.configurable);      // false
    console.log(descriptor.get);               // "function",是一个指向getter函数的指针
    

    在JS中可以针对任何对象(包括DOM、BOM)使用Object.getOwnPropertyDescriptor()方法.

  • 相关阅读:
    Loj #6307. 「雅礼国庆 2017 Day1」Clique
    bzoj 4457: 游戏任务
    Codeforces 375 D Tree and Queries
    Codeforces 837 E Vasya's Function
    [POI2008]BLO
    Codeforces 451 E Devu and Flowers
    洛谷 P4318 完全平方数
    [JSOI2016]反质数序列
    bzoj 4320: ShangHai2006 Homework
    bzoj4454 C Language Practice
  • 原文地址:https://www.cnblogs.com/LittlePANDA-ZSJ/p/10963990.html
Copyright © 2020-2023  润新知