2016-06-08 134 views
2

我已经定义了一个辅助类来创建一些对象。 由于对象A包含Bs,我试图从createA调用createB,但是我得到一个“未捕获的引用错误:createB未定义为”。 JS是不是我的主要语言,所以请原谅我,如果这件事情明显;)Javascript - 从另一个静态方法访问静态方法抛出ReferenceError

这里是我的代码:

define([ 
    "model/A", 
    "model/B", 
    "model/C" 
], function (A, B, C) { 
    return { 
    addTo: function (params, key, target, source) { 
     if (params[key] !== undefined && params[key] !== null) { 
     target.set(key, params[key], source); 
     } 
    }, 
    createA: function (params, source) { 
     var result = new A(); 

     ... 
     bDefs.forEach(function(bDef) { 
     result.get("bs").push(this.createB(params,source)); 
     }); 
     return result; 
    }, 
    createB: function (params, source) { 

     var result = new B(); 
     ... 

     result.get("cs").push(createC(params,source)); 
     return result; 
    }, 
    createMediaType: function (params, source) { 

     var result = new C(); 
     ... 

     return result; 
    } 
    }; 
}); 

编辑:复读的问题,我注意到我省略了一些重要的东西,可能是问题的原因:我从forEach中调用createB()。我猜想匿名函数没有其他类的可见性。如何将这个的引用传递给forEach?

+0

这是不行的SO编辑这样的问题该编辑将使现有问题的答案无效,因此我已从您用编辑添加的createB调用中删除了'this.'。作为[algiogia说](http://stackoverflow.com/questions/37696799/javascript-accessing-static-method-from-another-static-method-throws-reference/376​​96945?noredirect=1#comment62869281_37696945),解决方案我的回答也涉及到“forEach”问题。我还更新了答案,向您展示如何使用'this'来实现'forEach'的工作。 –

+0

@ T.J.Crowder我编辑了这个问题,因为它是错误的。在SO中复制代码我省略了相关部分。在我刚才提到的初始版本中,我已经尝试过使用“this.createB()”。你的回答仍然有效。 – algiogia

+0

即使您错误地发布了代码,它也不适合修复它*一旦收到答案,它就会失效*。但是,正如你注意到的那样,你最初的问题* *在最后关于'this.createB'(我错过了!)有那么一点,所以它不适用于这种情况。顺便说一句,在我上面的评论中,我的意思是“正如jamiec所说的”不是“,因为algiogia说” - 哈哈! –

回答

1

此行

result.get("bs").push(createB(params,source)); 

预计将有称为createB一个在范围内的标识符。代码中没有一个。对象初始值设定项中的属性键不会成为独立标识符(幸好)。

假设createA将与this一起被称为您使用初始化程序创建的对象,您可以使用this.createB代替。但它需要假设约this,这将需要执行代码使用您的对象。我在下面给你一个替代方案。

I'm calling createB() from within a forEach . I suppose that anonymous function does not have visibility of the rest of the class.

是的,它的确如此。 (这不是一个类。)

How can I pass a reference to this to the forEach ?

的第二个参数forEach是价值回调期间this使用,所以:

bDefs.forEach(function(bDef) { 
    result.get("bs").push(this.createB(params,source)); 
}, this); 
// ^^^^ 

或交替您可以使用Function#bind,但我不会'那里。

如果您正在使用ES2015(又名“ES6”),可以产生它们在那里使用箭头功能,因为箭头功能关闭了上下文的this值:

// Requires ES2015 ("ES6") 
bDefs.forEach(bDef => { 
    result.get("bs").push(this.createB(params,source)); 
}); 

您有第二个选项不依赖调用代码来调用正确的this值,并且不要求您在forEach内保留该值:您可以在私有范围内将这些函数独立标识符生成并返回他们作为对象的属性:

define([ 
    "model/A", 
    "model/B", 
    "model/C" 
], function (A, B, C) { 
    // Note how each of these is a function declaration; that defines 
    // their names as in-scope identifiers within this anonymous function 
    // and the functions created within it (which close over the context of 
    // the call to this anonymous function where these are created). 
    function addTo(params, key, target, source) { 
    if (params[key] !== undefined && params[key] !== null) { 
     target.set(key, params[key], source); 
    } 
    } 

    function createA(params, source) { 
    var result = new A(); 

    ... 
    result.get("bs").push(createB(params,source)); 

    return result; 
    } 

    function createB(params, source) { 

    var result = new B(); 
    ... 

    result.get("cs").push(createC(params,source)); 
    return result; 
    } 

    function createMediaType(params, source) { 

    var result = new C(); 
    ... 

    return result; 
    } 

    // Now we return the object 
    return { 
     addTo: addTo, 
     createA: createA, 
     createB: createB, 
     createMediaType: createMediaType 
    }; 
}); 

边注:在ES2015(又名“ES6”)结尾的那段对象初始化可以多一点简洁:

// Requires ES2015 (aka "ES6") 
return { 
    addTo, 
    createA, 
    createB, 
    createMediaType 
}; 
+0

谢谢。我发现问题是forEach(请参阅更新的问题)。 – algiogia

+1

@algiogia如果按照此答案中显示的方式进行操作,它也可以解决您的forEach问题。 – Jamiec

+0

@algiogia:有什么需要澄清的东西吗? –