javascript-数据属性&访问器属性

作用:主要用于定义变量的权限 (可读,可写,可删除,可枚举)

在其它语言中,比如java, 对于class类中变量需要设置其get, set方法,
这样做的目的是出于安全考虑, 仅能调用由class暴露出来的方法。

并且可以在方法内对变量进行其它操作,修改其内容或者内部的其它变量。当然,这其实也是非必需的。如swift语言中新出的计算属性这个新词

比如lua语言中,并没有要求要对变量设置其get, set属性, 在需要的时候,可以直接修改其内容,只要不进行一些我们自己都不能确定的操作,程序依然是健壮的。当然,这里完全是由人来控制。

object-c语言中, 如果想访问一个受保护的变量, 还可以通过kvc,kvo的方式

总值,javasript的数值属性,访问器属性只是一种对变量进行权限约定和对象的变量进行添加,修改的一种手段, 在合适的时候使用即可

1. 数值属性
    行为特征:
    1.1 [[Configurable]]  是否可删除
    1.2 [[Enumerable]]    是否可遍历
    1.3 [[Writable]]      是否可写
    1.4 [[Value]]          属性值, 默认undefined

    e.g.
    var person = {};
    Object.defineProperty(person, 'name', {
        writable: false,
        value: 'Nicholas'
    });

    alert(person.name); //'Nicholas'
    person.name = 'Greg';
    alert(person.name); //'Nicholas'


2. 访问器属性
    行为特征:
    2.1 [[Configurable]]  是否可删除
    2.2 [[Enumerable]]    是否可遍历
    2.3 [[Get]]              读取属性时调用的方法   默认 underfined
    2.4 [[Set]]              写入属性行调用的方法   默认 underfined

    e.g.
    var book = {
        _year: 2004,
        edition: 1
    };

    Object.defineProerty(book, 'year', {
        get: function() {
            return this._year;
        },
        set: function(newValue) {
            if (newValue > 2004) {
                this._year = newValue;
                this._edition += newValue - 2004;
            }
        }
    });

    book.year = 20005; 
    alert(book.edition); //2

注: 当通过数据属性或访问器的重新定义变量时, Configurable, Enumerable,Writable 默认值全部都重设为false, 不使用,默认是true

多属性定义方法
var book = {};
Object.defineProperties(book, {
    _year: {
        value: 2004
    },

    edition: {
        value: 1
    },

    year: {
        get: function() {
            return this._year;
        },

        set: function(newValue) {
            if (newValue > 2004) {
                this._year = newValue;
                this.edition += newValue - 2004;
            }
        }
    }
});


属性特征读取方式
var descriptor = Object.getOwnPropertyDescriptor(book, '_year');
alert(descriptor.value);        //2004
alert(descriptor.configurable); //false
alert(type description.get);    //'undefined'

var descriptor = Object.getOwnPropertyDescriptor(book, 'year');
alert(descriptor.value);         //undefined
alert(descriptor.enumerable);     //false
alert(typeof descriptor.get);   //'function'