关于一道函数与变量声明赋值的题

2019-08-29  本文已影响0人  twentyshaw

今天做题的时候错了一道这样的题:

var foo = {n:1};
(function(foo){
    var foo; 
    console.log(foo.n);
    foo.n = 3;
    foo = {n:2};
    console.log(foo.n);
})(foo);
console.log(foo.n);

问:打印的结果
答案: 1 2 3


解析要点:

1. 变量的值——基本类型 与 引用类型

1.1 基本类型的值

var a = 1
var b = 2
b = a 

是直接把a对应的栈内存的值复制到b对应的栈内存里,覆盖掉原来的值。

1.2 引用类型的值

引用类型的值就例如:var c = {name:"xiaoc", age: 100}这种

var c = {name:"xiaoc", age: 100}
var d = {name:"xiaod", age: 99}
d = c

它是直接把c对应的栈内存里的地址复制到d对应的栈内存里面,d以前的地址被覆盖,以前的地址对应的堆内存的内容,被垃圾回收机制清除掉

2. 变量的声明与赋值

var a = 1
var a 
console.log(a) //打印出 1

重复声明而没有赋值的语句会被忽略

3. 函数中形参和局部变量同名

在函数内部,会把形参和局部变量同名直接视为变量的重复声明。和上面那种情况一样。不过函数的参数只在函数内部有效。


所以,套用到题目中:

var foo = {n:1};
(function(foo){
    ......
    foo.n = 3; // 函数内部的foo的属性n的值被修改为3,因为地址相同,所以也就是修改了全局foo的属性n的值,变为3
    ......
})(foo);  // foo的值被传进函数里(此时函数里的foo与全局的foo的栈内存里的地址相同)
console.log(foo.n); //打印出全局foo的n的值,全局的地址没有变,只是在函数内部被改为了3,所以打印出3
(function(foo){
    ......
    foo.n = 3;
    ......
})(foo) //foo的值被传进函数里(此时函数里的foo与全局的foo的栈内存里的地址相同)
  1. var foo: 函数内部变量的重复声明 无效
  2. console.log(foo.n) : 打印出接收到的参数的值, 为 1
  3. foo.n = 3: 函数内部的foo的属性n的值被修改为3,因为地址相同,所以也就是修改了全局foo的属性n的值,变为3
  4. foo = {n:2}: 函数内部的foo的地址被修改,指向一个新的堆内存空间,这里存的是{n:2}
  5. console.log(foo.n): 打印出函数内部的foo的n的值,因为在上一句已经被改地址了,所以是2
  6. console.log(foo.n) : 打印出全局foo的n的值,全局的地址没有变,只是在函数内部被改为了3,所以打印出3
上一篇 下一篇

猜你喜欢

热点阅读