欧美bbbwbbbw肥妇,免费乱码人妻系列日韩,一级黄片

探討:JavaScript ECAMScript5 新特性之get/set訪問器

 更新時(shí)間:2016年05月05日 09:19:21   作者:DaisyWang88  
這篇文章主要介紹了探討:JavaScript ECAMScript5 新特性之get/set訪問器 的相關(guān)資料,需要的朋友可以參考下

EcmaScript5簡(jiǎn)介

首先得先搞清楚ECMAScript是神馬,我們知道JavaScript或者說LiveScript最開始是Netscape搞出來的,后來微軟也跟進(jìn)搞出了Jscript,ScriptEase也有自己的CENvi,這樣就有了三個(gè)版本的瀏覽器Script各行其是,大家懂這個(gè)混亂的,于是乎標(biāo)準(zhǔn)化的問題被提上議事日程。1997年以JavaScript1.1為藍(lán)本的建議被提交到歐洲計(jì)算機(jī)制造商協(xié)會(huì)( E uropean C omputer M anufacturers A ssociation),最后大家載歌載舞搞出了ECMA-262——一種名為ECMAScript的新腳本語言標(biāo)準(zhǔn)。第二年,ISO/IEC(國際標(biāo)準(zhǔn)化組織和國際電工委員會(huì))也采用ECMAScript作為標(biāo)準(zhǔn),此后天下太平,各大瀏覽器廠商以ECMAScript作為各自實(shí)現(xiàn)JavaScript的基礎(chǔ),當(dāng)然只是基礎(chǔ),沒完全按照來,否則我們也不會(huì)有那么多瀏覽器兼容性問題。

ECMAScript5是什么呢?顧名思義跟iPhone5一樣是這個(gè)奇怪東東的第五個(gè)版本,我們現(xiàn)在常用的時(shí)ECMAScript3,相比前兩個(gè)版本這個(gè)版本算是一門正真的編程語言而不是玩具了,變得很流行。

正文:

之前對(duì)get/set的理解一直有誤,覺得get set 是對(duì)象屬性方法??戳藙e人的博客也有很多疑問,今天系統(tǒng)的做了很多測(cè)試終于弄明白了。(自己通過看書和寫demo測(cè)試的,如有不對(duì)歡迎大家批評(píng)指正)

get/set訪問器不是對(duì)象的屬性,而是屬性的特性。大家一定要分清楚。特性只有內(nèi)部才用,因此在javaScript中不能直接訪問他們。為了表示特性是內(nèi)部值用兩隊(duì)中括號(hào)括起來表示如[[Value]]。

1.先簡(jiǎn)單介紹一下屬性的這些特性(這里是簡(jiǎn)單的背書)

(1)數(shù)據(jù)屬性——包含一個(gè)數(shù)據(jù)值的位置。這個(gè)位置可以讀入和寫入值。

數(shù)據(jù)屬性有描述其行為的四個(gè)特性:

[[Configurable]]:是否可配置

[[Enumerable]]:是否可枚舉

 [[Writable]]:是否可讀

[[Value]]: 屬性值    

(2)訪問器屬性屬性——不包含數(shù)據(jù)值,包含一個(gè)getter和setter函數(shù)(這兩個(gè)函數(shù)不是必須的)

訪問器屬性也有描述其行為的四個(gè)特性:

[[Configurable]]:是否可配置

[[Enumerable]]:是否可枚舉

[[Get]]:在讀取屬性時(shí)調(diào)用的函數(shù),默認(rèn)是undefined

[[Set]]:在寫入屬性時(shí)調(diào)用的函數(shù),默認(rèn)是undefined  

2.這里著重介紹[[Get]]/[[Set]]就是我們所說的get/set訪問器

先說一個(gè)書上說的 get/set訪問器行為特點(diǎn):get/set訪問器可以不用定義,不定義也可以讀寫屬性值。也可以只定義一個(gè)。只定義get,則被描述的屬性只可讀,不可寫。只定義set,則被描述的屬性只可寫,不可讀。

(1)我們?cè)瓉淼膅et set方法是這樣的:

function Foo(val){
var value=val;
this.getValue=function(){
return value;
};
this.setValue=function (val){
value=val;
};
}
var obj=new Foo("hello");
alert(obj.getValue());//"hello"
obj.setValue("hi");
alert(obj.getValue());//"hi" 

以上代碼只是利用閉包作用域?qū)崿F(xiàn)的get set 方法,注意是方法即實(shí)例對(duì)象的屬性方法,不是屬性特性。如果不定義,將無法訪問value值

function Foo(val){
var value=val;
/* this.getValue=function(){
return value;
};
this.setValue=function (val){
value=val;
};
*/
}
var obj=new Foo("hello");
alert( obj.value);//undefined

以下例子也是對(duì)象的屬性方法,不是屬性特性。

var obj={
name:"john",
get:function (){
return this.age;
}//只定義了get ,沒有定義set,但是仍然可以讀,寫,name屬性,即使這里是age
//這里這樣定義的方法不會(huì)影響屬性的get,set 特性。只是普通的對(duì)象屬性
};
alert(obj.name);//john 可讀
obj.name="jack";//可寫
alert(obj.name);//jack 

(2)作為訪問器屬性的特性的get/set訪問器。

再說一遍不是對(duì)象的屬性,他們 決定屬性能否、怎么讀寫。如果不設(shè)置也行,就和平時(shí)的讀寫一樣(屬性可讀可

寫,讀寫訪問的都是屬性本身的值)

要改變屬性的get /set 特性,有兩種方式:

a.就是用Object.defineProperty()

var object={
_name:"Daisy" 
};
Object.defineProperty(object,"name",{//這里的方法名name,就表示定義了一個(gè)name屬性(因此才能通過object.name訪問),只定義了getter訪問器,沒有定義[[value]]值
get:function (){//只定義了get 特性,因此只能讀不能寫
return this._name;
}
});
alert(object.name);//"Daisy"
object.name="jack";//只定義了getter訪問器,因此寫入失效
alert(object.name);//"Daisy" 

注意Object.defineProperty(object,pro,{})中的屬性名一定要和object.pro訪問的屬性對(duì)應(yīng)

b.就是用用 get set 關(guān)鍵字:

var object={
_name:"Daisy",
get name(){//這里的方法名name ,就表示定義了一個(gè)name屬性(因此才能通過object.name訪問),只定義了getter訪問器,沒有定義[[value]]值
return this._name;
}//get,set方法只是屬性的特性 ,不是對(duì)象方法,決定屬性能否、怎么讀寫
};
alert(object.name);// Daisy這里去掉下劃線 方法就是Daisy ;加上就是undefined
object.name="jack";//只定義了getter訪問器,因此只能讀不能寫
alert(object.name);//Daisy 

以上兩種方法等效。注意的是以上兩種方法object對(duì)象當(dāng)中都將有有兩個(gè)屬性:_name(有初始值) name(無初始值),通過瀏覽器控制臺(tái)可以看到

那么這個(gè)name屬性實(shí)在什么時(shí)候定義的呢?我們知道Object.defineProperty(object,pro,{})可以給對(duì)象定義一個(gè)新屬性pro,既然get pro(){}/set pro(){}和Object.defineProperty(object,pro,{})等效,則也會(huì)定義一個(gè)新屬性pro .這就是為什么object里面有兩個(gè)屬性的原因。

(3)在此篇文章中網(wǎng)絡(luò)之美 JavaScript中Get和Set訪問器的實(shí)現(xiàn)代碼關(guān)于標(biāo)準(zhǔn)標(biāo)準(zhǔn)的Get和Set訪問器的實(shí)現(xiàn):引發(fā)的思考

我自己也寫了一個(gè)一樣的例子

function Foo(val){
this.value=val;//定義了value屬性 并沒有定義_value
}
Foo.prototype={
set value(val){//注意方法名和屬性名相同,在prototype里定義了value屬性
this._value=val;
},
get value(){//方法名和屬性名相同,在prototype里面定義了value屬性和它的get 特性
return this._value;
}
}; //訪問器返回和設(shè)置的都是_name,這里并沒有定義_name屬性為什么也可以讀可以寫????     
var obj=new Foo("hello");     
alert(obj.value);//"hello"     
obj.value="yehoo";     
alert(obj.value);//"yehoo" 

為了解決以上這個(gè)疑問,做了很多測(cè)試,我們一一來看:

先看這個(gè)例子,在prototype里面只定義get 特性,在obj.value讀value屬性時(shí),在實(shí)例里面尋找沒有,然后在原型里面找到,調(diào)用的是原型的get方法,只能讀不能寫

function Foo(val){
this._value=val;//這里 的屬性是帶下劃線的,初始化實(shí)例對(duì)象的_value屬性,_value屬性可讀可寫
}
Foo.prototype={
// set value(val){//注意方法名和屬性名相同,在prototype里定義了value屬性
// this._value=val;
// },
get value(){//方法名和屬性名相同,在prototype里面定義了value屬性和它的get 特性
return this._value;
}
}; 
var obj=new Foo("hello");
alert(obj.value);//hello 訪問的是prototype里面的value 屬性
obj.value="yehoo";//只定義了name 屬性的get 特性,因此只能讀不能寫,寫入失效
alert(obj.value);//hello 

如果構(gòu)造函數(shù)里面this._value 去掉下劃線,在prototype里面定義的value屬性,定義了get 特性。依然可以控制value屬性的讀寫 。也就是說obj.value訪問屬性時(shí),會(huì)調(diào)用get方法,先在對(duì)象本身尋找,如果沒有,再到prototype尋找,如果都沒有才算沒有定義,默認(rèn)的既可讀又可寫

function Foo(val){
this.value=val;//在原型里面只定義了value的get特性,因此這里寫入失效
}
Foo.prototype={
// set value(val){//注意方法名和屬性名相同,在prototype里定義了value屬性的set特性
// this._value=val;
//},
//value:"hah",//即使手動(dòng)寫入value值,由于get方法返回的是this._value,因此也不能正確讀取value:"hah"
//只要聲明了get pro (){}和set pro (){}屬性就都能讀能寫,但是如果函數(shù)定義錯(cuò)誤,依然不能按要求訪問到正確的屬性值
get value(){//方法名和屬性名相同,在prototype里面定義了value屬性和它的get 特性
return this._value;
}
}; 
var obj=new Foo("hello");//"hello"沒有寫入成功
alert(obj.value);//undefined 
obj.value="yehoo";//只定義了get 特性,因此只能讀不能寫,寫入失效
alert(obj.value);//undefined 

為了證明上面例子是可讀不可寫的:手動(dòng)寫入_value:"hah",就可以讀取value 但不能寫入。

function Foo(val){
this.value=val;//在原型里面只定義了value的get特性,因此這里寫入失效
}
Foo.prototype={
// set value(val){//注意方法名和屬性名相同,在prototype里定義了value屬性的set特性
// this._value=val;
//},
_value:"hah",//即使手動(dòng)寫入value值,由于get方法返回的是this._value,因此也不能正確讀取value:"hah"
//只要聲明了get pro (){}和set pro (){}屬性就都能讀能寫,但是如果函數(shù)定義錯(cuò)誤,依然不能按要求訪問到正確的屬性值
get value(){//方法名和屬性名相同,在prototype里面定義了value屬性和它的get 特性
return this._value;
}
}; 
var obj=new Foo("hello");//"hello"沒有寫入成功
alert(obj.value);//"hah" 
obj.value="yehoo";//只定義了get 特性,因此只能讀不能寫,寫入失效
alert(obj.value);//"hah" 

如果手動(dòng)寫入的是value:"hah",那么可以爭(zhēng)取讀取value的值嗎?由于get方法返回的this._value并沒有定義,obj.value讀取value值調(diào)用get value(){}方法失效,但是value仍然不能寫入。

function Foo(val){
this.value=val;//在原型里面只定義了value的get特性,因此這里寫入失效
}
Foo.prototype={
// set value(val){//注意方法名和屬性名相同,在prototype里定義了value屬性的set特性
// this._value=val;
//},
value:"hah",//即使手動(dòng)寫入value值,由于get方法返回的是this._value,因此也不能正確讀取value:"hah"
//只要聲明了get pro (){}和set pro (){}屬性就都能讀能寫,但是如果函數(shù)定義錯(cuò)誤,依然不能按要求訪問到正確的屬性值
get value(){//方法名和屬性名相同,在prototype里面定義了value屬性和它的get 特性
return this._value;
}
}; 
var obj=new Foo("hello");//"hello"沒有寫入成功
alert(obj.value);//undefined 讀取失效 因?yàn)橹灰猳bj.value就會(huì)調(diào)用get ,而get返回的是this._value,沒有這個(gè)值,因此undefined
obj.value="yehoo";//只定義了get 特性,因此只能讀不能寫,寫入失效
alert(obj.value);//undefined 

再看這個(gè)例子,get set 都定義了,但是返回沒有定義的this._value??梢园l(fā)現(xiàn)value既可讀又可寫。去掉原型里面的get set方法,依然可讀可寫

function Foo(val){
this.value=val;
}
Foo.prototype={
set value(val){
this._value=val;
},
get value(){
return this._value;
}
}; 
var obj=new Foo("hello");
alert(obj.value);//hello 
obj.value="yehoo";
alert(obj.value);//yehoo 
function Foo(val){
this.value=val;
}
//和平時(shí)的操作是一樣的了,就是回到了不定義get /set訪問器特性的默認(rèn)狀態(tài)
var obj=new Foo("hello");
alert(obj.value);//hello 
obj.value="yehoo";
alert(obj.value);//yehoo 

總結(jié)

只聲明了get pro(){}屬性 可讀不可寫;

只聲明 set pro(){}屬性可寫不可讀。

如果都不聲明,屬性可讀可寫;

如果都聲明就按照,get set 定義的方法,讀寫;

如果都聲明了,但是定義的讀寫方法不能正確讀寫,get/set失效。變成默認(rèn)的可讀可寫

在prototype里面定義的value屬性,定義了get 特性。依然可以控制value屬性的讀寫 。也就是說obj.value訪問屬性時(shí),會(huì)調(diào)用get方法,先在對(duì)象本身尋找,如果沒有,再到prototype尋找,如果都沒有才算沒有定義,默認(rèn)的既可讀又可寫。

補(bǔ)充:

不管是用get pro(){}/set pro (){} 

還是用Object.defineProperty(object,pro,{


         get:function (){
           return this._name;
           } });

pro不能和 return this. 后面的屬性一樣,不然會(huì)報(bào)下面的錯(cuò)誤:(具體我也不知道為什么,好像是自身調(diào)用引起的棧溢出)

經(jīng)大神指正,明白為什么這里報(bào)錯(cuò):在get value(){}方法里返回 this.value,就會(huì)又去調(diào)用value的get 方法,因此陷入死循環(huán),造成方法棧溢出。

  • 淺談JavaScript中內(nèi)存泄漏的幾種情況

    淺談JavaScript中內(nèi)存泄漏的幾種情況

    本文主要介紹了淺談JavaScript中內(nèi)存泄漏的幾種情況,文中通過示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧
    2023-04-04
  • JS中setTimeout的巧妙用法前端函數(shù)節(jié)流

    JS中setTimeout的巧妙用法前端函數(shù)節(jié)流

    這篇文章主要介紹了JS中setTimeout的巧妙用法前端函數(shù)節(jié)流 的相關(guān)資料,需要的朋友可以參考下
    2016-03-03
  • 用客戶端js實(shí)現(xiàn)帶省略號(hào)的分頁

    用客戶端js實(shí)現(xiàn)帶省略號(hào)的分頁

    帶省略號(hào)的分頁只有在服務(wù)器端才可以實(shí)現(xiàn),下面為大家介紹的是用js實(shí)現(xiàn)的帶省略號(hào)的分頁,感興趣的朋友可以參考下哈,希望對(duì)你寫出好的分頁有所幫助
    2013-04-04
  • ?JavaScript?數(shù)據(jù)結(jié)構(gòu)之散列表的創(chuàng)建(2)

    ?JavaScript?數(shù)據(jù)結(jié)構(gòu)之散列表的創(chuàng)建(2)

    這篇文章主要介紹了?JavaScript?數(shù)據(jù)結(jié)構(gòu)之散列表的創(chuàng)建,主要看如何處理散列值沖突的問題,并實(shí)現(xiàn)更完美的散列表。下文詳細(xì)介紹需要的小伙伴可以參考一下
    2022-04-04
  • IE view-source 無法查看看源碼 JavaScript看網(wǎng)頁源碼

    IE view-source 無法查看看源碼 JavaScript看網(wǎng)頁源碼

    查看網(wǎng)頁源代碼的方法其實(shí)有好幾種,最常用的我們就是在瀏覽器中直接選擇“查看網(wǎng)頁源代碼”就可以了,但是在有些時(shí)候這種方法卻不能見效,以下再介紹幾種簡(jiǎn)單的方法供大家參考!
    2009-07-07
  • JS控制TreeView的結(jié)點(diǎn)選擇

    JS控制TreeView的結(jié)點(diǎn)選擇

    這篇文章主要為大家詳細(xì)介紹了JS控制TreeView的結(jié)點(diǎn)選擇,具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下
    2016-11-11
  • js html5 css俄羅斯方塊游戲再現(xiàn)

    js html5 css俄羅斯方塊游戲再現(xiàn)

    這篇文章主要為大家詳細(xì)介紹了js html5 css俄羅斯方塊游戲?qū)崿F(xiàn)代碼,文中示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下
    2016-10-10
  • 處理文本部分內(nèi)容的TextRange對(duì)象應(yīng)用實(shí)例

    處理文本部分內(nèi)容的TextRange對(duì)象應(yīng)用實(shí)例

    TextRange是用來表現(xiàn)HTML元素中文字的對(duì)象,是一個(gè)用于處理JavaScript對(duì)象文本部分內(nèi)容的一個(gè)對(duì)象
    2014-07-07
  • Js獲取下拉框選定項(xiàng)的值和文本的實(shí)現(xiàn)代碼

    Js獲取下拉框選定項(xiàng)的值和文本的實(shí)現(xiàn)代碼

    本篇文章主要是對(duì)Js獲取下拉框選定項(xiàng)的值和文本的實(shí)現(xiàn)代碼進(jìn)行了介紹,需要的朋友可以過來參考下,希望對(duì)大家有所幫助
    2014-02-02
  • 最新評(píng)論