javascript范围引用变量

cod*_*key 1 javascript variables scope reference

所以我对js采访的问题基本上涉及内部函数中的范围和变量,例如假设你有这个:

function(){
var a=b=3;
}
Run Code Online (Sandbox Code Playgroud)

很明显,b没有定义所以它已经成为一个全局变量,现在当你在全局范围内改变b时会发生什么,变化的值是否也是?

我不确定如何测试这个,但是例如,如果你将b改为10,那么现在也是10还是会保持3?

T.J*_*der 8

显然,b没有定义,所以它已成为一个全局变量

仅在松散模式下.不要使用松散模式.:-)使用严格模式,它应该是它应该存在的错误.

现在,当你改变b全局范围时会发生什么,变化的价值a呢?

不,这之间没有任何联系a,并b在所有.变量包含(下面有更多内容).执行此操作时a = b,将复制 in .两个变量之间没有链接.ba

面试官可能会问一个技巧问题(他们这样做很喜欢这样做)和/或他/她可能会陷入常见的错误,所以继续阅读... :-)

我不确定如何测试这个

由于我们处于松散模式,因此我们知道原始函数调用将设置this为在调用期间引用全局对象.由于隐式b全局将是全局对象的属性,我们可以通过更改this.b(全局)来检查它:

function foo() {
  var a = b = 3;
  console.log("(Before) a is " + a + ", b is " + b);
  this.b = 10;
  console.log("(After) a is " + a + ", b is " + b);
}
foo();
Run Code Online (Sandbox Code Playgroud)

(在我们可以使用的浏览器上window而不是this上面,window在引用全局对象的浏览器上是默认的全局.)

值得指出的是,虽然只有一个b,但上面的a每次通话都会有不同foo之处.但我认为这不会影响到这个问题.


在评论中,您询问了"参考变量".JavaScript中没有"引用变量".您可能正在考虑对象引用.关键事实即将来临:对于我们所谈论的内容(将改变b变化a?),变量是否包含对象引用或基元是没有区别的.但这是人们常常犯的错误(甚至可能是面试官提出问题:-))认为这很重要.但是他们混淆改变b(变量)与改变对象的状态所引起的混淆b.

变量包含.将对象引用分配给变量时,该对象引用是一个,它告诉javaScript引擎对象在内存中的位置.例如:

var b = {answer:42};
Run Code Online (Sandbox Code Playgroud)

在记忆中,我们有:

                 +------------+
[b:REF55134]-----|  (object)  |
                 +------------+
                 | answer: 42 |
                 +------------+

b是对对象的引用.我已经在上面表示过REF55134,但我们实际上永远无法访问该引用的原始值.原始值无关紧要,它只是告诉JavaScript引擎对象所在的东西(类似于一个数字).

现在,如果我们这样做:

var a = b;
Run Code Online (Sandbox Code Playgroud)

......我们复制价值b进入a,并在内存中得到这样的:


[b:REF55134]--+
              |   +------------+
              +-->|  (object)  |
              |   +------------+
[a:REF55134]--+   | answer: 42 |
                  +------------+

a并且b它们具有相同的值,因此它们都指向同一个对象.

改变b仍然没有任何影响a.人们感到困惑的地方在于,如果我们改变对象的状态b指向,我们自然也可以看到改变状态a.该b没有改变,它的指向改变事物的状态.

例如:

b.question = "Life, the Universe, and Everything";
Run Code Online (Sandbox Code Playgroud)

给我们:


[b:REF55134]--+
              |   +------------------------------------------------+
              +-->|                   (object)                     |
              |   +------------------------------------------------+
[a:REF55134]--+   | answer: 42                                     |
                  | question: "Life, the Universe, and Everything" |
                  +------------------------------------------------+

b没改变,对象改变了.所以,如果我们这样做console.log(a.question);,我们就会看到这个着名的问题,因为ab指向同一个对象.

如果我们真的改变了b,它根本没有影响a:

b = {foo:"bar"};
Run Code Online (Sandbox Code Playgroud)
                  +------------+
[b:REF14359]----->|  (object)  |
                  +------------+
                  | foo: "bar" |
                  +------------+

                  +------------------------------------------------+
[a:REF55134]----->|                   (object)                     |
                  +------------------------------------------------+
                  | answer: 42                                     |
                  | question: "Life, the Universe, and Everything" |
                  +------------------------------------------------+

请注意,现在b它具有不同的值,指的是不同的对象.