Javascript 如何处理此问题以指向最上面的封闭fn?

Javascript 如何处理此问题以指向最上面的封闭fn?,javascript,Javascript,想象我有一个这样的fn: var test = (function() { var self = this; var a = function() { (function() { self.b() })() } var b = function() { console.log("hello") } return { a:a,b:b } })(); testa函数调用另一个函数中的b函数。然而,我保留了这个作为自我,但我还是遇到了问题

想象我有一个这样的fn:

var test = (function() {
     var self = this;
     var a = function() {  (function() { self.b() })() }
     var b = function() { console.log("hello") }
     return { a:a,b:b }
})();
test
a
函数调用另一个函数中的
b
函数。然而,我保留了
这个
作为
自我
,但我还是遇到了问题:

test.a()

我在哪里犯错?为什么
自身
没有保留

如何解决这个问题

注 将功能更改为:

var a = function() {  (function() { b() })() }
这很有效。但是我不想这样,因为,想象一下,现在我正在测试函数
a
调用函数
b
。现在我想侦察
b
,如果我这样做了:

var spyb = sandbox.spy(test,"b")
并致电:

test.a()
在测试代码中,如果我尝试执行断言:

assert(b.calledOnce)
这失败了,因为spy lib无法确定调用了
test
b
fn


因此,请帮助我找到
self
的方法。

您用于构建
测试的匿名函数中的该
要么是
未定义的
(在严格模式下)要么是全局对象(在松散模式下);也不是你想要的

a
调用
b
完全不需要对象引用:

var test = (function() {
     var a = function() {  (function() { b() })() }
     // No need for an object -----------^
     var b = function() { console.log("hello") }
     return { a:a,b:b }
})();
由于
a
是匿名函数调用上下文的闭包,因此它持久地引用
b
(正如
b
a

但如果您想使用一个,您可以这样做:

var test = (function() {
     var obj = {
        a: function() {  (function() { obj.b() })() },
        b: function() { console.log("hello") }
     };
     return obj;
})();

在用于生成
测试的匿名函数中是
未定义的
(在严格模式下)或全局对象(在松散模式下);也不是你想要的

a
调用
b
完全不需要对象引用:

var test = (function() {
     var a = function() {  (function() { b() })() }
     // No need for an object -----------^
     var b = function() { console.log("hello") }
     return { a:a,b:b }
})();
由于
a
是匿名函数调用上下文的闭包,因此它持久地引用
b
(正如
b
a

但如果您想使用一个,您可以这样做:

var test = (function() {
     var obj = {
        a: function() {  (function() { obj.b() })() },
        b: function() { console.log("hello") }
     };
     return obj;
})();
当你回来的时候 {a:a,b:b,c:self} 您将看到'self==window'为true,因此self是指向window的

但是在函数中声明变量“b”使用“var”,因为“b”的范围在函数中,而不是在窗口中,所以“self”不能到达变量“b”

正确答案是:

var test = function() {
  var self = this;
  self.a = function() {  (function() { self.b() })() }
  self.b = function() { console.log("hello") }
  return { a:self.a,b:self.b }
};
var q = new test();
q.a(); //hello
当你回来的时候 {a:a,b:b,c:self} 您将看到'self==window'为true,因此self是指向window的

但是在函数中声明变量“b”使用“var”,因为“b”的范围在函数中,而不是在窗口中,所以“self”不能到达变量“b”

正确答案是:

var test = function() {
  var self = this;
  self.a = function() {  (function() { self.b() })() }
  self.b = function() { console.log("hello") }
  return { a:self.a,b:self.b }
};
var q = new test();
q.a(); //hello

谢谢,告诉我一件事,现在我做
var a=function(){(function(){b()}()()}
,但是如果我尝试使用simon lib模拟
b
,总是调用真正的
b
fn,而不是模拟!知道为什么会这样吗?这使得代码变得非常复杂-testable@batman:因为
a
引用了
b
,而不是您返回的对象上的
b
属性。因此,如果替换对象上的
b
a
仍将调用原始的。对于您的场景,第二个示例可能更合适。谢谢,请告诉我一件事,现在我执行
var a=function(){(function(){b()})(}
,但是如果我尝试使用simon lib模拟
b
,则总是调用真正的
b
fn,而不是模拟!知道为什么会这样吗?这使得代码变得非常复杂-testable@batman:因为
a
引用了
b
,而不是您返回的对象上的
b
属性。因此,如果替换对象上的
b
a
仍将调用原始的。对于您的场景,第二个示例可能更合适。