標籤:inf blog 有意思 影響 知識 內容 start 列印 解構
總的來說js語言就是門物件導向編程的語言,對象這個概念幾乎貫穿了整個js的學習。
對象
建立對象兩種方法:(若要產生對象執行個體必須調用建構函式)
1、var obj = {name:"jer" , age:12};(在js內部調用了預設的Object()建構函式)
訪問:alert(obj.name);//"jer"
alert(obj["name"]);//"jer"
2、var obj = new Object();
obj.name="jer";
列印結果:
1>上述就是通過原型鏈遍曆出來object建構函式的原型對象屬性和方法
2> prototype指定了這個建構函式執行個體繼承了哪個對象(執行個體)
3> obj.Object.prototype就可以訪問到這個繼承對象下的屬性
4>_proto_:原型連結點,是執行個體的屬性。它的值是由prototype決定的,修改Prototype的值可以操作這個原型鏈的指向。
重點說第二個方法:
var obj = new Object();
//Object()是一個建構函式
//obj是這個建構函式的一個執行個體
//這個建構函式還可以有更多執行個體:var obj1 = new Object(); var obj2 = new Object();
//obj1和obj2的特性:
1、共同繼承了Object()這個建構函式的方法及屬性(object是所有對象的基本類型。所以這就是為什麼很多個物件有著共同的繼承屬性);
2、修改obj1執行個體的建構函式的屬性不會影響obj2的那個屬性(從建構函式那裡擷取來的屬性變成了這個執行個體的屬性,修改每個執行個體上的屬性,不會互相影響)
3、它倆有著共同的原型對象:Object.prototype
4、修改obj1的原型屬性不會影響obj2
5、原型裡方法的this指向這個建構函式的執行個體對象
//通過列印更好理解:
列印結果:
第一個原型鏈指向了Per的原型對象,這個原型對象包括兩個屬性和一個繼承的原型對象,這個對象就是Object執行個體(也可以說是Object建構函式的屬性及方法)
Per.prototype.constructor返回的是建構函式,per1.prototype返回undefined,因為prototype是建構函式的屬性
constructor是原型對象的屬性,用來指向建構函式
//還有一種封裝prototype對象屬性的寫法,這個寫法是重新編寫了原型對象:
在執行個體之後添加這種寫法,執行個體訪問不到原型對象的屬性
下面這個例子是在重寫原型對象之前建立的執行個體:
列印
因為執行個體上面沒有給屬性,所以直接向上尋找列印出來建構函式的屬性,列印的內容包括建構函式內定義的屬性和原型鏈上的屬性
展開
原型鏈上的屬性有原型對象屬性name和內建屬性constructor(指向建構函式)還有個繼承的Object執行個體
constructor指代的建構函式包含函數自身的屬性和重新定義的原型對象(prototype屬性),應為是在原型鏈上重新封裝了原型對象,這個新原型對象也會繼承Object
重點:後面兩個列印的都返回undefined
第一個undefined是因為,執行個體在重寫的原型對象之前定義的,重寫原型對象就意味著切斷了執行個體和本來的原型之間的聯絡,執行個體繼承不到新原型對象的屬性
第二個undefined是因為,prototype是建構函式的屬性
重寫:將建立執行個體放到重寫原型對象下面
列印:
因為執行個體是在重寫原型對象之後定義的,所以執行個體能夠訪問到新原型對象裡的屬性。還有個有意思的是,這個執行個體繼承的建構函式的原型裡面只有重寫的原型對象的屬性,Per.prototype.name="cuz";訪問不到。
執行個體若是能繼承重新封裝建構函式的原型對象,那麼它的原型屬性只在這個對象裡
//深入理解建構函式:
先來看個例子:
列印
從上述例子提取到的知識點有:
1、用建構函式名字新建立的屬性沒有用。
2、設定原型函數的屬性語句放在函數裡面還是外面同樣有效
3、執行個體建立屬性放置在建立執行個體之後也還是會被訪問到,(因為是全域屬性,雖然start方法是在第一個列印的執行個體之後調用的)
這些知識架構無所謂對象,對象裡包含屬性方法,這個屬性方法又包含對象,對象又...每個屬性方法又有不同的知識結構,然後各種訪問調用各種特性,組成了js編程的一張大網,不要忘了函數其實也是個對象。建構函式和其他函數沒有區別,只是用來產生對象執行個體。
快速理解JavaScript物件導向編程—原型繼承