2012-12-20 58 views
1

我dindn't知道一個更好的標題,所以要解釋它之間的原始值, 可以說你有一個「構造」,這部分繼承 - 分享對象

  • 實例化一個對象,並設置一些屬性
    • 在創建annother對象Instatiation的過程
    • 這個對象的原型應該陰影的一些屬性從第一對象給他的孩子

所以當propertie num第一對象改變其他對象樣機propertie num 也應該被

改變,這將在num案件過程中工作是

  • 包裹在一個對象
  • 非原始對象的特性/元素

但如果num將是一個數或字符串

如果num將在第一對象作爲原始瓦爾作爲值傳遞,而不是通過引用,或者如果propertie被重寫的樣機的propertie不會改變是一個對象,將與新的對象覆蓋

所以我的問題是 是那裏可以讓一個對象從另一個對象繼承屬性的原始值,並讓他們分享一個參考任何「整齊」的方式?

下面是一些示例代碼,你可以跳過第一個,它在這裏的代碼

/* Inheritance Helper*/ 

var base = (function baseConstructor() { 

    var obj = { 
    create:function instantiation() { 
     if(this != base) { 
     var instance = Object.create(this.pub); 
     this.init.apply(instance,arguments); 
     this.instances.push(instance); 
     return instance; 
     } else { 
      throw new Error("You can't create instances of base"); 
     } 
    }, 
    inherit:function inheritation() { 
     var sub = Object.create(this); 
     sub.pub = Object.create(this.pub); 
     sub.sup = this; 
     return sub; 
    }, 
    initclosure:function initiation() {}, 
    instances: [], 
    pub: {} 

    }; 



    Object.defineProperty(obj,"init",{ 
    set:function (fn) { 
    if (typeof fn != "function") 
     throw new Error("init has to be a function"); 
    if (!this.hasOwnProperty("initclosure"))  
     this.initclosure = fn; 
    }, 
    get:function() { 
     var that = this; 
     //console.log(that) 
      return function() { 
       if(that.pub.isPrototypeOf(this)) //!(obj.isPrototypeOf(this) || that == this)) 
       that.initclosure.apply(this,arguments); 
       else 
       throw new Error("init can't be called directly"); 
      }; 
    }  

    }); 


    Object.defineProperty(obj,"create",{configurable:false,writable:false}); 
    Object.defineProperty(obj,"inherit",{configurable:false,writable:false}); 
    return obj; 
})(); 

/*Helpers*/ 
function merge (obj) { 
if(arguments.length < 2) 
    throw new Error({msg:"At least 2 parameters needed"}); 
    for (var i = 1, ilen = arguments.length;i < ilen; i++) 
    for (var k in arguments[i]) 
    obj[k] = arguments[i][k]; 
} 

/*Helpers for workarounds*/ 
function tieProp (prop,obj) { 
    if(arguments.length < 3) 
    throw new Error({msg:"At least 2 Objects are needed"}); 
    var ref = obj[prop]; 

    for (var i = 1,ilen = arguments.length;i<ilen;i++) 
     Object.defineProperty(arguments[i],prop,{ 
     set: function (val) { 
     ref = val; 
     }, 
     get: function() { 
     return ref; 
     } 
    }); 

} 

這樣的完整性,這是其中的對象被創建的部分

/*Example Code*/ 

var Series = base.inherit(); 
Series.init = function (specs) { 
    var _Series = this; 
     specs = specs ||{}; 

    this.seasons = []; 

    var Season = Series.inherit(); 
    Season.init = function(specs) { 
    var _Season = this; 
     specs = specs || {}; 
    _Series.seasons.push(this); 

    merge(this,specs); 



    }; 

    merge(this,specs); 
    Season.pub.score = this.score; // First way 
    Season.pub.stats = this.stats; // Second Way 
    tieProp("scoreTied",this,Season.pub); //Third Way 
    Season.pub.scoreSetter = this.scoreSetter; // Second Way 

    this.updateScore = function (score) { // Forth Way 
     this.scoreSetter = score; 
     Season.pub.scoreSetter = score; 
    }; 
    tieProp("someObj",this,Season.pub); //Obj Example 

    this.addSeason = function (specs) { 
    Season.create(specs); 
    }; 


}; 
Series.pub.toString = function() { 
return this.title + " has a score of " + this.scoreTied ; 
}; 


var Futurama = Series.create({ 
    title:"Futurama", 
    score:1, // 1. 
    scoreTied:2, // 2. 
    stats:{ //3. 
    score:3 
    }, 
    scoreSetter:4, 
    someObj:{a:"b"} 
}); 
Futurama.addSeason(); 

並讓我們在更改屬性之前記錄控制檯輸出

console.log("BeforeChange",Futurama.score + " - " + Futurama.seasons[0].score); //"1 - 1" 
console.log(Futurama.scoreTied + " - " + Futurama.seasons[0].scoreTied); // "2 - 2" 
console.log(Futurama.stats.score + " - " + Futurama.seasons[0].stats.score); // "3 - 3" 
console.log(Futurama.scoreSetter + " - " + Futurama.seasons[0].scoreSetter); //"4 - 4" 
console.log(JSON.stringify(Futurama.someObj) + " - " + JSON.stringify(Futurama.seasons[0].someObj)); //"{"a":"b"} - {"a":"b"}" 

然後使用

  • 對象既可以當改變Futurama

    Futurama.score = 2; //TFirst way // This will fail 
    Futurama.scoreTied = 3; //Second way 
    Futurama.stats.score = 4; // Third way 
    Futurama.updateScore(5); // Forth Way 
    Futurama.someObj = {b:"a"}; // Object replacement 
    

    比分性能和日誌他們

    console.log("After Change",Futurama.score + " - " + Futurama.seasons[0].score); // 2 - 1 
    console.log(Futurama.scoreTied + " - " + Futurama.seasons[0].scoreTied); // 3 - 3 
    console.log(Futurama.stats.score + " - " + Futurama.seasons[0].stats.score); //4 -4 
        console.log(Futurama.scoreSetter + " - " + Futurama.seasons[0].scoreSetter); //5 - 5 
    console.log(JSON.stringify(Futurama.someObj) + " - " + JSON.stringify(Futurama.seasons[0].someObj)) ; //"{"b":"a"} - {"b":"a"}" 
    

    所以,這將是可能的。defineProperty提供的屬性與getter和setter

function tieProp (prop,obj) {...

但如果使用Object.defineProperty會在這種情況下適當的,我不知道我是不是真的有設置屬性描述符以讓某些屬性共享一個對原始值的引用?

  • 結束語中會引用傳遞Object的所有原始值,並改變這個對象propertie

Season.pub.stats = this.stats; // Second Way

這將是確定的,但我不認爲舒服,因爲我不得不把物業搬到另一個地方,這種拿走了一些命名的自由度,在這個例子中,我想score作爲Futurama的得分在Futurama.score而不是Futurama.stats.score

*寫作setter方法的屬性,這只是設置對象

*的兩個值就像this.updateScore = function (score) { // Forth Way *

但我寧願要從此遠離,因爲我將不得不增加方法對象

我不知道我是不是應該這樣做,或者如果我只是錯過了一個非常簡單的方法做到這一點?

在正確的方向有任何建議或勾縫將非常感激

,並在此先感謝答案和耐心通過這個

繼承人JSBin念給擺弄

+0

+1把這麼多的細節到您的問題! –

回答