最新国产好看的视频,伊人天堂AV在线,国产Aaaaaa视频,蜜臀视频在线观看一区,人妻av色图,密臀久久久精品影片,青青视频免费观看毛片,久草在线观看视,国产三级精品色情在线

一文詳解JavaScript中的按值傳遞和按引用傳遞

 更新時(shí)間:2024年05月07日 11:01:51   作者:劉同學(xué)有點(diǎn)忙  
編程語(yǔ)言中,把一個(gè)變量的值賦值給另一個(gè)變量,或者給函數(shù)調(diào)用傳遞參數(shù)有兩種方式:按值傳遞和按引用傳遞,本文將給大家詳細(xì)介紹JavaScript中的按值傳遞和按引用傳遞,需要的朋友可以參考下

JavaScript中幾乎都是按值傳遞

編程語(yǔ)言中,把一個(gè)變量的值賦值給另一個(gè)變量,或者給函數(shù)調(diào)用傳遞參數(shù)有兩種方式:按值傳遞按引用傳遞。

JavaScript中幾乎都是按值傳遞。我們看一個(gè)例子:

let a = 1
let b = a
b = 2
console.log(a) // 1
  • 上面的代碼,聲明了一個(gè)變量a,賦值為1;
  • 然后又聲明了一個(gè)變量b,將變量a的值1賦值給變量b,此時(shí)變量b的值也是1;
  • 接著我們將變量b的值修改為2;
  • 此時(shí)打印變量a的值應(yīng)該仍然是1,而不是2。

這就是按值傳遞,我們把變量a的值賦值給變量b的時(shí)候,只是把1這個(gè)值復(fù)制了一份給變量b,變量b的值的修改并不會(huì)影響到變量a的值。

很好,到目前為止,我們說(shuō)上面的代碼是按值傳遞很好理解,很符合我們的直覺(jué)。

上面是基元值的情況,如果換成引用類型的值呢?看下面的代碼。

const foo = {
    a: 1
}
const bar = foo
bar.a = 2
console.log(foo.a) // 2
  • 上面的代碼聲明了一個(gè)變量foo,給它賦值了一個(gè)對(duì)象;
  • 然后又聲明了一個(gè)變量bar,把變量foo指向的對(duì)象賦值給變量bar;
  • 接著我們通過(guò)bar.a把對(duì)象的屬性a修改為2;
  • 我們發(fā)現(xiàn)foo.a也被修改了!

說(shuō)好的按值傳遞呢?如果是按值傳遞,修改bar.a不應(yīng)該導(dǎo)致foo.a被修改啊,這好像不太符合直覺(jué)啊?難道引用類型的值是按引用傳遞嗎?

并不是。JavaScript中引用類型的值也是按值傳遞的,只不過(guò)這個(gè)傳遞的值是對(duì)象在堆內(nèi)存中的地址。

看上面的圖片可以更清楚地理解這個(gè)過(guò)程,假設(shè)對(duì)象在堆內(nèi)存中的地址是0x100,那么按值傳遞的就是0x100這個(gè)地址。bar.a修改了對(duì)象里屬性的值,但是foobar仍都然都指向地址0x100,所以通過(guò)bar.a修改對(duì)象屬性值會(huì)反應(yīng)到foo.a上。

上面的圖只是一個(gè)粗略的方便理解的圖,下面的圖可能更符合代碼實(shí)際的內(nèi)存分布。

另外,仍然是上面的代碼,如果我們稍加改動(dòng),給變量bar賦值一個(gè)新的對(duì)象,那么變量foo和變量bar就指向不同的內(nèi)存地址了,修改變量bar將不再導(dǎo)致變量foo被修改。有些支持按引用傳遞的語(yǔ)言,類似的操作會(huì)導(dǎo)致變量foo也被修改,這個(gè)我不太了解,所以就不展開(kāi)了。

const foo = {
    a: 1
}
let bar = foo
bar = {
    a: 2
}
console.log(foo.a) // 1

ES Module中的live bindings

前面我們說(shuō)了,JavaScript中幾乎都是按值傳遞,這樣說(shuō)通常都有例外。ES Module中export導(dǎo)出的變量被稱為live bindings(實(shí)時(shí)綁定),這是JavaScript中唯一按引用傳遞的情況。

// a.js
export let count = 1
export function increment() {
    count++
}
// b.js
import { count, increment } from './a.js'
console.log(count) // 1
// count = 2 // import的變量是只讀的,不能修改,嘗試修改會(huì)報(bào)錯(cuò) TypeError: Assignment to constant variable.
increment()
console.log(count) // ?

讓我們暫停下來(lái),思考一下,上面的代碼中,第二個(gè)console.log(count)會(huì)輸出什么?

答案是2。ES Module中export的變量,其它模塊import進(jìn)來(lái)之后是只讀的,嘗試修改會(huì)報(bào)錯(cuò)。但是export變量的模塊可以另外導(dǎo)出一個(gè)方法用來(lái)修改這個(gè)變量,變量的修改會(huì)同步反應(yīng)在兩個(gè)模塊中,這種情況被稱為live bindings,是按引用傳遞的。

上面類似的代碼在CommonJs中的執(zhí)行結(jié)果截然不同。

// a.js
let count = 1
function increment() {
    count++
}
module.exports = {
    count,
    increment
}
const { count, increment } = require('./a.js')
console.log(count) // 1
count = 2  // 可以修改
console.log(2) // 2
increment()
console.log(count) // 是2而不是3

require導(dǎo)入的變量是可以被修改的,上面的代碼中最后的console.log(count)的值是2而不是3,因?yàn)檫@里count是按值傳遞的。

總結(jié)

  • JavaScript中幾乎都是按值傳遞。
  • ES Module中export導(dǎo)出的變量是JavaScript中唯一的按引用傳遞,這被稱作live bindings。另外export導(dǎo)出的變量是只讀的,在模塊外部不允許修改它的值,通??梢灶~外導(dǎo)出一個(gè)方法用來(lái)修改這個(gè)變量。

以上就是一文詳解JavaScript中的按值傳遞和按引用傳遞的詳細(xì)內(nèi)容,更多關(guān)于JavaScript按值和按引用傳遞的資料請(qǐng)關(guān)注腳本之家其它相關(guān)文章!

相關(guān)文章

最新評(píng)論

法库县| 玛沁县| 崇左市| 怀柔区| 兴仁县| 太白县| 洞头县| 济阳县| 涟水县| 河北省| 秦皇岛市| 文成县| 威宁| 遵义市| 洛宁县| 渑池县| 友谊县| 贵州省| 南平市| 麟游县| 肥城市| 集安市| 雅安市| 龙川县| 娱乐| 龙门县| 同江市| 观塘区| 濉溪县| 湘乡市| 镇原县| 两当县| 马山县| 陇西县| 司法| 武穴市| 洛宁县| 甘泉县| 新郑市| 巴南区| 河曲县|