js里类型:按值传递和按引用传递

JavaScript08

js里类型:按值传递和按引用传递,第1张

avascript的数据类型分为基本类型和引用类型(对象)。基本类型分为如下几种:

数字字面量

字符串字面量

布尔字面量

undefined

null

引用类型分为如下几种

new Object()

new Array()

new RegExp()

new String()

new Number()

new Bollean()

new 自定义对象()

通过new的方式生成的对象

{},[],正则字面量。

var a = 'abc'

var b = 123

var c = true

var d = undefined

var e = null

var f = {

 n: 'test'

}

f.n = null

var a = {

 b: 123,

 c: 'abc',

 d: true,

 e = null,

 f = {

   h: 'test',

   j: {

     k: 567    }

 }

}

函数的内存使用

functionsay(){  

 var a = '测试'  var b = {

   c: 123  }

}

functionsay(){  var a = '测试'  var b = {

   c: 123  }

}

say()

String;

按值传递,互相不影响

Number

按值传递,互相不影响

Boolean

按值传递,互相不影响

Array

按引用传递,对当前内存指向同一地址:

解决方案:

1.采用es6中Set进行解耦(浅拷贝)

2.使用JSON进行解耦(深拷贝)

3.使用slice函数进行解耦(浅拷贝)

4.利用拓展运算符解决(浅拷贝)

const a2=[...a1]

const[...a2]=a1

Object

按引用传递,对当前内存指向同一地址

采用JSON (深拷贝)

Object.assign()克隆(浅拷贝)

Object.create() 创建(浅拷贝)

浅拷贝只针对单层结构的数组或对象,对于复杂结构的需要采用深拷贝

更多深拷贝 ,可以采用jquery,lodash等类库实现

或者自己实现,对结构一层一层遍历

function copy (obj) {

        var newobj = obj.constructor === Array ? [] : {}

        if(typeof obj !== 'object'){

            return

        }

        for(var i in obj){

           newobj[i] = typeof obj[i] === 'object' ?

           copy(obj[i]) : obj[i]

        }

        return newobj

}

堆是动态分配内存,内存大小不一,也不会自动释放。栈是自动分配相对固定大小的内存空间,并由系统自动释放。

按引用传递的数据 再堆里面存储执行栈的指针

值传递仅仅传递的是值

引用传递,传递的是内存地址,修改后会改变内存地址对应储存的值。

用数组来举例就最清楚了,例如我们定义一个数组a[]={1,2}

那么a[0]=1,a[1]=2。

如果我们把数组a里的元素值作为参数传递,实际上只是进行了值传递,对数组本身没有影响

如果我们把 数组a的指针作为参数传递,那么假如处理的函数就可以直接修改数组a里的值。

代码实例:(只是写个大概的逻辑,语法可能有错误)

main()

{

int a[]={1,2}

test(a)

printf(a[0]) //此处打印的值是3, 这就是引用传递。

}

public void test(int b[])

{

b[0]=3

}

JS求值策略有诸多争议和不同版本。

对于这个问题的答案:“JS中基本类型是按值传递的,对象类型是按共享传递的。”

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

你可以自己写个demo运行下结果就知道。

var a = 1

function foo(x) {

    x = 2

}

foo(a)

console.log(a) // 仍为1, 未受x = 2赋值所影响

var obj = {x : 1}

function foo(o) {

    o.x = 3

}

foo(obj)

console.log(obj.x) // 3, 被修改了!