js中 建構函式,原型,和例項化物件
阿新 • • 發佈:2019-01-07
1,建構函式建立物件造成的記憶體浪費,和原型的引入
function Person(name,age){ this.name = name; this.age = age; this.introduce = function(){ alert('我是'+this.name) }; } var p1 = new Person('小敏',12); var p2 = new Person('小敏',12); var p3 = new Person('小敏',12); //.....................
如上不斷地例項化Person物件,每次例項化都要為intrduce方法開闢新的記憶體空間,這樣做浪費了記憶體空間
下面想了一個辦法,在外部為方法寫一個函式,讓物件中的方法指向這個函式,當物件呼叫方法時,通過屬性指向方法函式所在的地址,
那麼就可以實現多個物件公用一個方法函式
function introduce(){ alert('我是'+this.name); } // var introduce = '你好'; //缺點當其他人定義變數與函式名相同時,會報錯 function Person(name,age){ this.name = name; this.age = age; this.introduce = introduce; } //例項化物件 var p1 = new Person('小敏',12); var p2 = new Person('小明',12); p1.introduce(); //第5行有效 則 這裡會報錯 // console.log(p1.introduce == p2.introduce); //true
上面的程式碼依然存在缺陷,封裝物件後,假如其他人看不到原始碼的情況下,且定義了一個與方法函式名相同的變數,那麼這個程式將會報錯,程式不能正常執行.
下面我們引入原型,prototype
原型存在於每個函式物件中,是函式物件的屬性 函式名.prototype.方法名 = function(){函式體} (當然我們也可以通過這種方式為建構函式新增屬性)
function Person(name,age){ this.name = name; this.age = age; } Person.prototype.introduce = function(){//prototype 原型,模式 alert('我是'+this.name); }; //例項化物件 var p1 = new Person('小敏',12); var p2 = new Person('小明',12); p1.introduce(); console.log(p1.introduce == p2.introduce); //true
3,建構函式 原型 例項化物件 之間的關係
建構函式中存在一個屬性叫 prototype 也就是原型,原型本身又是一個物件,它內部儲存著 constructor 構造器,還用使用者定義的需要共享的屬性以及方法
prototype 原型物件中的constructor屬性 指向的是prototype自己所在的建構函式
在例項化物件中存在著一個叫 __proto__的屬性,同時它本身是一個物件,確切地說 它指向建構函式中的 prototype物件所在的記憶體空間,所以 __proto__ ==Prototype ,
但是__proto__是一個非標準化的物件, 它內部的方法 可以直接 被它的父級物件直接呼叫, 如上段程式碼中 introduce方法在 __proto__物件中, __proto__是p1的屬性, 正常呼叫方式是 p1.__proto__.introduce(), 由於__proto__的非標準化, p1.introduce() 呼叫方法也是行得通的.