Warning: file_get_contents(/data/phpspider/zhask/data//catemap/8/variables/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
JavaScript变量范围的澄清_Javascript_Variables_Scope - Fatal编程技术网

JavaScript变量范围的澄清

JavaScript变量范围的澄清,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

我已经知道如何使这段代码工作,但我的问题更多的是为什么它会这样工作,以及我做的事情是否正确

我可以举一个最简单的例子来说明我的问题:

假设我有一个函数,按下一个按钮,将输入字段的值增加10

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变量和被调用函数变量的名称相同。不管怎样,我还是要试试

变量的作用域是可见的。你可以把它看作是存放东西的地方。此范围由函数的位置定义。这意味着它在源代码中的位置(在全局范围内或在函数范围内)。它是在编写源代码时定义的,而不是以后如何调用函数

范围可以嵌套。在您的示例中,有四个作用域。全局作用域和每个函数都有一个作用域。函数的作用域都具有全局作用域作为父作用域。父作用域意味着,无论何时尝试访问名称/变量,都会首先在函数作用域中搜索该名称/变量,如果未找到该名称/变量,则搜索将继续到父作用域,直到找到该名称/变量或到达全局作用域(在这种情况下,会出现无法找到该名称/变量的错误)

允许多次定义同一名称。我认为这是你困惑的根源。你眼中的“价值”这个名字总是一样的,但我