Js是函式式語言,并不是傳統的面對物件語言,如Java等等,所以在js中有一些比較獨特的面對物件實作方法,
面對物件有多個特點,如封裝,繼承,多型等,由于js的oop特性并不明顯,所以僅敘述繼承在js中的實作,
眾所周知,js中函式也可以是類,通過new在堆中手動開辟空間就是物件的實體,而且,每個物件都天生有一個指標,指向原型,原型也可以理解為一個物件,可以定義自己的方法,如下圖所示,不再贅述,詳細可以參考廖雪峰教程,

function Person(name){
this.name = name||'unnamed';
}
function Student(name,grade){
Person.call(this,name);
this.grade = grade||1;
}
Person.prototype.getname = function(){
return this.name;
}
function f(){}
// 令f的原型指向Person的原型
f.prototype = Person.prototype;
// 令student的原型指向f的實體
Student.prototype = new f();
// 重置建構式為Student
Student.prototype.constructor = Student;
// 必須在改變原型指標后再定義函式,否則無法訪問到
Student.prototype.getgrade = function(){
return this.grade;
}
var xm = new Student('xm',2);
console.log(new f().__proto__) // Person {getname:[Function]}
console.log(new f().__proto__==Person.prototype) // true
console.log(xm.getname()) // xm
console.log(xm.getgrade()) // 2
console.log(xm.__proto__==Student.prototype) // true
console.log(xm.__proto__.__proto__==Person.prototype) // true
上述程序可以用原型鏈來理解,起初Student的原型鏈為
new Student() ---> Student.prototype ---> Object ---> null
其中一定要引入新的f函式繞一下的原因是如果暴力引入
Student.prototype = Person.prototype
那么就失去了繼承和共享原型的意義,原型鏈變成了
new Student() ---> Person.prototype ---> Object ---> null
我們希望原型鏈是
new Student() ---> Student.prototype ---> Person.prototype ---> Object ---> null
這條原型鏈就很好的共享了Person的原型,如果要創建更多的物件,如工人,就也可以用到Person原型的方法了,十分方便,
對于這些代碼,其實有一個最好的理解方式,即將這些指標等等程序理解為記憶體中的變化即可,以原型鏈的更改為例
- new student().__proto__指向的是Student.prototype變數,這是靜態的,記憶體中的一個名稱
- Student.prototype指標變數含有一個地址,這是動態的,前面通過指向new f()指向了Person.prototype,所以Student.prototype記憶體其實包含兩部分,一部分是本身的原型方法,另一部分指向Person的原型指標
轉載請註明出處,本文鏈接:https://www.uj5u.com/ruanti/298811.html
標籤:其他
上一篇:Redis 基礎知識介紹
下一篇:Redis 基礎知識介紹
