基本类型传递和引用类型传递

1.我是变量声明,我会被提升在作用域顶端!

var a;

2.我是变量定义,我的声明部分会被提升,赋值部分不会被提升!

var b = 'test';

3.我是函数定义,或者叫我函数表达式。其实我就是变量定义,只不过恰好被赋值的类型是函数,所以也只提升变量名不提升函数值

var c = function() {
    console.log('test');
}

4.我是函数声明,所以我全部被提升了,包括函数名和函数体。另外,我的优先级比变量声明要高,名字和我相同的变量声明会被忽略!

function d() {
    console.log('test');
}

题目

参数是引用参数

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

结果: 1 2 3

 
var foo = {n:1};
(function(foo){            //形参foo同实参foo一样指向同一片内存空间,这个空间里的n的值为1
    var foo;           //优先级低于形参,无效。形参优先级比变量声明要高,名字和我相同的变量声明会被忽略!
    console.log(foo.n);       //输出1
    foo.n = 3;          //形参与实参foo指向的内存空间里的n的值被改为3
    foo = {n:2};         //形参foo指向了新的内存空间,里面n的值为2.
    console.log(foo.n);       //输出新的内存空间的n的值
})(foo);
console.log(foo.n);            //实参foo的指向还是原来的内存空间,里面的n的值为3.

编译过程:

  • 第一步:进行预编译,var全局变量foo、匿名函数 function、var局部变量foo
  • 第二步:代码自上而下、自左向右执行计算:
    1. 对全局变量foo进行赋值foo={n:1};注意:此值为对象,属于引用类型;
    2. 匿名函数传入参数foo={n:1}自执行;
    3. console.log(foo);打出数字1;
    4. 由于存在foo局部变量,那么对foo变量进行赋值foo={n:3},同时更改了引用类型的参数值,全局foo变量被重新赋值foo={n:3};
    5. 对局部变量foo进行重新赋值foo={n:2};
    6. console.log(foo);打出数字2;
    7. 全局变量foo={n:3},因此,console.log(foo);打出数字3;

可以这样改一下更好理解

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

解释:

var foo={n:"我是形参或全局变量"};
(function (foo) {
    console.log(foo.n);
    foo.n="我改变了参数和全局变量";
    var foo={n:"我是局部变量"};
    console.log(foo.n);
})(foo);
console.log(foo.n);

---------------------------------------------------------------------------------------------------------------------------------------------------------------------
var o={n:1};
(function (foo) {
                     //这里形参相当于var foo =  o ;//这里foo是引用类型,所以都指向的是同一个对象
  var foo ;    //变量提升,但是与形参变量同名,且优先级比形参低,所以被忽略       
    console.log(foo.n);   //因为指向的是同一个对象,所以也就是o.n=1;
    foo.n=3;             //在函数内部改变属性值后,函数外部对象o也会有所反映;
    foo={n:2};        //这里相当于创建了一个新的对象赋值给了foo,就成了函数的一个局部对象了;
    console.log(foo.n);
})(o);
console.log(o.n);


------------------------------------------------------------------------------------------------------------------------------------------
向参数传递引用类型时的值时,会把这个值在内存中的地址复制给一个局部变量,因此这个局部变量的变化会反映在函数的外部。
在javascript高级程序设计中
function setName(obj){
obj.name="xie";
}
var person = new Object();
setName(person);
alert(person.name);//"xie"

参数是传值参数

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

结果:1 2 1

原文地址:https://www.cnblogs.com/aixiuxiu/p/6544964.html