1. 程式人生 > >JavaScript 面向物件(一)——原型

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
如有錯誤,請指正,謝謝。