JavaScript基础教程 参数传递中值和引用的一种理解
小作 2018-03-07 来源 :网络 阅读 571 评论 0

摘要:值(value)和引用(reference)是各种编程语言老生常谈的话题,js也不例外。 我将在这篇JavaScript基础教程中剖析一个例子的实际运行过程,跟大家分享我对js参数传递中的值和引用的理解。

值(value)和引用(reference)是各种编程语言老生常谈的话题,js也不例外。

我将在这篇JavaScript基础教程中剖析一个例子的实际运行过程,跟大家分享我对js参数传递中的值和引用的理解。

参考官网数据类型的两种分类,本文将这两种分类简称为基本类型(boolean, null, undefined, string, number, symbol)和object类型。

首先,用一个example 演示参数传递的应用:

var obj = {};

obj.inner = 10;

var num = 10;var str = 'Hello';var boo = true;var oth = null;var und = undefined;var sym = Symbol('foo');

function passingobject(myobj){

    myobj.inner  = 1 + myobj.inner ;

}

function passingvalue(myvalue){

  switch(typeof myvalue){

    case 'number':

        myvalue = myvalue + 1;

        break;

      case 'string':

        myvalue = 'I am a new string now!';

        break;

      case 'boolean':

        myvalue= false;

        break;

      default:

        myvalue = 'Null, Undefined, or Symbol';

     }

  }

 

  console.log("before num = " + num);  // before num = 10

  passingvalue(num);

  console.log("after num = " + num);  // after num = 10

  console.log("before str = " + str); // before str = Hello

  passingvalue(str);

  console.log("after str = " + str);  // after str = Hello

  console.log("before boo = " + boo); // before boo = true

  passingvalue(boo);

  console.log("after boo = " + boo);  // after boo = false

  console.log("before oth = " + oth); // before oth = null

  passingvalue(oth);

  console.log("after oth = " + oth);  // after oth = null

  console.log("before und = " + und); // before und = undefined

  passingvalue(und);

  console.log("after und = " + und);  // after und = undefined

  console.log(sym); // Symbol(foo)

  passingvalue(sym);

  console.log(sym); // Symbol(foo)

  console.log("before obj.inner = " + obj.inner); // before obj.inner = 10

  passingobject(obj); // after obj.inner = 11

  console.log("after obj.inner = " + obj.inner);


从example 1 的结果似乎可以总结出以下两条结论:

1. 传递的数据类型为基本类型(number, string boolean, null, undefined, symbol),在参数传递过程中,函数内部对传递值的操作并不影响原始值。

2. 传递的数据类型为object, 在参数传递过程中,函数内部对传递值的操作会导致原始值的改变。

然而, 有没有其他特殊情况呢?

有一种在stackoverflow讨论很火热的用法,跟结论二背道而行。example 2。

例子引自://stackoverflow.com/questions/518000/is-javascript-a-pass-by-reference-or-pass-by-value-language

 1 function changeStuff(a, b, c)

 2 {

 3   a = a * 10;

 4   b.item = "changed";

 5   c = {item: "changed"};

 6 }

 7 

 8 var num = 10;

 9 var obj1 = {item: "unchanged"};10 var obj2 = {item: "unchanged"};11 12 console.log(obj1.item); // unchanged13 console.log(obj2.item); // unchanged14 changeStuff(num, obj1, obj2);15 console.log(obj1.item); // changed16 console.log(obj2.item); // unchanged

example 2中, obj2.item并没有被函数changeStuff改变。changeStuff内部同样改变了b、c的值,为什么obj1被改变了(L15)而obj2没有被改变呢?

我用js的执行上下文对这种现象进行解释,如图。

 JavaScript基础教程 参数传递中值和引用的一种理解

在js运行过程中,编辑器动态生成执行上下文(execution context),example 2中,首先生成global的执行上下文和changeStuff的执行上下文。

执行到changeStuff(num, obj1, obj2)的时候, a, b, c指向参数num, obj1, obj2,a和num指向10, b跟obj1指向同一个值,c跟obj2指向同一个值。

执行step 1的时候,对a重新赋值,为a赋值前的10倍,从此a与num毫无关系。

执行step 2的时候,对b所指向的值的item属性进行重新赋值,这个赋值只改变了item的值, 而obj1和b仍然指向同一个值。

执行step 3的时候,对c重新赋值,从此c与obj2再无瓜葛,因此即使c有一个叫item的属性,与obj2的item属性有着各自的值,并没有影响obj2.item。

也就是说,js函数参数传递过程中,若函数内部对参数重新赋值,这个赋值过程不会影响原始变量的值。

这也很好地解释了基本类型的参数变量(结论1)不会受影响的现象,基本类型的参数变量每一次改变都是一次全新赋值,对原始变量不会造成影响。


总结

在js函数传递中,当基本类型(number, string, boolean, null, undefined, symbol)变量作为参数传递时,函数内部对参数的任何操作都不会改变变量的值。

当object类型变量作为参数传递时,函数内部对参数的操作会影响变量的值,除非函数内部对参数重新赋值(任何类型的值)。


希望这篇文章可以帮助到你。总之,同学们,你想要的职坐标IT频道都能找到!


本文由 @小作 发布于职坐标。未经许可,禁止转载。
喜欢 | 0 不喜欢 | 0
看完这篇文章有何感觉?已经有0人表态,0%的人喜欢 快给朋友分享吧~
评论(0)
后参与评论

您输入的评论内容中包含违禁敏感词

我知道了

助您圆梦职场 匹配合适岗位
验证码手机号,获得海同独家IT培训资料
选择就业方向:
人工智能物联网
大数据开发/分析
人工智能Python
Java全栈开发
WEB前端+H5

请输入正确的手机号码

请输入正确的验证码

获取验证码

您今天的短信下发次数太多了,明天再试试吧!

提交

我们会在第一时间安排职业规划师联系您!

您也可以联系我们的职业规划师咨询:

小职老师的微信号:z_zhizuobiao
小职老师的微信号:z_zhizuobiao

版权所有 职坐标-一站式IT培训就业服务领导者 沪ICP备13042190号-4
上海海同信息科技有限公司 Copyright ©2015 www.zhizuobiao.com,All Rights Reserved.
 沪公网安备 31011502005948号    

©2015 www.zhizuobiao.com All Rights Reserved

208小时内训课程