Javascript 如何使用回调更改局部变量的方法?

Javascript 如何使用回调更改局部变量的方法?,javascript,ruby,Javascript,Ruby,是否可以重写闭包外部的局部变量,并在该范围内运行函数的其余部分?所以,我想要一个输出: var hello = function(callback) { var greet = "hello world"; var name = "doug"; callback(); console.log(greet, name) } hello(function() { greet = "こにちわ"; name = "だぐ"; console.log

是否可以重写闭包外部的局部变量,并在该范围内运行函数的其余部分?所以,我想要一个输出:

var hello = function(callback) {
    var greet = "hello world";
    var name = "doug";
    callback();
    console.log(greet, name)
}

hello(function() {
    greet = "こにちわ";
    name = "だぐ";
    console.log(greet, name)

})
こにちわ だぐ
hello world doug 
我意识到回调中的作用域只是在外部作用域中隐藏局部变量,但是有没有一种方法可以直接访问外部作用域并在那里修改变量

奖金,这在Ruby中可能吗

编辑: 我可以这样做,有更好的方法吗

こにちわ だぐ
こにちわ だぐ

您可以通过实例变量在Ruby中实现同样的功能,如下所示:

var hello = function(callback) {
    this.greet = "hello world";
    this.name = "doug";
    callback.call(this);
    console.log(greet, name)
}

hello(function() {
    this.greet = "こにちわ";
    this.name = "だぐ";
    console.log(this.greet, this.name)

})
Javascript:
this.var
我记得它不是局部变量。由于我对Javascript的了解有限,我认为使用
this.var
的版本很好。
根据您的需要,我建议只传递一个参数,例如
var hello=function(var1)
。您可以使用某种哈希:

def hello(&block)
  @a = "Foo"
  @greet = "Hello"
  block.call
  puts "#{@greet}, #{@a}"
  end

 hello do
   @a = "Bar"
   @greet = "Hi"
  puts "#{@greet}, #{@a}"
 end

# => Hi, Bar
# => Hi, Bar
红宝石:
如上所述,您可以在代码中的某个地方使用实例变量(
@a=“new value”

您可以使用全局变量(
$var
)。没有新的类/对象,全局变量和实例变量非常相似:整个程序都可以更改它。
如果您正在创建新的类/对象,我建议您坚持使用实例变量,因为只有类/对象可以更改它(当然不需要像
some\u object.instance\u variable\u set:@a,'34'
这样的元编程)

我想在大多数情况下您都会使用实例变量,但是我应该编写其他方式,因为您的需求可能会有所不同

如何使用回调更改局部变量的方法

如果您确实需要局部变量:

var h = new Object()
h['greet'] = 'Hello'
您可以使用来自块的隐式返回(不能对
proc
类型的块使用
return
;发送到方法的块被转换为
proc
类型块)

当然,我们可以利用这样一个事实,即很少有变量可以指向一个对象,例如字符串。如果修改该字符串,则指向该字符串的每个变量都将看到更改。我记得这叫做就地修改

def meth2 &block
  a = 1
  b = 2
  a, b = block.call # returns array (in this case); equivalent: `arr=block.call; a=arr[0]; b=arr[1]`
  puts a,b
end

meth2 {[2,3]}
然而,这种方法是有限的。您可以修改在位字符串、数组、哈希,但不能修改符号或数字。就地修改的方法可能有
(bang)在其名称的末尾,但这不是规则

笔记: 这些方法很简单,用来演示如何做某事。我应该指出:
eval
几乎可以运行任何代码。它很危险(而且速度很慢),所以使用时要小心。您应该检查传递给
eval

块:如果您不发送块(例如,只需调用
meth3
),它将引发错误。您可能需要检查是否存在块-。
您可以检查块返回的内容(在类似于
meth2
的情况下)。当块不返回任何好的结果时,可以将变量更改为默认值


我认为这是危险的。您必须记住指向特定单元格的每个变量

您可以在ruby中使用实例变量来实现相同的功能
def meth2 &block
  a = 1
  b = 2
  a, b = block.call # returns array (in this case); equivalent: `arr=block.call; a=arr[0]; b=arr[1]`
  puts a,b
end

meth2 {[2,3]}
def meth3 &block
  a = "string a"
  b = "something b"
  block.call a, b
  puts a, b
end


meth3 do |a,b|
  a.gsub! 's', '*'
  b.gsub! 'b', '^'
end