Jquery 为什么传递给闭包的对象的更改会保留在全局范围内?

Jquery 为什么传递给闭包的对象的更改会保留在全局范围内?,jquery,closures,Jquery,Closures,好的,当你有参数x时,你的x=2指的是作用于你的iLife的本地副本,它不是指存在于全局作用域上的x。这是因为编译器在向外移动之前总是查看变量存在的最近范围。但是,您可以在“j”参数上设置属性的原因是,当作为参数传递时,javascript对待原语的方式不同于对象/数组 javascript中的任何参数都是通过值传递的-始终。这意味着,如果要为该参数指定一个新值,它将在调用范围内保持不变。但是,有两个例外(对象/数组),即如果指定该对象的属性或数组的特定元素,它将反映调用范围中的更改。有些人称它

好的,当你有参数x时,你的x=2指的是作用于你的iLife的本地副本,它不是指存在于全局作用域上的x。这是因为编译器在向外移动之前总是查看变量存在的最近范围。但是,您可以在“j”参数上设置属性的原因是,当作为参数传递时,javascript对待原语的方式不同于对象/数组

javascript中的任何参数都是通过值传递的-始终。这意味着,如果要为该参数指定一个新值,它将在调用范围内保持不变。但是,有两个例外(对象/数组),即如果指定该对象的属性或数组的特定元素,它将反映调用范围中的更改。有些人称它为“通过引用传递”,因为它的行为类似,但从技术上讲,变量本身在任何情况下都是通过值传递的

根据,这些是规则

  • 字符串和数字等基本类型变量在其调用范围内始终保持不变
  • 数组和对象在其调用范围内根据这些条件进行更改

    如果要为对象或数组指定新值,则该值在调用范围内保持不变

    var x = 1;
    
    (function(x, j) {
        j.fn.cool = function() {};
        x = 2;
    })(x, jQuery);
    
    console.log(jQuery.fn.cool); // returns the newly added function
    object1 = {prop: "car"};
    array1 = [1,2,3];
    
    如果要为对象或数组元素的属性指定新值,则该值将在调用范围内更改

    var x = 1;
    
    (function(x, j) {
        j.fn.cool = function() {};
        x = 2;
    })(x, jQuery);
    
    console.log(jQuery.fn.cool); // returns the newly added function
    object1 = {prop: "car"};
    array1 = [1,2,3];
    
  • 您可以通过从参数/参数列表中删除x,并保持所有其他内容不变来查看这方面的证据。由于没有标识符为x的局部变量作用于IIFE,因此编译器会在全局作用域上进行检查,在全局作用域中找到var x声明,并使用该声明将其设置为2


    好问题!希望这有助于澄清问题!如果您需要更多的澄清,请告诉我。

    谢谢您的回答。我掌握了范围界定的工作原理,因此在查看原语时,很容易理解。在发布此问题之前,我发现了一个类似的问题,其答案与您和您链接的答案类似。然而,它是负支持,所以我的信心在适应这个答案下降。我注意到您链接到的答案下面的注释,表明通过引用传递对象背后的原因实际上更加复杂。@adi518:否。JavaScript完全是通过值传递的。传入JavaScript的语义与Java相同,Java也是完全按值传递的。没有“幕后”或“幕后”。@adi518:没有通过引用的示例。通过引用传递意味着对函数内参数的赋值与对调用范围内传递的变量的赋值具有相同的效果。参数的唯一赋值是
    x=2,它不分配给调用范围中传递的变量。没有为参数
    j
    赋值。它仅读取
    j
    以访问引用
    j
    所指向对象上的属性,以及该引用所指向对象上的属性设置。它在Java中的工作原理是相同的。@adi518也许这会为您澄清:javascript中的任何参数都是通过值传递的-始终如此。这意味着,如果要为该参数指定一个新值,它将在调用范围内保持不变。但是,有两个例外(对象/数组),即如果指定该对象的属性或数组的特定元素,它将反映调用范围中的更改。有些人称它为通过引用传递,因为它的行为类似,但从技术上讲,变量本身在任何情况下都是通过值传递的。哈哈,我现在看到这个问题,我笑了。我又看了一遍,当你指出JS中的所有内容都是按值传递的,当我传递一个对象时,它本质上是一个引用,一个我可以重写的半原语,因此不会在调用范围内持续存在,或者如果我更改属性,它显然也会在调用范围内改变它。好极了!