美文网首页
javascript中所有函数参数都是按值传递

javascript中所有函数参数都是按值传递

作者: 指尖跳动 | 来源:发表于2020-02-17 18:18 被阅读0次

在看《JavaScript高级程序设计》(第三版)的时候,传递参数这一节,里面提到

ECMAScript中所有函数的参数都是按值传递的

它自己的解释是:

把函数外部的值复制给函数内部的参数,就和把值从一个变量复制到另一个变量一样。
基本类型值的传递如同基本类型变量的复制一样,
而引用类型值的传递,则如同引用类型变量的复制一样。

我们先明白几个概念,之后再讨论。

数据类型

基本数据类型,有6种,Undefined、Null、Boolean、Number、String、Symbol

引用类型,Object、Array、Date、RegExg、Function等

数据类型介绍,可以参考JavaScript数据类型的非常6+1

内存空间

var a = 2
var b = 'abc'
var c = true
var d = {value : 1}
var e = [1, 2, 3]

定义的以上几个变量,在内存中,所占用的空间如图示意:


基础数据类型值,在栈中存储实际的值。引用数据类型值,在栈中存储引用地址值,在堆中存储实际的值。

赋值拷贝/复制

基础数据类型,赋值拷贝,拷贝实际值

var a = 1

var b = a

b = 2

console.log(a) // 1

引用类型,赋值拷贝,拷贝引用地址,浅拷贝。可以参考javascript中的浅拷贝ShallowCopy与深拷贝DeepCopy

var a = {value : 1}

var b = a

b.value = 2

console.log(a.value) // 2

举例分析

明白了以上几个概念,我们再来说说,把函数外部的值复制给函数内部的参数,就和把值从一个变量复制到另一个变量一样。也就是一个赋值复制过程。我们举几个例子分析下。

1. 传递基础类型,函数中不修改参数类型
var a = 1

function func(o) {

    o = 2

    console.log(o)

}

func(a) // 2

console.log(a) // 1

这里的func函数,传递了一个参数o,而参数实际上是函数的局部变量。那么,我们就可以修改函数

var a = 1

function func() {

    var o = a // 函数内部的参数变量,赋值函数外部的值

    o = 2 // 修改内部变量的值

    console.log(o)

}

func(a) // 2

console.log(a) // 1

可以得到相同的结果。他们在内存中的变化,如图示意:

从以上图中,我们能清楚的看出,变量a一直等于1,而变量o,由于赋值之后,复制了a的实际值,在内存中开辟了空间,存储在栈中。再执行func函数,修改变量o的值,只会影响其自身。

2. 传递基础类型,函数中修改类型
var a = 1

function func(o) {

    o = {value : 1}

    console.log(o)

}
func(a) // {value: 1}

console.log(a) // 1

同理,我们也可以修改这里的函数

var a = 1

function func() {

    var  o = a // 函数内部的参数变量,赋值函数外部的值

    o = {value : 1} // 修改内部变量的值

    console.log(o)  // {value: 1}

}
func() // {value: 1}

console.log(a) // 1

内存中的变化示意图:


从以上图中,我们能清楚的看出,变量a一直等于1,而变量o,由于内部参数赋值之后,复制了a的实际值,在内存中开辟了空间,存储在栈中。再执行func函数,修改变量o的值,只会影响其自身。

3. 传递引用类型,函数中不修改类型
var a = { value : 1 }

function func(o) {

    o.value = 2

    console.log(o)

}

func(a) // { value : 2}

console.log(a) // {value : 2}

同理,我们也可以修改这里的函数

var a = { value : 1 }

function func() {

    var  o = a // 函数内部的参数变量,赋值函数外部的值

    o.value = 2 // 修改内部变量的值

    console.log(o)  // {value: 2}

}
func() // {value: 2}

console.log(a) // {value: 2}

内存中的变化示意图:


从以上图中,我们能清楚的看出,由于变量a是引用类型,通过函数内部参数的赋值复制,传递了引用地址值,那么变量a和o会指向同一个内存对象。再执行func函数,修改变量o在堆内存中的值,并没有修改在栈中的引用地址的值。这样,由于变量o和变量a使用的是同一个引用地址,也就是同一个堆内存中的值,那么变量a的值,也就会随着变量o的变化而变化了。

4. 传递引用类型,函数中修改类型
var a = {value : 1 }

function func(o) {

    o = 2

    console.log(o)

}

func(a) // 2

console.log(a) // { value : 1}

接下来,我们也可以修改这里的函数

var a = { value : 1 }

function func() {

    var  o = a // 函数内部的参数变量,赋值函数外部的值

    o = 2 // 修改内部变量的值

    console.log(o)  // 2

}
func() // 2

console.log(a) // {value: 1}

内存中的变化示意图:

由于变量a是引用类型,通过函数内部参数的赋值复制,传递了引用地址值,那么变量a和o会指向同一个内存对象。再执行func函数时,改变了变量o的数据类型,变成了基础数据类型,也就切断了引用。这样,变量a和o就没有关系了。

总结

JavaScript中所有函数参数都是按值传递的。基本类型值,传递的是实际值,引用类型,传递的是引用地址值。

相关文章

  • 2019-06-26

    深入理解JavaScript 参数按值传递 定义:ECMAScript中所有函数的参数都是按值传递的。 值传递:函...

  • 数据结构与算法 javascript

    基础概念 javascript中,函数的参数传递方式都是按值传递,没有按引用传递的参数。但是javascript中...

  • 值传递or引用传递

    javascript都是按值传递 javascript的函数的参数传递,传递的都是值,参数是 Object 类型的...

  • 再学JS--函数参数传递类型

    JavaScript的函数参数传递分为按值传递、按引用传递以及按共享传递。 按值传递 什么是按值传递? 把函数外部...

  • 值传递和引用传递——javascript

    1.javascript所有函数的基本类型参数都是按值传递,而Object类型是共享传递(call by shar...

  • 数组

    Math.sqrt(x) Math.abs(x) Javascript中,函数的参数传递方式都是按值传递,没有引用...

  • JavaScript参数传递

    《javascript高级程序设计》4.1.3:所有函数的参数都是按值传递的就是说把函数外部的值赋值给函数内部的参...

  • 带你深入理解传递参数

    传递参数 ECMAScript中所有函数的参数都是按值传递的。也就是说,把函数外部的值复制给函数内部的参数,就和把...

  • javascript中所有函数参数都是按值传递

    在看《JavaScript高级程序设计》(第三版)的时候,传递参数这一节,里面提到 ECMAScript中所有函数...

  • JavaScript函数的参数传递

    JavaScript函数的参数传递取决于参数的类型: 若参数为基本类型,那么按值传递 若参数为引用类型,那么按共享...

网友评论

      本文标题:javascript中所有函数参数都是按值传递

      本文链接:https://www.haomeiwen.com/subject/yskifhtx.html