2017-03-25 143 views
0

如果我在函数中创建回调函数,我可以通过回调函数访问函数中的局部变量吗?在回调函数内部访问函数的局部变量

Obj.prototype.outerFunc = function() 
{ 
    var x = 0; 
    var callback = this.innerFunc; 
    callback(); 
} 

Obj.prototype.innerFunc = function() 
{ 
    x++; 
} 

x自然不是innerFunc范围内,并且如果调用本身将产生错误。但是如果我从outerFunc调用它,我可以扩展innerFunc's范围以访问x

编辑:应该提到,我不想将参数传递到函数或使x和Obj的实例。我更愿意将innerFunc视为在outerFunc的本地宣告。类似于下面的做法:

Obj.prototype.outerFunc = function() 
{ 
    var x = 0; 
    var callback = function() { 
     x++; 
    } 
    callback(); // works 
} 
+0

唯一的方法是如果'outerFunc'将'x'放在共享范围内。全球范围是所有功能之间共享的。但是,没有办法直接影响被调用者的范围。基本上你以后称之为*动态范围*。 JavaScript和大多数语言都有*词法范围*。 –

回答

2

是的:这正是功能参数的用途。它们允许您将一个范围的值传递给另一个范围。

Obj.prototype.outerFunc = function() 
{ 
    var x = 0; 
    var callback = this.innerFunc; 
    x = callback(x); 
} 

Obj.prototype.innerFunc = function(x) 
{ 
    x++; 
    return x; 
} 

请注意,该值被发送到另一个函数,而不是变量。所以你需要返回值并赋值才能使用它。

+0

应该提到,但我试图避免将x作为参数传递(请参阅我对原始问题所做的编辑) – sookie

+0

@sookie这正是函数应该避免的。 – lonesomeday

0

如果您使用的原型,只是设置实例属性:

// constructor 
var Obj = function() {} 

Obj.prototype.outerFunc = function() 
{ 
    this.x = 0; 
    var callback = this.innerFunc.bind(this); 
    callback(); 
} 

Obj.prototype.innerFunc = function() 
{ 
    this.x++; 
} 

var instance = new Obj() 
instance.outerFunc() 
console.log(instance.x) // returns 1 

编辑:但@ lonesomeday的答案是一个更好的解决方案,因为它需要一个功能更强大的方式避免副作用:)

+0

对不起,应该提到,但我实际上试图避免使x的一个Obj的实例(见编辑我对原始问题) – sookie

0

这样做的优先停留的方式是对x分配给对象然后所有功能可以访问它的范围内,通过this.x

Obj.prototype.outerFunc = function() 
{ 
    this.x= 0; // set x to zero 
    this.innerFunc(); 

} 

Obj.prototype.innerFunc = function(x) 
{ 
    this.x++; 
    return this.x; 
} 
+0

谢谢。实际上,我试图避免将x作为Obj的实例(请参阅我对原始问题所做的编辑) – sookie

+0

如果可以在outerFunc中添加原型,那么x将是可访问的,或者如果可以使x成为对象外的全局。 – MartinWebb

0

这有点硬而不knowi解决为什么你不想传递一个参数;如果你只是想有一个特定的功能签名,也许更高阶的功能可能有帮助?

Obj.prototype.outerFunc = function() 
{ 
    var x = 0; 
    var callback = this.innerFunc(x); 
    callback(); 
} 

Obj.prototype.innerFunc = function(x) 
{ 
    return function() { /* use x in here */ }; 
} 

这样你就有两个功能在一个里面。外部参数接受参数,内部参数可以访问传递给外部参数的变量。

这当然只给你一半你在你的例子中演示:你可以访问本地变量,但不能修改它。

0

在任何情况下,在OOP上下文中或其他情况下,都不能从函数外部访问任何函数的内部变量。

唯一的例外是在函数B中定义并从该函数B返回的函数A继续访问函数B中的变量 - 闭包的基本概念。

我不知道为什么你不想使用实例变量。这就是他们想要的 - 跨方法共享数据。我不知道为什么你不想传入或传出值 - 这就是参数和返回值。

我可以扩展innerFunc的范围以访问x吗?

不,你不能,无论如何。 JS中没有这样的概念。

你可以来你似乎什么也许想要做的最接近的是在构造函数中定义变量:

function Obj() { 
    var x = 0; 

    this.outerFunc = function() { 
    var callback = this.innerFunc; 
    callback(); 
    }; 

    this.innerFunc = function() { 
    x++; 
    } 
} 

但是,这将无法正常工作,是因为this.innerFunc缺少它的上下文。因此,你需要写

var callback =() => this.innerFunc(); 

然而,这是一个谜,你为什么会想这样做,而不是仅仅写this.innerFunc()