JavaScript中基本数据类型和引用类型的参数传递

320 阅读2分钟

Js中所有函数的参数传递都是按值传递的,也就是把函数外面的值复制给函数内部的参数,就和把值从一个变量复制到另一个变量一样.而JS中某种意义上来说只包含两种类型的变量,即基本类型引用类型。 这两种类型的变量解析方式完全不同。在Js中,定义变量进行初始化就会开辟空间。

一、基本类型传参

对于基本类型(Undefined、Null、Boolean、Number、String)会在栈空间中开辟空间,存储值本身。 赋值时将栈空间中的内容复制一份进行赋值,而不同的变量有不同的栈空间,互不影响。

function test(num) {
            num = 100
            num++
            return num
        }
        let num = 10
        test(num)
        console.log(num)           // 10
        console.log(test(num))     // 101

这段代码主要是涉及到实参和形参传递时,如果类型是值类型的时候的特性,值类型数据在做为参数传递的时候,会将值的副本赋值一份进行传递,方法的形参是一个局部遍历,同时如果变量是值类型,那么是将实参的值的副本复制一份进行赋值,那么方法中的形参的操作和实参没有任何的关系了,所以num打印出的结果是10,test(num)打印出的结果才是101

二、引用类型传递参数

对于引用类型(Array、Object、Function)会在栈空间中开辟空间,存储堆空间的引用地址,真正的值存储在堆空间。 赋值时也是将栈空间中的内容复制一份进行赋值,造成形参和实参本质上指向同一个堆空间,修改其中一个,另外一个也会变化。

function test(arr) {
            arr[0] = 100
            arr[0]++
        }
        let nums = [10, 20, 30]
        test(nums)
        console.log(nums[0])       // 101

这段代码主要涉及到引用类型的数据做为参数传递时的特性 引用类型做为参数传递,传递的是变量的引用地址,会造成实参和形参指向同一个地址空间,修改其中一个,另外一个也会变化。所以这个题目中,方法中对arr[0]的修改,会改变外面的nums的值,所以答案为101

进一步验证引用类型传参

function test(obj) {
            obj.name = "James"
            obj = {}
            obj.name = "Kevin"
        }
        let person = {}
        test(person)
        console.log(person.name)  // James 

在这段代码中,给obj添加了新的属性name之后,又将obj定义为一个新的对象并重新为name属性赋了新值。这说明即使在函数内部修改了参数的值,但原始的引用还保持不变。在函数内部定义的新的对象obj,只是函数的内部对象而已。