2015-06-01 41 views
0

我知道javascript原型繼承相當不錯,但我有一個類似於角scopes的情況,我不知道如何處理它。正確的方法來更改對象__proto__屬性

讓我們開始錯誤(因爲它是壞主意改變__proto__財產),但工作例如

https://jsfiddle.net/hxm61r7j/

function Scope() { 
} 

Scope.prototype.$new = function() { 
    var new_scope = new Scope(); 

    //TODO: change line bellow 
    new_scope.__proto__ = this; 

    return new_scope; 
} 

// Create root scope 
var scope_level_1 = new Scope(); 
scope_level_1.a = 'scope_level_1 a'; 
scope_level_1.b = 'scope_level_1 b'; 

// Create scope which inherits from parent 
var scope_level_2 = scope_level_1.$new(); 
scope_level_2.b = 'scope_level_2 b'; 

// We don't have property "a" in "scope_level_2" so it will be taken from "scope_level_1" 
// But we have property "b" in "scope_level_2" so it will be taken from there 
console.log(scope_level_2.a, scope_level_2.b); 

正如你看到的,我需要一種方法來創建某種scope這將有一些屬性。後來我需要創建其他的scope,它將繼承前一個。我的意思是,如果屬性沒有在當前範圍中定義,則將從父項中取出。

但我不知道如何改變這一行:new_scope.__proto__ = this;

+0

可能重複(http://stackoverflow.com/questions/572897/how-does-javascript-prototype-work) –

+0

@RobertRossmann這不是這種情況。我知道如何在平常情況下使用'prototype'。例如,如果我需要構造函數'Vehicle'和另外兩個構造函數'Car'和'Motorbike'並且它們都從'Vehicle'繼承。但是在這種情況下,我只需要一個繼承自它的構造函數'Scope' –

+0

繼承自身並不會幫助實現任何內容 - 存在於Scope上的任何屬性將立即在當前對象上解析,其他所有內容都將無法解析(即'未定義「);在最壞的情況下,引擎會在遞歸查找您的財產時達到最大堆棧跟蹤。你的這種行爲的用例是什麼......? –

回答

1

我認爲你正在尋找Object.create()

此功能允許您創建與內部原型屬性一個新的JavaScript對象(__proto__)設置爲你傳遞給函數的第一個參數的任何對象:

Scope.prototype.$new = function() { 
    var new_scope = Object.create(this); 
    // If you also need to call the constructor function: 
    Scope.call(new_scope); 

    return new_scope; 
} 

或者,你可以使用Object.setPrototypeOf(),但這是ECMAScript的6的一部分和瀏覽器支持可能會有所不同:

Scope.prototype.$new = function() { 
    var new_scope = new Scope(); 

    Object.setPrototypeOf(new_scope, this); 

    return new_scope; 
} 

注意,__proto__屬性只被在ES 6標準化,因此,其直接操縱是迪斯科uraged。

+0

如果我想修改'Array'的'__proto__',該怎麼辦?這隻適用於「對象」。 –

1

首先它是不使用dunder原一個很好的做法,有setPrototyOf對於事業

setPrototypeOf

當然,除非你需要支持舊的IE版本。

現在請記住,在設置原型之後,您還需要再次設置構造函數。 所以正確的是 new_scope。 proto = this.prototype; new_scope。 .constructor =的[如何JavaScript的.prototype合作?] this.prototype.constructor

+1

在http://shop.oreilly.com/product/0636920033738.do –

+0

提供了一個很好的解釋謝謝你的答案。 (@羅伯特第一次發佈,所以我接受了他的回答)。非常感謝一本書。我喜歡看書! –

+0

但爲什麼使用這個不好的做法?我認爲'angularjs'以類似的方式完成它,我喜歡我可以從父範圍訪問變量。我的情況是完全一樣的 –