Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/javascript/416.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中使用“with”关键字的范围解析_Javascript_Jquery_Google Chrome_Javascript Engine - Fatal编程技术网

Javascript中使用“with”关键字的范围解析

Javascript中使用“with”关键字的范围解析,javascript,jquery,google-chrome,javascript-engine,Javascript,Jquery,Google Chrome,Javascript Engine,当使用“with”关键字时,Javascript中似乎有一种奇怪的提升和作用域行为 我知道“with”的用法被认为是禁忌,但在其中一个框架中遇到了这种情况,因此不得不处理它。但尽管如此 有人能解释为什么如果我们有一个“with”块,那么声明但未定义的变量会使用with对象解析,但闭包变量不是这样 要演示,请参阅以下代码的输出: 通过谷歌浏览器检查 注意:我理解并理解为什么在警报后使用var语句是一个问题,但我想弄清楚的主要问题是, 在警报声明的范围解析过程中,由于吊装,“aptNum”和“x”应

当使用“with”关键字时,Javascript中似乎有一种奇怪的提升和作用域行为

我知道“with”的用法被认为是禁忌,但在其中一个框架中遇到了这种情况,因此不得不处理它。但尽管如此

有人能解释为什么如果我们有一个“with”块,那么声明但未定义的变量会使用with对象解析,但闭包变量不是这样

要演示,请参阅以下代码的输出:

通过谷歌浏览器检查

注意:我理解并理解为什么在警报后使用var语句是一个问题,但我想弄清楚的主要问题是, 在警报声明的范围解析过程中,由于吊装,“aptNum”和“x”应在局部范围内未定义,因此应视为“已声明但未定义”

但是,aptNum仍然作为“2”输出。

来自fiddle:

with(address){
    $('#output').text('aptNum : ' + aptNum + ",   x : " + x ); 
    var aptNum = 100,
        x = 10 ;
}
变量x正在with语句体中重新声明,请参见前面的var关键字。变量声明被挂起,因此x被临时定义为未定义,然后在值被记录之后,最终被重新定义为10

在这个更新的fiddle中,我将变量声明语句更改为一个简单的赋值语句,这将产生预期的行为,将x的值记录为90。请参见fiddle的

with(address){
    $('#output').text('aptNum : ' + aptNum + ",   x : " + x ); 
    var aptNum = 100,
        x = 10 ;
}
变量x正在with语句体中重新声明,请参见前面的var关键字。变量声明被挂起,因此x被临时定义为未定义,然后在值被记录之后,最终被重新定义为10

在这个更新的fiddle中,我将变量声明语句更改为一个简单的赋值语句,这将产生预期的行为,将x的值记录为90。请参见

我猜您调用了x,它甚至在声明x之前就应该是address的属性。with作用域中的x不引用在函数外部声明的x。引擎正在尝试读取address.x的值,当然,该值不存在。这就是原因。关于,因为aptNum被“重新”声明为该范围内的变量,所以它不引用地址的aptNum。

我猜您在声明x之前调用了x,它将被预期为地址的属性。with作用域中的x不引用在函数外部声明的x。引擎正在尝试读取address.x的值,当然,该值不存在。这就是原因。关于,由于aptNum被“重新”声明为该范围内的变量,因此它不引用地址的aptNum。

代码

alert(aptNum + ":" +  x);
var aptNum = 100,
      x = 10 ;
是与中的aptNum和x的变量。var被提升,因此也可被视为

var aptNum, x;
alert(aptNum + ":" +  x);
aptNum = 100, x = 10;
现在很容易理解为什么它们没有定义。您可能不想在这里使用var。

代码

alert(aptNum + ":" +  x);
var aptNum = 100,
      x = 10 ;
是与中的aptNum和x的变量。var被提升,因此也可被视为

var aptNum, x;
alert(aptNum + ":" +  x);
aptNum = 100, x = 10;
现在很容易理解为什么它们没有定义。您可能不想在这里使用var

不建议与一起使用,并且在ECMAScript 5严格模式下禁止使用。建议的替代方法是将要访问其属性的对象指定给临时变量

它不喜欢有一个全局变量。我认为这是因为x超出了address对象的范围。您可以将参数传递到函数中,它就可以工作了

var x = 90;
test(x);
例如:

更多关于

不建议与一起使用,并且在ECMAScript 5严格模式下禁止使用。建议的替代方法是将要访问其属性的对象指定给临时变量

它不喜欢有一个全局变量。我认为这是因为x超出了address对象的范围。您可以将参数传递到函数中,它就可以工作了

var x = 90;
test(x);
例如:

有关with的详细信息在with块中,变量aptNum被address.aptNum隐藏,而x指的是局部变量never address.x,因为没有这样的属性

考虑到这一点,您的代码相当于:

var x = 90;
function test1(){

    var aptNum; // hoisted
    var x;      // hoisted

    var address = {
        street: 'Haight',
        aptNum: 2
    };

    with (address){

        // any reference to aptNum or street inside the with block
        // is actually referencing address.aptNum and address.street

        alert(aptNum + ":" +  x); // this  outputs 2 : undefined. 
                                  // as expected, because there is no address.x
                                  // and the local x is undefined at this point

        aptNum = 100; // this assigns to address.aptNum
                      // the variable aptNum is shadowed by address.aptNum

        x = 10; // this assigns to the local x inside the function 
                // (again because there is no address.x)
    }
}
在with块中,变量aptNum被address.aptNum隐藏,而x指的是局部变量never address.x,因为没有这样的属性

考虑到这一点,您的代码相当于:

var x = 90;
function test1(){

    var aptNum; // hoisted
    var x;      // hoisted

    var address = {
        street: 'Haight',
        aptNum: 2
    };

    with (address){

        // any reference to aptNum or street inside the with block
        // is actually referencing address.aptNum and address.street

        alert(aptNum + ":" +  x); // this  outputs 2 : undefined. 
                                  // as expected, because there is no address.x
                                  // and the local x is undefined at this point

        aptNum = 100; // this assigns to address.aptNum
                      // the variable aptNum is shadowed by address.aptNum

        x = 10; // this assigns to the local x inside the function 
                // (again because there is no address.x)
    }
}

我不关心如何使x等于x。实际上,我试图在这里演示范围解析特性。问题是为什么x和aptnumx的分辨率不同,这已经通过在x上滥用var关键字来解释了。我不关心如何使x等于x。实际上,我试图在这里演示范围解析特性。问题是为什么x和aptnumx在分辨率上的差异已经通过在x上滥用var关键字来解释了。我明白你的意思。但是,使
有趣的是:aptNum不是作为“未定义”输出的。它正在解析address.aptNum中的值,即“2”,我明白你的意思。但有趣的是:aptNum并不是作为“未定义”输出的。它正在解析address.aptNum中的值,该值为“2”,JavaScript没有块作用域。with中的var aptNum是封闭函数的局部变量。提供给的对象的属性可以作为块中的变量访问,这就是为什么会得到2。您不能使用var向对象添加新属性,尽管您可以在不直接引用对象的情况下更新现有属性。@谢谢。这似乎以某种方式创建了一个块范围,其中在本地范围中填充了“with”对象属性。然后范围在块之后消失。但由于JS中没有块作用域,这是一种奇怪的行为,它的行为奇怪且令人困惑,这就是人们建议避免它的原因。不过,它可能很有用。它是一个范围,但不是一个典型的变量范围。var不受块的约束。JavaScript没有块作用域。with中的var aptNum是封闭函数的局部变量。提供给的对象的属性可以作为块中的变量访问,这就是为什么会得到2。您不能使用var向对象添加新属性,尽管您可以在不直接引用对象的情况下更新现有属性。@谢谢。这似乎以某种方式创建了一个块范围,其中在本地范围中填充了“with”对象属性。然后范围在块之后消失。但由于JS中没有块作用域,这是一种奇怪的行为,它的行为奇怪且令人困惑,这就是人们建议避免它的原因。不过,它可能很有用。它是一个范围,但不是一个典型的变量范围。var不受块的约束。因此,基本上,对于with块中的aptNum,它更新address.aptNum,但对于x,它更新本地“x”。如果我们检查块外x和aptNum的值,这就证明了这一点。谢谢这是有道理的,没错。它还证明了with语句是如何令人困惑的。因此,基本上,对于with块中的aptNum,它更新地址。aptNum但是对于x,它更新本地“x”。如果我们检查块外x和aptNum的值,这就证明了这一点。谢谢这是有道理的,没错。这也证明了with语句是如何令人困惑的。