鍍金池/ 問答/HTML/ js數(shù)組引用

js數(shù)組引用

var a = [
  {
    name: 'is_empty',
    items: ['1', '2', '3', '4', '5']
  },
  {
    name: 'is_true',
    items: ['6', '7', '8', '9', '10']
  }
]
var b = []

for (var i = 0; i < a.length; i++) {
  b[i] = a[i]
}

// 注釋掉a[0] = [], 此時(shí)B 為{[], ['1', '2', '3', '4', '5']}
// 未注釋掉的情況下,B為{[1, 2, 3, 4, 5]}, {[6, 7, 8, 9, 10]}

// a[0] = []
// console.log(b)  // {['6', '7', '8', '9', '10']}, {['6', '7', '8', '9', '10']}

// a[0].items = []
// console.log(b) // {[], [6, 7, 8, 9, 10]}

重置a[0] = []的時(shí)候,數(shù)組的引用被切斷了,但是如果只重置a[0].items = []時(shí)候,引用卻并未被切斷,這是為什么?

回答
編輯回答
愿如初

兩個(gè)都不是同一個(gè)東西,a[0]指的是第一個(gè)數(shù)組元素,a[0].items指的是第一個(gè)數(shù)組元素的對(duì)象屬性items,所以你賦值的時(shí)候得到的結(jié)果肯定不一樣了。

2017年1月6日 13:59
編輯回答
替身

假設(shè)這有個(gè)數(shù)組[{},{}](就是你上面a引用的那個(gè),我簡寫吧)

a是它的指針,指向這個(gè)數(shù)組所在的地址

然后你創(chuàng)建了一個(gè)變量b,把那個(gè)數(shù)組里面的元素地址放到了b里面,因?yàn)槟莻€(gè)數(shù)組里面的元素是對(duì)象 所以b[i] = a[i]的操作也只是a[i]把某個(gè)地址賦值給了b[i]。他們都是一個(gè)指針。

下面進(jìn)入分支:

a[0] = []的情況:a[0] 本來是一個(gè)指向[{},{}]其中一個(gè)元素的指針,后被替換成[]空數(shù)組的指針。然后給這個(gè)指針?biāo)傅膶?duì)象(也就是空數(shù)組)添加了一個(gè)屬性item,這個(gè)屬性是一個(gè)空數(shù)組的指針。b還是指向[{},{}],沒有任何影響。

a[0] = []被注釋的情況:下一條語句 a[0].item = []。在這條語句執(zhí)行前,a[0]還是和b[0]一樣,是指向[{},{}]一個(gè)元素的指針。執(zhí)行這條語句之后,也就是a[0]指向的這個(gè)對(duì)象的item屬性被覆蓋為一個(gè)空數(shù)組的指針。但是b[0]指向的內(nèi)存地址還是沒有變的,還是跟a[0]一樣的。所以b[0].item也還是指向那一塊內(nèi)存,所以b[0].item = a[0].item = []。
(取屬性的操作會(huì)對(duì)對(duì)象所在內(nèi)存地址塊執(zhí)行操作,個(gè)人總結(jié)。。)

需要注意的地方就是 引用類型的賦值是把對(duì)象的地址傳遞給變量,讓變量成為它的指針。所以a[0] = b[0] 都一樣都指向[{},{}]的一個(gè)元素?;蛟S你之前很有心的先var b = []開辟了一個(gè)內(nèi)存。但是這個(gè)新的內(nèi)存里面存放的東西,都是指向[{},{}]的指針。也就是通篇涉及到的有三個(gè)地址塊。一個(gè)是存放a數(shù)組的地址,一個(gè)是存放b數(shù)組的地址,一個(gè)是[{},{}]的地址。

參考關(guān)鍵字:Call by sharing

附上例子希望能看懂:
圖片描述

歡迎指正,一起進(jìn)步。剛剛開始接觸可能描述不規(guī)范。

2018年2月15日 04:09