JavaScript Object.defineProperty()进修笔记。

属性范例

ECMAScript中有两种属性:数据属性和接见器属性。
数据属性:
数据属性包括一个数据值的位置。在这个位置能够读取和写入值。数据属性有4个形貌其行动的特征。

[[Configurable]]:示意可否经由过程delete删除属性从而从新定义属性,可否修正属性的特征,或许可否把属性修正为接见器属性。在对象上直接定义的属性,它们的这个特征默许值为true。
[[Enumerable]]:示意可否经由过程for-in轮回返回属性。在对象上直接定义的属性,它们的这个特征默许值为true。
[[Writable]]:示意可否修正属性的值。在对象上直接定义的属性,它们的这个特征默以为true.
[[Value]]:包括这个属性的数据值。读取属性值的时刻,从这个位置读;写入属性值的时刻,把新值保留在这个位置。这个特征的默许值为undefined。

要修正属性默许的特征,必需运用ECMAScript5的Object.defineProperty()要领。这个要领接收三个参数:属性地点的对象、属性的名字和一个形貌符对象。个中,形貌符对象的属性必需是:configurable、enumerable、writable和value。设置个中的一个或多个值,能够修正对应的特征值。比方:

var person = {};
Obejct.defineproperty(person,'name',{
    writable:false,
    value:'Nics'
})
console.log(person.name)//Nics
person.name = 'tom';
console.log(person.name)//Nics

这个例子建立了一个明为name的属性,它的值是只读的,假如为它指定新的值,在非严厉形式下,赋值操纵将被疏忽;在严厉形式下赋值操纵将会抛出毛病。
假如把configurable设置为false,示意不能从对象中删除属性,而且一旦把属性定义为不可设置的,就不能再把它变成可设置了。此时再挪用Object.defineProperty()要领修正writable以外的特征都邑抛出毛病。
也就是说,能够屡次挪用Object.defineProperty()要领修正同一个属性,但在把configurable特征设置为false以后就会有限定了。
再挪用Object.defineProperty()要领建立一个新的属性的时刻,假如不指定configurable、enumerable、writable特征的默许值都是false。
Obejct.defineProperty(obj,prop,descriptor)要领会直接在一个对象上定义一个新属性,或许修正一个对象的现有属性,并返回这个对象。
参数:

obj:要在其上定义属性的对象。
prop:要定义或修正的属性的称号。
descriptor:将被定义或修正的属性形貌符。

返回值:

被传递给函数的对象。

属性形貌符:

configurable:当且仅当改属性的configurable为true时,该属性形貌符才够被转变,同时该属性也能从对应的对象上被删除。默以为false。
enumerable:当且仅当改属性的enumerable为true时,改属性才够出现在对象的罗列属性中。默以为false。
数据形貌符同时具有以下可选键值:
value:该属性对应的值。能够是任何有用的JavaScript值(数值,对象,函数等)。默以为undefined。
writable:当且仅当该属性的writable为true时,value才被赋值运算符转变。默以为false。
存取形貌符同时具有以下可选键值:
get:一个给属性供应getter的要领,假如没有getter则为undefined。当接见改属性时,该要领会被实行,要领实行时没有参数传入,然则会传入this对象(因为继续关联,这里的this并不一定是定义该属性的对象)默以为undefined。
set:一个给属性供应setter的要领,假如没有setter则为undefined。当属性值修正时,触发实行该要领。该要领将接收唯一参数,即改属性新的参数值。
var o = {}
//在对象中增加一个属性与数据形貌符的示例。
Obejct.defineProperty(o,'a',{
    value:37,
    writable:true,
    enumerable:true,
    configurable:true
})
//对象o具有了属性a,值为37

//在对象中增加一个属性与存取形貌符的示例。
var bValue;
Obejct.defineProperyty(o,'b',{
    get:function(){
        return bValue;
    },
    set:function(newValue){
        bValue = newValue;
    },
    enumerable:true,
    configurable:true
})
o.b = 38;
//对象o具有了属性b,值为38.
//数据形貌符和存取形貌符不能混合运用。

平常的Setters和Getters
下面的例子展现了怎样完成一个自存档对象。当设置temperature属性时,archive数组会猎取日记条目。

function Archiver(){
    var temperatrue = null;
    var aechive = [];
    Obejct.defineProperty(this,'temperatrue',{
        get:function(){
            console.log('get!');
            return temperature;
        },
        set:function(value){
            temperature = value;
            archive.push({val:temperature})
        }
    });
    this.getArchive = function(){return archive}
}
var arc = new Archiver();
arc.temperature;//'get!';
arc.temperature = 11;
arc.temperature = 13;
arc.getArchive();//[{val:11},{val:13}]

或:

var pattern = {
    get:function(){
        return 'I alway return this string,whatever you have assigned'
    },
    set:function(){
        this.myname = 'this is my name string'
    }
}
function TestDefineSetAndGet(){
    Object.defineProperty(this,'myproperty',pattern);
}
var instance = new TestDefineSetAndGet();
instance.myproperty = 'test';
console.log(instance.myproperty);
console.log(instance.myname)

假如接见者的属性是被继续的,他的get和set要领会在子对象的属性被接见或许修正时被挪用。假如这些要领用一个变量存值,该值会被一切对象同享。

function myclass(){}
var value;
Obejct.defineProperty(myclass.prototype,'x',{
    get(){
        return value;
    },
    set(x){
        value = x;
    }
})
var a = new myclass();
var b = new myclass();
a.x=1;
console.log(b.x);//1

在get和set要领中,this指向某个被接见和修正属性的对象。

function myclass(){}
Obejct.defineProperty(myclass.prototype,'x',{
    get(){
        return this.stored_x;
    },
    set(x){
        this.stored_x = x;
    }
});
var a = new myclass();
var b = new myclass();
a.x=1;
console.log(b.x)//undefined

不像接见者属性,值属性一直在对象自身上设置,而不是一个原型。但是,假如一个不可写的属性被继续,它依然能够防备修正对象的属性。

function myclass() {
}
myclass.prototype.x = 1;
Object.defineProperty(myclass.prototype, "y", {
  writable: false,
  value: 1
});
var a = new myclass();
a.x = 2;
console.log(a.x); // 2
console.log(myclass.prototype.x); // 1
a.y = 2; // Ignored, throws in strict mode
console.log(a.y); // 1
console.log(myclass.prototype.y); // 1
    原文作者:Lessong
    原文地址: https://segmentfault.com/a/1190000018607337
    本文转自网络文章,转载此文章仅为分享知识,如有侵权,请联系博主进行删除。
点赞