国产av日韩一区二区三区精品,成人性爱视频在线观看,国产,欧美,日韩,一区,www.成色av久久成人,2222eeee成人天堂

javascript - 關(guān)於js中組合使用建構(gòu)函式模式和原型模式的寫法
曾經(jīng)蠟筆沒有小新
曾經(jīng)蠟筆沒有小新 2017-05-19 10:33:10
0
5
724

高階程式設(shè)計(jì)裡面的寫法是下面這樣的

function Person(name,age,job){
    this.name = name;
    this.age = age;
    this.job = job;
    this.lessons = ['Math','Physics'];
}
Person.prototype = {
    constructor: Person,
    getName: function(){
        return this.name;
    }
}

那我像下面這樣寫是不是一樣的,差別只在於他們的constructor不一樣?

function Person(name,age,job){
    this.name = name;
    this.age = age;
    this.job = job;
    this.lessons = ['Math','Physics'];
    Person.prototype.getName = function(){
        return this.name;
    }
}
曾經(jīng)蠟筆沒有小新
曾經(jīng)蠟筆沒有小新

全部回覆(5)
洪濤

prototype定義(的位置)寫在構(gòu)造函數(shù)內(nèi)或外的區(qū)別 ?

第二種寫法每次建立實(shí)例都會執(zhí)行一遍對prototype的操作! 關(guān)鍵是這個(gè)操作很沒意義,這個(gè)方法對每個(gè)實(shí)例都是相同的。
第一種方法中, 當(dāng)prototype在構(gòu)造函數(shù)外面書寫時(shí),可以從形式上和內(nèi)存分配中解決重複定義或分配內(nèi)存的問題。
對應(yīng)在記憶體中,第一種寫法,無論你創(chuàng)建了多少實(shí)例,每個(gè)實(shí)例佔(zhàn)據(jù)空間只是name, age,job和lessons。 getName在記憶體中只有一份,所有實(shí)例共用; 第二種寫法,每個(gè)新建立的實(shí)例會分配一塊額外的空間(堆疊)來執(zhí)行prototype的定義。

prototype在第一種方法中賦值的方式和第二種方法有何不同?

區(qū)別很大的,一個(gè)function類別定義好,它預(yù)設(shè)的 constructor屬性就是自己, 它的實(shí)例在存取constructor屬性時(shí)會傳回這個(gè)值。

function Person() {};
console.log(Person.prototype.constructor);  // Person

var p = new Person();
console.log(p.constructor);   // Person    表示p的構(gòu)造函數(shù)是Person類

方法1中為什麼要定義constructor? 因?yàn)樗oprototype重新賦值了,如果你不定義constructor(Person.prototype = {getName: function() {}}),那么上例中p.constructor返回值將是 Object, 即p的構(gòu)造函數(shù)是Object,顯然與事實(shí)不符。

方法1更明智的做法是不要重新給prototype賦值,只為prototype添加我們需要的屬性getName, 改為 Person.prototype.getName = function() {return this.name;},也就是第二種方法裡的定義方法,這麼寫就不會覆蓋prototype的預(yù)設(shè)屬性。

習(xí)慣沉默

雷雷

PHPzhong

前一種寫法重寫了prototype,而你的寫法只是在prototype裡增加了一個(gè)方法而已,兩個(gè)是不同的方式

世界只因有你

按照你的寫法會在每一次實(shí)例化過程中重新再分配存儲空間給實(shí)例,而原型模式的意義之一在於所有實(shí)例都可以共享原型上的屬性和方法,雖然單獨(dú)這麼做有缺陷。第二點(diǎn)就是我還是傾向於給原型物件物件字面量的寫法,個(gè)人認(rèn)為一個(gè)是比較直觀,第二是有利於維護(hù)。如下:

    Person.prototype = {
        constructor: Person,
        getName: function(){
            return this.name;
        }
    }

一定要寫constructor屬性,不然會發(fā)生指向的錯誤,此時(shí)是重寫了原型對象,如果不指明這個(gè)屬性就無法起到原型鏈應(yīng)有的作用。

為情所困

原型繼承和構(gòu)造函數(shù)有很多的不同,原型繼承即原型鏈繼承。

原型鏈並非十分完美, 它包含如下兩個(gè)問題.

問題一: 當(dāng)原型鏈中包含引用類型值的原型時(shí),該引用類型值會被所有實(shí)例共享;

問題二: 在創(chuàng)建子類型(例如創(chuàng)建Son的實(shí)例)時(shí),不能向超類型(例如Father)的建構(gòu)函數(shù)中傳遞參數(shù).

有鑑於此, 實(shí)踐中很少會單獨(dú)使用原型鏈.

為此,下面將有一些嘗試以彌補(bǔ)原型鏈的不足.

借用建構(gòu)子

為解決原型鏈中上述兩個(gè)問題, 我們開始使用一種叫做借用構(gòu)造函數(shù)(constructor stealing)的技術(shù)(也叫經(jīng)典繼承).

基本思想:即在子型別建構(gòu)函式的內(nèi)部呼叫超型別建構(gòu)函式.

function Father(){
    this.colors = ["red","blue","green"];
}
function Son(){
    Father.call(this);//繼承了Father,且向父類型傳遞參數(shù)
}
var instance1 = new Son();
instance1.colors.push("black");
console.log(instance1.colors);//"red,blue,green,black"

var instance2 = new Son();
console.log(instance2.colors);//"red,blue,green" 可見引用類型值是獨(dú)立的

很明顯,借用構(gòu)造函數(shù)一舉解決了原型鏈的兩大問題:

其一, 保證了原型鏈中引用類型值的獨(dú)立,不再被所有實(shí)例共享;

其二, 子類型創(chuàng)建時(shí)也能夠向父類型傳遞參數(shù).

隨之而來的是, 如果僅僅借用構(gòu)造函數(shù),那麼將無法避免構(gòu)造函數(shù)模式存在的問題--方法都在構(gòu)造函數(shù)中定義, 因此函數(shù)復(fù)用也就不可用了.而且超類型(如Father )中定義的方法,對子類型而言也是不可見的. 考慮此,借用構(gòu)造函數(shù)的技術(shù)也很少單獨(dú)使用.
更多請參考JS原型鏈與繼承別再被問倒了,喜歡就點(diǎn)讚支持一下,謝謝!

最新下載
更多>
網(wǎng)站特效
網(wǎng)站源碼
網(wǎng)站素材
前端模板