为什么 javascript 会保留在外部函数中发生的局部变量重新分配,而不必捕获返回值

Why does javascript persist local variable reassignments that occur in outside functions without having to capture the return values?

本文关键字:分配 新分配 返回值 不必 局部变量 保留 javascript 外部 函数 为什么      更新时间:2023-09-26

我是一个Ruby程序员,所以我习惯上来自哪里,如果你有这样的东西:

  def addone(x)
    x+1
  end
  def ruby_assignment_behavior(x)
    addone(x)
    puts "x equals " + x
  end

运行最后一个方法将导致以下结果:

ruby_assignment_behavior(1)
#=> "x equals 1"

在 JavaScript 中,我认为与此等效的东西会返回x equals 2

在研究了这段代码(获取用户 GPS 坐标)后,我发现了 javascript 的这种独特品质(相对于 ruby)

var currPosition;
navigator.geolocation.getCurrentPosition(function(position) {
    updatePosition(position);
    $("#lat").html(position.coords.latitude;);
    $("#lng").html(position.coords.longitude);  
};
function updatePosition(position) {
    currPosition = position;
}

为什么在 getCurrentPosition 函数内部,position变量会用 updatePosition() 的返回值进行更新,即使 position 是闭包(?

也:我很好奇,在 javascript 代码示例中,是否有必要在getCurrentPosition之外使用该功能updatePosition,如果是这样,为什么会这样?在最外层范围内定义的currPosition变量是否以某种方式携带重新分配的position值?

这两段代码非常不同。在 Ruby 代码中,您正在更改变量值。由于变量是局部变量,因此正如您正确声明的那样,更改不会反映在范围之外。

在 JavaScript 代码中,您正在更改变量指向的对象的内部状态。变量本身不会更改。

在这方面,Ruby 和 JavaScript 的行为是相同的。

var a = { count: 0 };
function increment(x) {
  x.count++; // variable changed, changing referenced object state
}
increment(a);
console.log(a.count);
// => 1

相当于

a = { count: 0 }
def increment(x)
  x[:count] += 1 # variable changed, changing referenced object state
end
increment(a)
puts a[:count]
# => 1

var b = { count: 0 };
function increment(x) {
  x = { count: x.count + 1 }; // changing variable's reference
}
increment(b);
console.log(b.count);
// => 0

相当于

b = { count: 0 }
def increment(x)
  x = { count: x[:count] + 1 } # changing variable's reference
end
increment(b)
puts b[:count]
# => 0

函数外部的var currPosition声明变量currPosition在比函数更宽的范围内,有点但不完全像在 Ruby 中使用 $currPosition。这允许函数将值分配给一个变量,该变量将可见:

var c = 0; // outer scope
function update() {
  c = 1;
}
update();
console.log(c);
// 1

function update() {
  var d = 0; // inner scope
  d = 1;
}
update();
console.log(d);
// undefined

在 Ruby 中,变量不允许像这样跳转函数(方法)作用域,但您可以使用 @a@@a$a 来访问外部作用域(实例、类或全局):

def update
  c = 1 # local scope
end
update
puts c
# => Error

@d = nil # instance scope
def update
  @d = 1
end
update
puts @d
# => 1

但是,Ruby 中的块与 JavaScript 中的函数具有类似的作用域效应:

e = nil # outer scope
1.times do
  e = 1
end
e
# => 1

1.times do
  f = 1 # inner scope
end
f
# => Error