zoukankan      html  css  js  c++  java
  • js传参是按值传递还是按引用传递?

      今天遇到个题目是有关js传递的,做对了一般,另一半错了,这在做选择题的时候那就是错了,没分的!所以大家如果基础不扎实的话就很容易出错,而且做题的时候心里没底,模棱两可,

    所以还是要实时不断去复习基础知识,这样才能成长更快!

      什么是按值传递?什么是按引用传递?

      按值传递(call by value)是最常用的求值策略:函数的形参是被调用时所传实参的副本。修改形参的值并不会影响实参。
     
      按引用传递(call by reference)时,函数的形参接收实参的隐式引用,而不再是副本。这意味着函数形参的值如果被修改,实参也会被修改。同时两者指向相同的值。

      按值传递由于每次都需要克隆副本,对一些复杂类型,性能较低;按引用传递会使函数调用的追踪更加困难,有时也会引起一些微妙的BUG。

      探究JS值的传递方式

      JS的基本类型,是按值传递的,如下代码可以证明:

    1 var a = 1;
    2 function foo(x) {
    3     x = 2;
    4 }
    5 foo(a);
    6 console.log(a); // 仍为1, 未受x = 2赋值所影响

      而对于引用类型来看如下代码:

    1 var obj = {x : 1};
    2 function foo(o) {
    3     o.x = 3;
    4 }
    5 foo(obj);
    6 console.log(obj.x); // 3, 被修改了!

    说明o跟obj指向的是同一个对象,所以不是按值传递的,但是这就能证明js中对象是按引用传递的吗??少年们可以看如下这个例子:

    1 var foo = {name:'foo'};
    2 function test(o){
    3    o = {name:'bar'};  
    4 }
    5 test(foo);
    6 console.log(foo.name);

    打印foo.name的值确还是'foo',这就说明js中对象的传递也不是不是按引用传递。好凌乱啊...那js中对象究竟是按什么传递呢?

      按共享传递 call by sharing

      严格的说,JS中的基本类型按值传递,对象类型按共享传递的(call by sharing,也叫按对象传递、按对象共享传递)。最早由Barbara Liskov. 在1974年的GLU语言中提出。该求值策略被用于Python、Java、Ruby、JS等多种语言。

    该策略的重点是:调用函数传参时,函数接受对象实参引用的副本(既不是按值传递的对象副本,也不是按引用传递的隐式引用)。 它和按引用传递的不同在于:在共享传递中对函数形参的赋值,不会影响实参的值。实质大家可以这么理解:

    在调用函数传递引用类型的参数时,传递是是对象引用的副本,但是这个对象引用的副本跟原对象引用指向的是同一个地方(也就是该对象在内存中存放的地址),大家要认真理解这句话!!!!

      大家看如下这个例子就印证了按共享传递的观点

    1 var foo = {name:'foo'};
    2 function test(o){
    3   o.name='test';
    4   o={name:'bar'}    
    5 }
    6 test(foo);
    7 console.log(foo);
    8 //打印结果为:
    9 Object {name: "test"}

    从上面结果可以得出第一:对象不是按值传递的,如果是按值传递的话打印出来的foo的name属性的值不会为test,因为按值传递的话传递的是对象的一个副本,对副本的修改不会影响元对象,所以可以证明对象不是按值传递的!

    也可以证明第二:js中对象也不是完全按引用传递的,如果是按引用传递的话在执行o={name:'bar'}这行代码的时候,foo打印的结果应该是Obeject {name:'bar'}了,而结果确是Object {name:'test'},所以综上两点js引

    用类型在作为参数传递时是按共享传递的,即传递是是原对象引用的一个副本,但是这个副本跟原对象的引用指向的都是内存中的对象!

      以前学习中知道对于js中基础类型是按值传递的,引用类型是按引用传递,而没有完全理解透彻js中参数传递的方式,所以对js基础知识的理解是非常重要的,一定要掌握牢固,理解透彻,否则浅尝辄止只会让自己是个半桶水,

    而成不了一个优秀的前端工程师!

  • 相关阅读:
    LC.225. Implement Stack using Queues(using two queues)
    LC.232. Implement Queue using Stacks(use two stacks)
    sort numbers with two stacks(many duplicates)
    LC.154. Find Minimum in Rotated Sorted Array II
    LC.81. Search in Rotated Sorted Array II
    LC.35.Search Insert Position
    前后端分离:(一)
    Redis基本使用(一)
    GIT篇章(二)
    GIT篇章(一)
  • 原文地址:https://www.cnblogs.com/QingChengFE/p/4543608.html
Copyright © 2011-2022 走看看