JavaScript变量范围的澄清
我已经知道如何使这段代码工作,但我的问题更多的是为什么它会这样工作,以及我做的事情是否正确 我可以举一个最简单的例子来说明我的问题: 假设我有一个函数,按下一个按钮,将输入字段的值增加10JavaScript变量范围的澄清,javascript,variables,scope,Javascript,Variables,Scope,我已经知道如何使这段代码工作,但我的问题更多的是为什么它会这样工作,以及我做的事情是否正确 我可以举一个最简单的例子来说明我的问题: 假设我有一个函数,按下一个按钮,将输入字段的值增加10 var scopeTest = { parseValue : function( element, value ) { value = parseInt( element.val(), 10 ); //Why does this not return the valu
var scopeTest = {
parseValue : function( element, value ) {
value = parseInt( element.val(), 10 );
//Why does this not return the value?
return value;
},
incrementValue : function( element, button, value ) {
button.on('mousedown', function (e) {
//Execute the parseValue function and get the value
scopeTest.parseValue( element, value );
//Use the parsed value
element.val( value + 10 );
e.preventDefault();
});
},
init : function () {
var element = $('#test-input'),
button = $('#test-button'),
value = '';
this.incrementValue( element, button, value );
}
};
scopeTest.init();
上面的代码不起作用,因为parseValue
方法在incrementValue
方法内执行时没有正确返回value
var
为了解决这个问题,我必须设置scopeTest.parseValue(元素,值)将参数设置为值
变量,如下所示:
value=scopeTest.parseValue(元素,值)代码>
比代码更有效
但我的问题是为什么?为什么这个额外的变量赋值步骤是必要的,为什么return语句是不够的?另外,我用我的函数/方法做的每件事都是正确的,还是这就是JavaScript的工作方式
这里的工作示例=>,因为parseValue的value参数只是一个引用。是的,您可以更改对象,因为您有一个参照,但如果指定给该参照,它现在指向另一个对象
原来的版本没有改变。是的,返回值是“够了”,但您将新对象保存在一个变量中,其生存期在下一行代码结束
人们说JavaScript通过引用来传递对象,但过于字面化可能会让人困惑。JavaScript中的所有对象句柄都是引用。这个引用本身不是通过引用传递的,也就是说,您不会得到双间接指针。因此,可以通过形式参数更改对象本身,但不能更改调用站点的引用本身。因为parseValue的value参数只是一个引用。是的,您可以更改对象,因为您有一个参照,但如果指定给该参照,它现在指向另一个对象
原来的版本没有改变。是的,返回值是“够了”,但您将新对象保存在一个变量中,其生存期在下一行代码结束
人们说JavaScript通过引用来传递对象,但过于字面化可能会让人困惑。JavaScript中的所有对象句柄都是引用。这个引用本身不是通过引用传递的,也就是说,您不会得到双间接指针。因此,您可以通过形式参数更改对象本身,但不能更改调用站点的引用本身。这不是范围问题,而是传递引用和传递值之间的混淆
在JavaScript中,所有数字都按值传递,这意味着:
var value = 10;
scopeTest.parseValue( element, value );
// value still == 10
对象和数组通过引用传递,这意味着:
function foo( obj ){
obj.val = 20;
}
var value = { val: 10 }
foo( value );
// value.val == 20;
这不是范围问题,而是按引用传递和按值传递之间的混淆
在JavaScript中,所有数字都按值传递,这意味着:
var value = 10;
scopeTest.parseValue( element, value );
// value still == 10
对象和数组通过引用传递,这意味着:
function foo( obj ){
obj.val = 20;
}
var value = { val: 10 }
foo( value );
// value.val == 20;
你可以看看
你可以看一看
正如其他人所说,这是一个通过参考与通过val的比较。
给定:函数foo(){return 3+10;}foo()代码>
会发生什么?该操作已执行,但您没有在任何地方设置该值
鉴于:result=foo()代码>
该操作将执行,但您已存储该值以备将来使用
这只是一个范围问题
为什么?
有一个param
是全局的,但是在函数内部,参数的名称被称为param
,因此函数不会使用全局参数。相反,param
仅应用本地实例(this.param
)。如果你这样做的话,情况就完全不同了:
这里没有名为param
的局部变量,因此它使用全局变量。正如其他人所说,它是一个pass-by-ref vs-pass-by-val。
给定:函数foo(){return 3+10;}foo()代码>
会发生什么?该操作已执行,但您没有在任何地方设置该值
鉴于:result=foo()代码>
该操作将执行,但您已存储该值以备将来使用
这只是一个范围问题
为什么?
有一个param
是全局的,但是在函数内部,参数的名称被称为param
,因此函数不会使用全局参数。相反,param
仅应用本地实例(this.param
)。如果你这样做的话,情况就完全不同了:
这里没有名为param
的局部变量,因此它使用全局变量。这主要是一个范围问题。pass-by-*问题讨论起来很奇怪,因为sender变量和被调用函数变量的名称相同。不管怎样,我还是要试试
变量的作用域是可见的。你可以把它看作是存放东西的地方。此范围由函数的位置定义。这意味着它在源代码中的位置(在全局范围内或在函数范围内)。它是在编写源代码时定义的,而不是以后如何调用函数
范围可以嵌套。在您的示例中,有四个作用域。全局作用域和每个函数都有一个作用域。函数的作用域都具有全局作用域作为父作用域。父作用域意味着,无论何时尝试访问名称/变量,都会首先在函数作用域中搜索该名称/变量,如果未找到该名称/变量,则搜索将继续到父作用域,直到找到该名称/变量或到达全局作用域(在这种情况下,会出现无法找到该名称/变量的错误)
允许多次定义同一名称。我认为这是你困惑的根源。你眼中的“价值”这个名字总是一样的,但我