2015-06-01 43 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'以类似的方式完成它,我喜欢我可以从父范围访问变量。我的情况是完全一样的 –