JavaScript 面向物件(一)——原型
一、類,物件,函式
var obj = {};//物件
obj.num = 10;//js物件中成員的增加,可以通過直接賦值實現
console.log(obj);
console.log(window);
執行結果:
obj可以看做window的一個成員。
//fun是一個函式 var fun = function () {}; //funObj是function的物件,執行結果證明它也是一個匿名函式 var funObj = new Function; //klass是fun的物件,所以fun既是函式又是類 var klass = new fun; console.log(klass instanceof fun); console.log(window); //屬性caller:是對fun的高階呼叫 //屬性lenght:引數個數
執行結果:
所以javaScript中函式既是類也是物件。
//一個函式也是類
function Klass() {
this.num = 3;//類中寫了一個成員
}
var obj = new Klass;//new一個物件
console.log(window);
執行結果:
執行結果中,類裡沒有num這個成員,而物件中有。
這是因為在var obj = new Klass; 時,實際上是申請了一段例項空間,將其首地址賦值給了物件obj。此時需要執行Klass的構造方法,而構造方法就是這個函式本身,( object.method)這個方法現在有字首(obj),就相當於呼叫這個函式,誰呼叫,this就是誰。所以現在this指的是obj,obj有了num成員,並不是一開始就給Klass加好的成員。
二、prototype,proto
var Fun = function() {};
var fun = new Fun;
console.log(window);
執行結果:
可以看到prototype是object型別,屬於Fun的一個成員,它其中有constructor,又指向了Fun本身。而fun中沒有這個prototype。
var Fun = function() {}; var fun = new Fun; console.log("fun.prototype:", fun.prototype); console.log("Fun.prototype:", Fun.prototype); console.log("fun.__proto__:", fun.__proto__); console.log(window);
執行結果:
所以類有prototype屬性(即原型物件),而物件沒有。
由上面執行結果可以看到和prototype__proto__兩個一模一樣。證明了物件有一個__proto__屬性,不顯示卻存在(加下劃線的就是不想讓外部使用,儘量不要用),它是一個指標,指向類的prototype物件(物件其實就是一個指標,指向某個空間;prototype所指向的空間稱為原型空間)。那麼一個類的多個物件的__proto__均指向類的prototype成員,而prototype作為一個成員也一定有自己的隱含的__proto__。
var Fun = function() {};
var one = new Fun;
var two = new Fun;
//給類的原型物件增加成員
Fun.prototype.member = "這是一個新加的成員";
console.log("Fun.prototype.member", Fun.prototype.member);
one.member = "one更改了成員!";
two.member = "two更改了成員!";
//給one和two別增加了member成員,各自修改了自己成員的值
two.__proto__.member = "你變不變";
//更改了Fun的prototype的member
console.log("****************");
console.log("Fun.prototype.member", Fun.prototype.member);
console.log("Fun.member", Fun.member);
console.log("two", two);
console.log("one", one);
執行結果:
由結果可以得出member不是Fun的!原型型別的成員(就是prototype裡的成員)通過類型別名稱必須要加prototype(類型別.prototype.成員名稱),否則JavaScript不會自動查詢,也就無法使用。
三、JavaScript處理左值和右值
eg: a.b = c.d
a.b 為左值,JavaScript裡的各種值實際上就是鍵值對,左值即空間,可以把值裝入,也就是鍵值對中的鍵,在a中查詢鍵b,若找到了就將右值賦給它,將原來的值覆蓋;找不到則新增一個鍵(成員),將右值賦給它。
c.d在此時代表一個值,實際上右值也是空間,一個鍵,在c中查詢d如果找到,將其中的值取出,使用;如果找不到就沿著__proto__去原型空間中查詢,而prototype也有__proto__,如果找不到就繼續順著原型鏈去父類的原型空間查詢,直到遍歷全部的原型空間,均未查到,則該右值為undefined。
四、原型鏈
指導:mec
如有錯誤,請指正,謝謝。