JavaScript笔记--数据属性和访问器属性

在JavaScript中最基本的创建一个对象的方法是new一个Object()的实例,然后再为其添加属性与方法,下例创建一个包含属性name的person对象,name属性的特征值为”xiaochang”:

<code class="hljs javascript has-numbering" style="display: block; padding: 0px; color: inherit; box-sizing: border-box; font-family: 'Source Code Pro', monospace;font-size:undefined; white-space: pre; border-top-left-radius: 0px; border-top-right-radius: 0px; border-bottom-right-radius: 0px; border-bottom-left-radius: 0px; word-wrap: normal; background: transparent;"><span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">var</span> person = <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">new</span> <span class="hljs-built_in" style="color: rgb(102, 0, 102); box-sizing: border-box;">Object</span>();
person.name = <span class="hljs-string" style="color: rgb(0, 136, 0); box-sizing: border-box;">"xiaochang"</span>;
person.say = <span class="hljs-function" style="box-sizing: border-box;"><span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">function</span><span class="hljs-params" style="color: rgb(102, 0, 102); box-sizing: border-box;">()</span>{</span>
    console.log(<span class="hljs-string" style="color: rgb(0, 136, 0); box-sizing: border-box;">"Hi, my name is "</span> + <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">this</span>.name);
};
person.say();   <span class="hljs-comment" style="color: rgb(136, 0, 0); box-sizing: border-box;">//Hi, my name is xiaochang</span></code><ul class="pre-numbering" style="box-sizing: border-box; position: absolute; width: 50px; top: 0px; left: 0px; margin: 0px; padding: 6px 0px 40px; border-right-width: 1px; border-right-style: solid; border-right-color: rgb(221, 221, 221); list-style: none; text-align: right; background-color: rgb(238, 238, 238);"><li style="box-sizing: border-box; padding: 0px 5px;">1</li><li style="box-sizing: border-box; padding: 0px 5px;">2</li><li style="box-sizing: border-box; padding: 0px 5px;">3</li><li style="box-sizing: border-box; padding: 0px 5px;">4</li><li style="box-sizing: border-box; padding: 0px 5px;">5</li><li style="box-sizing: border-box; padding: 0px 5px;">6</li></ul>

EAMAScript 5 定义了描述这些属性特征的各类特性,包括数据属性访问器属性。 
数据属性:该属性包含了一个数据值的位置,它包含了4个描述行为的特性: 
1. [[Configurable]]:表示是否能通过delete删除属性从而重新定义属性,能否修改属性的特性,能否把属性修改为访问器属性。 
2. [[Enumerable]]:表示能否用for-in循环返回。 
3. [[writable]]:表示能否修改属性的值。 
4. [[Value]]:包含这个属性的数据值。读取属性值的时候从这个位置读,写入属性值的时候更新到这个位置,默认值为undefined。

直接在对象上定义的属性的数据特性默认如下: 
1. [[Configurable]]:true 
2. [[Enumerable]]:true 
3. [[writable]]:true 
4. [[Value]]:”xiaochang” (初始时的赋值)

这些特性不能直接被访问,要修改属性的特性只能通过Object.defineProperty( )方法,该方法包含三个参数:属性所在的对象,属性的名字,描述符对象[configurable|enumerable|writable|value]。例如:

<code class="hljs cpp has-numbering" style="display: block; padding: 0px; color: inherit; box-sizing: border-box; font-family: 'Source Code Pro', monospace;font-size:undefined; white-space: pre; border-top-left-radius: 0px; border-top-right-radius: 0px; border-bottom-right-radius: 0px; border-bottom-left-radius: 0px; word-wrap: normal; background: transparent;">var person = {
    age:<span class="hljs-number" style="color: rgb(0, 102, 102); box-sizing: border-box;">100</span> 
};

Object.defineProperty(person,<span class="hljs-string" style="color: rgb(0, 136, 0); box-sizing: border-box;">"name"</span>,{
    configurable:<span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">false</span>,
    writable:<span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">false</span>,
    value:<span class="hljs-string" style="color: rgb(0, 136, 0); box-sizing: border-box;">"xiaochang"</span>
});

Object.defineProperty(person,<span class="hljs-string" style="color: rgb(0, 136, 0); box-sizing: border-box;">"tall"</span>,{
    value:<span class="hljs-number" style="color: rgb(0, 102, 102); box-sizing: border-box;">160</span>
});

<span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">for</span>(attr in person){
        console.<span class="hljs-built_in" style="color: rgb(102, 0, 102); box-sizing: border-box;">log</span>(attr); <span class="hljs-comment" style="color: rgb(136, 0, 0); box-sizing: border-box;">//name,age</span>
}
console.<span class="hljs-built_in" style="color: rgb(102, 0, 102); box-sizing: border-box;">log</span>(person.name);   <span class="hljs-comment" style="color: rgb(136, 0, 0); box-sizing: border-box;">//xiaochang</span>
person.name=<span class="hljs-string" style="color: rgb(0, 136, 0); box-sizing: border-box;">"CC"</span>;           <span class="hljs-comment" style="color: rgb(136, 0, 0); box-sizing: border-box;">//为name属性指定新值</span>
console.<span class="hljs-built_in" style="color: rgb(102, 0, 102); box-sizing: border-box;">log</span>(person.name);   <span class="hljs-comment" style="color: rgb(136, 0, 0); box-sizing: border-box;">//xiaochang</span>
<span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">delete</span> person.name;         <span class="hljs-comment" style="color: rgb(136, 0, 0); box-sizing: border-box;">//删除name属性</span>
console.<span class="hljs-built_in" style="color: rgb(102, 0, 102); box-sizing: border-box;">log</span>(person.name);   <span class="hljs-comment" style="color: rgb(136, 0, 0); box-sizing: border-box;">//xiaochang</span>

console.<span class="hljs-built_in" style="color: rgb(102, 0, 102); box-sizing: border-box;">log</span>(person.age);    <span class="hljs-comment" style="color: rgb(136, 0, 0); box-sizing: border-box;">//100</span>
person.age=<span class="hljs-number" style="color: rgb(0, 102, 102); box-sizing: border-box;">200</span>;             <span class="hljs-comment" style="color: rgb(136, 0, 0); box-sizing: border-box;">//为age属性指定新值</span>
console.<span class="hljs-built_in" style="color: rgb(102, 0, 102); box-sizing: border-box;">log</span>(person.age);    <span class="hljs-comment" style="color: rgb(136, 0, 0); box-sizing: border-box;">//200</span>
<span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">delete</span> person.age;          <span class="hljs-comment" style="color: rgb(136, 0, 0); box-sizing: border-box;">//删除age属性</span>
console.<span class="hljs-built_in" style="color: rgb(102, 0, 102); box-sizing: border-box;">log</span>(person.age);    <span class="hljs-comment" style="color: rgb(136, 0, 0); box-sizing: border-box;">//undefined</span>

console.<span class="hljs-built_in" style="color: rgb(102, 0, 102); box-sizing: border-box;">log</span>(person.tall);   <span class="hljs-comment" style="color: rgb(136, 0, 0); box-sizing: border-box;">//160</span>
person.tall = <span class="hljs-number" style="color: rgb(0, 102, 102); box-sizing: border-box;">160</span>;          <span class="hljs-comment" style="color: rgb(136, 0, 0); box-sizing: border-box;">//修改tall属性的值</span>
console.<span class="hljs-built_in" style="color: rgb(102, 0, 102); box-sizing: border-box;">log</span>(person.tall);   <span class="hljs-comment" style="color: rgb(136, 0, 0); box-sizing: border-box;">//160</span>
<span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">delete</span> person.tall;         <span class="hljs-comment" style="color: rgb(136, 0, 0); box-sizing: border-box;">//删除name属性</span>
console.<span class="hljs-built_in" style="color: rgb(102, 0, 102); box-sizing: border-box;">log</span>(person.tall);   <span class="hljs-comment" style="color: rgb(136, 0, 0); box-sizing: border-box;">//160</span></code><ul class="pre-numbering" style="box-sizing: border-box; position: absolute; width: 50px; top: 0px; left: 0px; margin: 0px; padding: 6px 0px 40px; border-right-width: 1px; border-right-style: solid; border-right-color: rgb(221, 221, 221); list-style: none; text-align: right; background-color: rgb(238, 238, 238);"><li style="box-sizing: border-box; padding: 0px 5px;">1</li><li style="box-sizing: border-box; padding: 0px 5px;">2</li><li style="box-sizing: border-box; padding: 0px 5px;">3</li><li style="box-sizing: border-box; padding: 0px 5px;">4</li><li style="box-sizing: border-box; padding: 0px 5px;">5</li><li style="box-sizing: border-box; padding: 0px 5px;">6</li><li style="box-sizing: border-box; padding: 0px 5px;">7</li><li style="box-sizing: border-box; padding: 0px 5px;">8</li><li style="box-sizing: border-box; padding: 0px 5px;">9</li><li style="box-sizing: border-box; padding: 0px 5px;">10</li><li style="box-sizing: border-box; padding: 0px 5px;">11</li><li style="box-sizing: border-box; padding: 0px 5px;">12</li><li style="box-sizing: border-box; padding: 0px 5px;">13</li><li style="box-sizing: border-box; padding: 0px 5px;">14</li><li style="box-sizing: border-box; padding: 0px 5px;">15</li><li style="box-sizing: border-box; padding: 0px 5px;">16</li><li style="box-sizing: border-box; padding: 0px 5px;">17</li><li style="box-sizing: border-box; padding: 0px 5px;">18</li><li style="box-sizing: border-box; padding: 0px 5px;">19</li><li style="box-sizing: border-box; padding: 0px 5px;">20</li><li style="box-sizing: border-box; padding: 0px 5px;">21</li><li style="box-sizing: border-box; padding: 0px 5px;">22</li><li style="box-sizing: border-box; padding: 0px 5px;">23</li><li style="box-sizing: border-box; padding: 0px 5px;">24</li><li style="box-sizing: border-box; padding: 0px 5px;">25</li><li style="box-sizing: border-box; padding: 0px 5px;">26</li><li style="box-sizing: border-box; padding: 0px 5px;">27</li><li style="box-sizing: border-box; padding: 0px 5px;">28</li><li style="box-sizing: border-box; padding: 0px 5px;">29</li><li style="box-sizing: border-box; padding: 0px 5px;">30</li><li style="box-sizing: border-box; padding: 0px 5px;">31</li><li style="box-sizing: border-box; padding: 0px 5px;">32</li><li style="box-sizing: border-box; padding: 0px 5px;">33</li><li style="box-sizing: border-box; padding: 0px 5px;">34</li></ul>

分析例子可知直接在对象上定义的属性,如age,[[Configurable]],[[Enumerable]],[[writable]]都被设置为true。 
属性name的[[Configurable]],[[writable]]被设置为false,所以无法修改和删除。 
调用Object.defineProperty( )方法时,如果不显示指定configurable,enumerable,writable的值,就默认为false,如属性tall。 
另外需要注意的是当configurable设置为false后无法再将其改为true,且除了writable之外,无法修改其它特性。在configurable为true的情况下可多次调用Object.defineProperty( )修改同一属性。 
在非严格情况下修改无法配置的属性操作会被忽略,在严格模式下会抛出错误。

访问器属性:包含getter和setter函数。读取访问器属性时,调用getter函数,返回有效的值;在写入访问器属性时,调用setter函数传入新值。它包含了4个特性: 
1. [[Configurable]]:表示是否能通过delete删除属性从而重新定义属性,能否修改属性的特性,能否把属性修改为访问器属性。 
2. [[Enumerable]]:表示能否用for-in循环返回。 
3. [[Get]]:读取属性时调用的函数,默认undefined。 
4. [[Set]]:写入属性时调用的函数,默认undefined。

getter和setter不一定要成对出现,只有getter函数证明该属性只读不可写,尝试写入在非严格模式下会被忽略,严格模式会抛出错误。相同,只有setter函数证明只写不能读,尝试读在非严格模式下返回undefined,严格模式则抛出错误。

访问器属性无法直接定义,必须使用Object.defineProperty( )来定义,如下:

<code class="hljs actionscript has-numbering" style="display: block; padding: 0px; color: inherit; box-sizing: border-box; font-family: 'Source Code Pro', monospace;font-size:undefined; white-space: pre; border-top-left-radius: 0px; border-top-right-radius: 0px; border-bottom-right-radius: 0px; border-bottom-left-radius: 0px; word-wrap: normal; background: transparent;"><span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">var</span> person = {
    _name:<span class="hljs-string" style="color: rgb(0, 136, 0); box-sizing: border-box;">"xiaochang"</span>, <span class="hljs-comment" style="color: rgb(136, 0, 0); box-sizing: border-box;">//name属性只读不可写</span>
    _age:<span class="hljs-number" style="color: rgb(0, 102, 102); box-sizing: border-box;">100</span>,          <span class="hljs-comment" style="color: rgb(136, 0, 0); box-sizing: border-box;">//age属性只写不可读</span>
    _tel:<span class="hljs-number" style="color: rgb(0, 102, 102); box-sizing: border-box;">123456</span>      <span class="hljs-comment" style="color: rgb(136, 0, 0); box-sizing: border-box;">//tel属性可读可写</span>
};
Object.defineProperty(person,<span class="hljs-string" style="color: rgb(0, 136, 0); box-sizing: border-box;">"name"</span>,{
    <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">get</span>:<span class="hljs-function" style="box-sizing: border-box;"><span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">function</span><span class="hljs-params" style="color: rgb(102, 0, 102); box-sizing: border-box;">()</span>{</span>
        <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">return</span> <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">this</span>._name;
    }
});
Object.defineProperty(person,<span class="hljs-string" style="color: rgb(0, 136, 0); box-sizing: border-box;">"age"</span>,{
    <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">set</span>:<span class="hljs-function" style="box-sizing: border-box;"><span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">function</span><span class="hljs-params" style="color: rgb(102, 0, 102); box-sizing: border-box;">(newage)</span>{</span>
        <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">this</span>._age = newage;
    }
});
Object.defineProperty(person,<span class="hljs-string" style="color: rgb(0, 136, 0); box-sizing: border-box;">"tel"</span>,{
    <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">get</span>:<span class="hljs-function" style="box-sizing: border-box;"><span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">function</span><span class="hljs-params" style="color: rgb(102, 0, 102); box-sizing: border-box;">()</span>{</span>
        <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">return</span> <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">this</span>._tel;
    },
    <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">set</span>:<span class="hljs-function" style="box-sizing: border-box;"><span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">function</span><span class="hljs-params" style="color: rgb(102, 0, 102); box-sizing: border-box;">(newtel)</span>{</span>
        <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">this</span>._tel= newtel;
    }
});
console.log(person.name);   <span class="hljs-comment" style="color: rgb(136, 0, 0); box-sizing: border-box;">//"xiaochang"</span>
person.name = <span class="hljs-string" style="color: rgb(0, 136, 0); box-sizing: border-box;">"CC"</span>;         <span class="hljs-comment" style="color: rgb(136, 0, 0); box-sizing: border-box;">//尝试修改name属性</span>
console.log(person.name);   <span class="hljs-comment" style="color: rgb(136, 0, 0); box-sizing: border-box;">//"xiaochang"</span>
console.log(person.age);    <span class="hljs-comment" style="color: rgb(136, 0, 0); box-sizing: border-box;">//不可读属性,undefined</span>
person.age = <span class="hljs-number" style="color: rgb(0, 102, 102); box-sizing: border-box;">200</span>;           <span class="hljs-comment" style="color: rgb(136, 0, 0); box-sizing: border-box;">//修改age</span>
console.log(person._age);   <span class="hljs-comment" style="color: rgb(136, 0, 0); box-sizing: border-box;">//直接读取对象方法才能访问的属性,可以看到值已更新200</span>
console.log(person.tel);    <span class="hljs-comment" style="color: rgb(136, 0, 0); box-sizing: border-box;">//123456</span>
person.age = <span class="hljs-number" style="color: rgb(0, 102, 102); box-sizing: border-box;">654321</span>;        <span class="hljs-comment" style="color: rgb(136, 0, 0); box-sizing: border-box;">//更新tel</span>
console.log(person.tel);    <span class="hljs-comment" style="color: rgb(136, 0, 0); box-sizing: border-box;">//654321</span></code><ul class="pre-numbering" style="box-sizing: border-box; position: absolute; width: 50px; top: 0px; left: 0px; margin: 0px; padding: 6px 0px 40px; border-right-width: 1px; border-right-style: solid; border-right-color: rgb(221, 221, 221); list-style: none; text-align: right; background-color: rgb(238, 238, 238);"><li style="box-sizing: border-box; padding: 0px 5px;">1</li><li style="box-sizing: border-box; padding: 0px 5px;">2</li><li style="box-sizing: border-box; padding: 0px 5px;">3</li><li style="box-sizing: border-box; padding: 0px 5px;">4</li><li style="box-sizing: border-box; padding: 0px 5px;">5</li><li style="box-sizing: border-box; padding: 0px 5px;">6</li><li style="box-sizing: border-box; padding: 0px 5px;">7</li><li style="box-sizing: border-box; padding: 0px 5px;">8</li><li style="box-sizing: border-box; padding: 0px 5px;">9</li><li style="box-sizing: border-box; padding: 0px 5px;">10</li><li style="box-sizing: border-box; padding: 0px 5px;">11</li><li style="box-sizing: border-box; padding: 0px 5px;">12</li><li style="box-sizing: border-box; padding: 0px 5px;">13</li><li style="box-sizing: border-box; padding: 0px 5px;">14</li><li style="box-sizing: border-box; padding: 0px 5px;">15</li><li style="box-sizing: border-box; padding: 0px 5px;">16</li><li style="box-sizing: border-box; padding: 0px 5px;">17</li><li style="box-sizing: border-box; padding: 0px 5px;">18</li><li style="box-sizing: border-box; padding: 0px 5px;">19</li><li style="box-sizing: border-box; padding: 0px 5px;">20</li><li style="box-sizing: border-box; padding: 0px 5px;">21</li><li style="box-sizing: border-box; padding: 0px 5px;">22</li><li style="box-sizing: border-box; padding: 0px 5px;">23</li><li style="box-sizing: border-box; padding: 0px 5px;">24</li><li style="box-sizing: border-box; padding: 0px 5px;">25</li><li style="box-sizing: border-box; padding: 0px 5px;">26</li><li style="box-sizing: border-box; padding: 0px 5px;">27</li><li style="box-sizing: border-box; padding: 0px 5px;">28</li><li style="box-sizing: border-box; padding: 0px 5px;">29</li><li style="box-sizing: border-box; padding: 0px 5px;">30</li><li style="box-sizing: border-box; padding: 0px 5px;">31</li><li style="box-sizing: border-box; padding: 0px 5px;">32</li></ul>

属性前面的下划线表示只能通过对象方法访问的属性,当我们调用person.name时实际调用了name属性的getter函数(直接调用person._name可得到相同的结果,这样做访问器就没什么意义了)。通过上面例子中可以很清晰的看出属性与访问器之间的关系。

支持Object.defineProperty( )方法的浏览器有IE9+(IE8是第一实现Object.defineProperty( )方法的浏览器,但仅限于DOM对象,且只能创建访问器属性)、Firefox4+、Safari5+,Opera12+、Chrome。在不支持Object.defineProperty( )方法的浏览器中不能修改[[Configurable]],[[Enumerable]]。

在Object.defineProperty( )方法之前,要创建访问器属性,一般使用非标准的方法:__defineGetter__() 和__defineSetter__(),这两个方法最初在Firefox引入,后来chrome1和Opera9.5也支持。改写上面的tel属性访问器如下:

<code class="hljs javascript has-numbering" style="display: block; padding: 0px; color: inherit; box-sizing: border-box; font-family: 'Source Code Pro', monospace;font-size:undefined; white-space: pre; border-top-left-radius: 0px; border-top-right-radius: 0px; border-bottom-right-radius: 0px; border-bottom-left-radius: 0px; word-wrap: normal; background: transparent;">person.__defineGetter__(<span class="hljs-string" style="color: rgb(0, 136, 0); box-sizing: border-box;">"tel"</span>,<span class="hljs-function" style="box-sizing: border-box;"><span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">function</span><span class="hljs-params" style="color: rgb(102, 0, 102); box-sizing: border-box;">()</span>{</span>
    <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">return</span> <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">this</span>._tel;
});
person.__defineSetter__(<span class="hljs-string" style="color: rgb(0, 136, 0); box-sizing: border-box;">"tel"</span>,<span class="hljs-function" style="box-sizing: border-box;"><span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">function</span><span class="hljs-params" style="color: rgb(102, 0, 102); box-sizing: border-box;">(newtel)</span>{</span>
    <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">this</span>._tel = newtel;
});</code><ul class="pre-numbering" style="box-sizing: border-box; position: absolute; width: 50px; top: 0px; left: 0px; margin: 0px; padding: 6px 0px 40px; border-right-width: 1px; border-right-style: solid; border-right-color: rgb(221, 221, 221); list-style: none; text-align: right; background-color: rgb(238, 238, 238);"><li style="box-sizing: border-box; padding: 0px 5px;">1</li><li style="box-sizing: border-box; padding: 0px 5px;">2</li><li style="box-sizing: border-box; padding: 0px 5px;">3</li><li style="box-sizing: border-box; padding: 0px 5px;">4</li><li style="box-sizing: border-box; padding: 0px 5px;">5</li><li style="box-sizing: border-box; padding: 0px 5px;">6</li></ul>

ECMAScript 5还定义Object.defineProperties( )方法,该方法包含两个参数:属性所在的对象,多个属性的名字和其描述符对象组成的对象。其作用于Object.defineProperty( )相同,区别是可一次性定于多个属性。支持该方法的浏览器有IE9+、Firefox4+、Safari5+,Opera12+、Chrome。上面的例子可以改写如下:

<code class="hljs actionscript has-numbering" style="display: block; padding: 0px; color: inherit; box-sizing: border-box; font-family: 'Source Code Pro', monospace;font-size:undefined; white-space: pre; border-top-left-radius: 0px; border-top-right-radius: 0px; border-bottom-right-radius: 0px; border-bottom-left-radius: 0px; word-wrap: normal; background: transparent;"><span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">var</span> person = {
    _name:<span class="hljs-string" style="color: rgb(0, 136, 0); box-sizing: border-box;">"xiaochang"</span>, <span class="hljs-comment" style="color: rgb(136, 0, 0); box-sizing: border-box;">//name属性只读不可写</span>
    _age:<span class="hljs-number" style="color: rgb(0, 102, 102); box-sizing: border-box;">100</span>,          <span class="hljs-comment" style="color: rgb(136, 0, 0); box-sizing: border-box;">//age属性只写不可读</span>
    _tel:<span class="hljs-number" style="color: rgb(0, 102, 102); box-sizing: border-box;">123456</span>      <span class="hljs-comment" style="color: rgb(136, 0, 0); box-sizing: border-box;">//tel属性可读可写</span>
};
Object.defineProperties(person,{
    name:{
        <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">get</span>:<span class="hljs-function" style="box-sizing: border-box;"><span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">function</span><span class="hljs-params" style="color: rgb(102, 0, 102); box-sizing: border-box;">()</span>{</span>
            <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">return</span> <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">this</span>._name;
        }
    },
    age:{
        <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">set</span>:<span class="hljs-function" style="box-sizing: border-box;"><span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">function</span><span class="hljs-params" style="color: rgb(102, 0, 102); box-sizing: border-box;">(newage)</span>{</span>
            <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">this</span>._age = newage;
        }
    },
    tel:{
        <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">get</span>:<span class="hljs-function" style="box-sizing: border-box;"><span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">function</span><span class="hljs-params" style="color: rgb(102, 0, 102); box-sizing: border-box;">()</span>{</span>
            <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">return</span> <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">this</span>._tel;
        },
        <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">set</span>:<span class="hljs-function" style="box-sizing: border-box;"><span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">function</span><span class="hljs-params" style="color: rgb(102, 0, 102); box-sizing: border-box;">(newtel)</span>{</span>
            <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">this</span>._tel= newtel;
        }
    }
});</code><ul class="pre-numbering" style="box-sizing: border-box; position: absolute; width: 50px; top: 0px; left: 0px; margin: 0px; padding: 6px 0px 40px; border-right-width: 1px; border-right-style: solid; border-right-color: rgb(221, 221, 221); list-style: none; text-align: right; background-color: rgb(238, 238, 238);"><li style="box-sizing: border-box; padding: 0px 5px;">1</li><li style="box-sizing: border-box; padding: 0px 5px;">2</li><li style="box-sizing: border-box; padding: 0px 5px;">3</li><li style="box-sizing: border-box; padding: 0px 5px;">4</li><li style="box-sizing: border-box; padding: 0px 5px;">5</li><li style="box-sizing: border-box; padding: 0px 5px;">6</li><li style="box-sizing: border-box; padding: 0px 5px;">7</li><li style="box-sizing: border-box; padding: 0px 5px;">8</li><li style="box-sizing: border-box; padding: 0px 5px;">9</li><li style="box-sizing: border-box; padding: 0px 5px;">10</li><li style="box-sizing: border-box; padding: 0px 5px;">11</li><li style="box-sizing: border-box; padding: 0px 5px;">12</li><li style="box-sizing: border-box; padding: 0px 5px;">13</li><li style="box-sizing: border-box; padding: 0px 5px;">14</li><li style="box-sizing: border-box; padding: 0px 5px;">15</li><li style="box-sizing: border-box; padding: 0px 5px;">16</li><li style="box-sizing: border-box; padding: 0px 5px;">17</li><li style="box-sizing: border-box; padding: 0px 5px;">18</li><li style="box-sizing: border-box; padding: 0px 5px;">19</li><li style="box-sizing: border-box; padding: 0px 5px;">20</li><li style="box-sizing: border-box; padding: 0px 5px;">21</li><li style="box-sizing: border-box; padding: 0px 5px;">22</li><li style="box-sizing: border-box; padding: 0px 5px;">23</li><li style="box-sizing: border-box; padding: 0px 5px;">24</li><li style="box-sizing: border-box; padding: 0px 5px;">25</li></ul>

对于上述讲到的属性特性,ECMAScript 5 给出了可以取得给定属性的描述符的方法Object.getOwnPropertyDescriptor(),该方法包含两个参数:属性所在的对象,要读取其描述符的属性名称。方法返回一个对象。如针对上面的例子可得:

<code class="hljs actionscript has-numbering" style="display: block; padding: 0px; color: inherit; box-sizing: border-box; font-family: 'Source Code Pro', monospace;font-size:undefined; white-space: pre; border-top-left-radius: 0px; border-top-right-radius: 0px; border-bottom-right-radius: 0px; border-bottom-left-radius: 0px; word-wrap: normal; background: transparent;"><span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">var</span> descriptor = Object.getOwnPropertyDescriptor(person,<span class="hljs-string" style="color: rgb(0, 136, 0); box-sizing: border-box;">"tel"</span>);
<span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">for</span>(attr <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">in</span> descriptor ){
    console.log(attr+<span class="hljs-string" style="color: rgb(0, 136, 0); box-sizing: border-box;">":"</span>+descriptor[attr]);
}

运行结果如下:
<span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">get</span>:<span class="hljs-function" style="box-sizing: border-box;"><span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">function</span> <span class="hljs-params" style="color: rgb(102, 0, 102); box-sizing: border-box;">()</span>{</span><span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">return</span> <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">this</span>._tel;}
<span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">set</span>:<span class="hljs-function" style="box-sizing: border-box;"><span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">function</span> <span class="hljs-params" style="color: rgb(102, 0, 102); box-sizing: border-box;">(newtel)</span>{</span><span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">this</span>._tel= newtel;}
enumerable:<span class="hljs-literal" style="color: rgb(0, 102, 102); box-sizing: border-box;">false</span>
configurable:<span class="hljs-literal" style="color: rgb(0, 102, 102); box-sizing: border-box;">false</span></code>
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值