python入門python的基本語法
617
2025-03-31
今天重讀了一下<
ECMAScript中沒有類的概念,因此它的對象也與基于類的語言中的對象有所不同.ECMA-262將對象定義為:"無序屬性的集合,其屬性可以包含基本值,對象和函數".
ECMAScript中有二種屬性:數據屬性和訪問器屬性.為了表示這些特性是內部值,規范把他們放在了二對方括號中如[[ Enmerable]]
1:數據屬性,數據屬性包含一個數值的位置,在這個位置可以讀取和寫入值,數據屬性有4個描述行為的特性.
[[Configurable]] :表示能否通過delete刪除屬性從而從新定義屬性,能否修改屬性的特性,或者能否把屬性修改為訪問器屬性,默認值為true
[[Enumerable]] : 表示能否通過for-in循環返回屬性,默認為true
[[Writable]] :表示能否修改屬性的值,默認true
[[Value]] : 包含這個屬性的值,讀取屬性值的時候,從這個位置讀,寫入屬性值得時候,把新值保存在這個位置.默認undefined
例子:
var person={};
Object.defineProperty(person,"name",{
writable:false,
value:'Nicholas'
})
alert(person.name) //Nicholas
person.name="Tom"
alert(person.name) //Nicholas
由于Person的數據屬性writable為false 所以不允許修改其值,即使賦新值也會返回舊值,嚴格模式下報錯,使用delete 刪除person.name也是返回舊值.
一旦將屬性設置為不可配置就不能再變回可配置了,
2:訪問器屬性,訪問器屬性不包含數據值,他們包含一對getter和setter函數,在讀取訪問器屬性時,會調用getter函數,這個函數負責返回有效的值,在寫入訪問器屬性時,會調用setter函數并傳入新值,這個函數負責決定如何處理數據,
[[Configurable]]? : 表示能否通過delete刪除屬性從而從新定義屬性,能否修改屬性的特性,或者能否把屬性修改為數據屬性,默認true.
[[Enumerable]]? ?: 表示能否通過for-in循環返回屬性,默認true.
[[Get]] : 在讀取屬性時調用的函數,默認undefined
[[Set]]? : 在寫入屬性時調用的函數,默認undefined
var book={
_year:2004,
edition:1
}
Object.defineProperty(book,"year",{
get:function(){
return this._year
},
set:function(newValue){
if(newValue>2004){
this._year=newValue;
this.edition+=newValue-2004;
}
}
})
book.year=2005;
alert(book.edition) //2
book對象的_yaer 帶有下橫線,表示內部屬性,在book的訪問器屬性year則包含一個getter 和setter函數,這個使用訪問器屬性的常見方法,Vue的監聽對象變化就是用的這一屬性.
定義多個屬性:
var boo={};
Object.defindeProperties(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
}
}
}
});
以上例子即使同時定義對象的多個屬性,
讀取屬性的特性,
使用Object.getOwnPropertyDescriptor()方法可以取得給定屬性的描述符,接受二個參數,屬性所在的對象,要讀取器描述符的屬性名稱,,返回一個對象,包含configurable,enumerable,get 和set 如果是數據屬性,返回configurable,enumerable,writable,value
如 var des=Object.getOwnPropertyDescriptor(book,"_year");
工廠模式
function createPerson(name,age,job){
var o=new Object();
o.name=name;
o.age=age;
o.job=job;
o.sayName=function(){
alert(this.name);
}
return o;
}
工廠模式雖然解決了創建多個相似對象的問題,但沒有解決對象識別的問題,
構造函數模式
function Person(name,age,job){
this.name=name;
this.age=age;
this.job=job;
this.sayName=function(){
alert(this.name);
}
}
var person1=new Person('Tom',25,'Doctor');
與工廠模式相比,沒有顯式創建對象,直接將屬性和方法賦給this對象,沒有return語句
使用new創建的實例,constructor屬性指向Person 可以用來檢查數據類型,但使用instanceof 操作符更可靠, 創建自定義的構造函數意味著將來可以將它的實例標識為一種特定的類型,而這是構造函數模式勝過工廠模式的地方.
使用構造函數的主要問題就是每個方法都要在每個實例上重新創建一遍.
原型模式 我們創建的每個函數都有一個prototype(原型)屬性 這個屬性是一個指針,指向一個對象,而這個對象的用途是包含可以由特定類型的所有實例共享的屬性和方法. 按照字面意思理解,prototype就是通過調用構造函數而創建的那個對象實例的原型對象.
function Person(){
}
Person.prototype.name="Tom"
Person.prototype.age=25
Person.prototype.job="Doctor"
Person.prototype.sayName=function(){
alert(this.name)
}
var person1=new Person();
理解原型對象
只要創建一個新的函數,就會根據一組特定的規則為該函數創建一個prototype屬性,這個屬性指向函數的原型對象,在默認情況下,所有原型對象都會自動獲得一個constructor屬性,這個屬性包含一個指向prototype屬性所在函數的指針.
從本質上講,如果[[Prototype]]指向調用isPrototypeOf()方法的對象那么這個方法就返回true.
當為對象實例添加一個屬性時,這個屬性就會屏蔽原型對象中保存的同名屬性.換句話說,添加這個是屬性只會阻止我們訪問原型中的那個屬性,但不會修改那個屬性.使用hasOwnProperty()方法可以檢測一個屬性市場存在實例中,還是存在原型中.
有兩種方式使用in操作符:單獨使用和在for-in 循環中使用.單獨使用時in操作符會在通過對象能夠訪問給定屬性時返回true,無論屬性存在于實例還是原型中.
如果你想要獲取所有實例屬性,無論是否枚舉,可以使用Object.getOwnPropertyNames()
更簡單的原型語法
function Person(){}
Person.prototype={
name:'Tom',
age:25,
job:'Doctor',
sayName:function(){
alert(this.name)
}
}
這種簡便的原型寫法,constructor屬性不在指向Person了,可以顯式地將原型的constructor設置為本身,但是這種寫法會使constructor的屬性[[Enumerable]] 特性被設置為true,
原型的動態性表明你可以隨時向原型中添加屬性,屬性會立即反應到實例中,但是如果重寫原型對象,就會切斷原型與實例的聯系,導致報錯.
原型對象的問題在于由共享的本性導致的.如果原型的屬性值為對象的話,那么所有實例的這個屬性都指向同一個屬性,統一修改.
未完待續.....
Prototype 面向對象編程
版權聲明:本文內容由網絡用戶投稿,版權歸原作者所有,本站不擁有其著作權,亦不承擔相應法律責任。如果您發現本站中有涉嫌抄襲或描述失實的內容,請聯系我們jiasou666@gmail.com 處理,核實后本網站將在24小時內刪除侵權內容。
版權聲明:本文內容由網絡用戶投稿,版權歸原作者所有,本站不擁有其著作權,亦不承擔相應法律責任。如果您發現本站中有涉嫌抄襲或描述失實的內容,請聯系我們jiasou666@gmail.com 處理,核實后本網站將在24小時內刪除侵權內容。