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
是否可以覆盖闭包之外的局部变量并运行该范围内的其余函数?所以,我想要一个输出:
こにちわ だぐ
こにちわ だぐ
我意识到回调中的范围只是遮蔽外部作用域中的局部变量,但是有没有办法直接访问外部作用域并改变那里的变量?
Bonus,这在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)
})
答案 0 :(得分:1)
您可以在Ruby中使用实例变量实现相同的功能,如下所示:
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
答案 1 :(得分:1)
this.var
公平不是局部变量。由于我对Javascript的了解有限,我会说this.var
的版本很好
根据您的需要,我建议只传递一个参数,例如var hello = function(var1)
。你可以使用某种哈希:
var h = new Object()
h['greet'] = 'Hello'
如bjhaid所述,您可以在代码中的某处使用实例变量(@a="new value"
)。
您可以使用全局变量($var
)。没有新的类/对象,全局变量和实例变量非常相似:整个程序可以改变它
如果你正在创建新的类/对象,我建议坚持使用实例变量,因为只有类/对象可以改变它(当然没有像some_object.instance_variable_set :@a, '34'
那样的元编程。)
我想你会在大多数情况下使用实例变量,但是我应该写其他方式,因为你的需求可能会有所不同。
如何使用回调更改方法局部变量?
如果你真的需要局部变量:
def meth1 &block # & - change block to the lambda
a = 42
b = 33
block.call binding # "send" local scope (variables like `a`, `b`) to the block
puts a,b
end
# `bin` is what you send in the `meth1` method;
`eval` may change variables etc
meth1 {|bin| bin.eval 'a="str"'; bin.eval 'b=:FF' }
您可以使用块中的隐式返回(您不能将return
与proc
类型的块一起使用;并且对方法的块发送将转换为{{1 }} type block)
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]}
但是,这种方法是有限的。您可以就地修改字符串,数组,哈希,但不能修改符号或数字。在适当位置修改的方法可能在其名称的末尾有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
(bang),但这不是规则。
这种方法很简单,可以说明如何做某事。我应该注意到:
!
几乎可以运行任何代码。它很危险(而且速度慢)所以请谨慎使用。您应该检查传递给eval
阻止:如果你不发送阻止(例如只是呼叫eval
),它将引发错误。您可能想要检查是否存在阻止 - method block_given?
您可以检查返回的块(在类似于meth3
的情况下)。当块没有返回任何 good 时,您可以将变量更改为默认值。
适应性:我认为这很危险。您必须记住指向特定单元格的每个变量。