Javascript 之《函数传参到底是值传递还是引用传递》

前言

这个问题其实困惑了我好久,但是在实际使用中总是得过且过,不想去深究。由于这种态度,在学习 Javascript 过程中,水平一直都是出于半桶水状态,很多概念和原理似懂非懂,模糊不清。

所以,写了一系列的《Javascript 之 ...》就是为了端正态度,认真地研究一下 Javascript 的特性和原理,夯实基础。

今天,这一篇探究的是函数传参的问题:函数传参到底是传值还是传的引用?

 

1.如果是引用传递

var name = 'JS';
function changeName(name){
    name = 'Javascript';  
console.log('name changed: '+name) } changeName(name); // name changed: Javascript console.log(name);
// 'JS'

为什么 name 没有变呢?

如果是引用传递的话,name 应该是会发生变化的。这么说应该是值传递?

也许你下意识也觉得没变是正常的,但这是因为你的经验告诉你的。我们暂且按下不表,看看下一种可能性。

 

2.如果是值传递

var obj = {name: 'JS'};
function changeObjName(obj){
    obj.name = 'Javascript';
    console.log('Obj.name changed: '+obj.name);  
}
changeObjName(obj); // Obj.name changed: Javascript
console.log(obj); // {name: 'Javascript'}

为什么这一次传入的参数被改变了?不是值传递吗?这么说是引用传递了?

那上面的例子又是怎么回事?开始一头雾水了...

 

3.到底是值传递还是引用传递??

其实在 Javascript 的世界中,函数传参并不是一定是一种传参方式,主要依据传入的参数而定。主要有两种情况:

1. 如果是值类型

基本数据类型的变量基本上都是值类型,例如字符串,数值,布尔值等。

值类型的传参是值传递,函数内对这种类型参数的修改不会影响到原来传入的值。

2. 如果是引用类型

复合数据类型如对象,数组等都是引用类型。

引用传参是引用传递,函数内对这种类型参数的修改都会影响到原来传入的值。

 

4.深入函数传参的机制

其实函数接受参数之前,会先在函数作用域内创建一个局部变量,并把传入的参数赋予创建的局部变量,如果值类型传递,就是重新开辟一块内存存储传入变量的值,并把新创建的变量指向此内存地址,因此对此变量的修改并不会影响到外部变量的值;

如果传入的不是值类型,则仅仅是对变量进行引用赋值操作,只是把新创建的局部变量指向外部变量的地址,因此对局部变量的修改就相当于对外部变量的修改。

posted @ 2017-04-11 12:31  Hisheng  阅读(784)  评论(0编辑  收藏  举报