摘要:關(guān)于的求值策略,問中函數(shù)的參數(shù)傳遞是按值傳遞還是按引用傳遞回答很經(jīng)典。所以不能說中函數(shù)的參數(shù)傳遞嚴(yán)格按值傳遞或按引入傳遞。中還采用一種參數(shù)傳遞策略,叫按共享傳遞。中參數(shù)是必須先求值再作為實(shí)參傳入函數(shù)的。參考求值策略中函數(shù)參數(shù)的默認(rèn)值
最近在研究 lambda 演算中的 η-變換 在 JavaScript 中的應(yīng)用,偶然在 stackoverflow 上看到一個(gè)比較有意思的問題。關(guān)于 JavaScript 的求值策略,問JS中函數(shù)的參數(shù)傳遞是按值傳遞還是按引用傳遞?回答很經(jīng)典。
一栗以蔽之function changeStuff(a, b, c) { a = a * 10; b.item = "changed"; c = {item: "changed"}; } var num = 10; var obj1 = {item: "unchanged"}; var obj2 = {item: "unchanged"}; changeStuff(num, obj1, obj2); console.log(num); // 10 console.log(obj1.item); // changed console.log(obj2.item); // unchanged
如果說JS中函數(shù)的參數(shù)傳遞是按值傳遞,那么在函數(shù)changeStuff內(nèi)部改變b.item的值將不會(huì)影響外部的obj1對(duì)象的值。
如果說JS中函數(shù)的參數(shù)傳遞是按引入傳遞,那函數(shù)changeStuff內(nèi)部所做的改變將會(huì)影響到函數(shù)外部所有的變量定義,num將會(huì)變成100、obj2.item將會(huì)變成changed。很顯然實(shí)際不是這樣子的。
所以不能說JS中函數(shù)的參數(shù)傳遞嚴(yán)格按值傳遞或按引入傳遞??偟膩碚f函數(shù)的參數(shù)都是按值傳遞的。JS中還采用一種參數(shù)傳遞策略,叫按共享傳遞。這要取決于參數(shù)的類型。
如果參數(shù)是基本類型,那么是按值傳遞的;
如果參數(shù)是引用類型,那么是按共享傳遞的。
參數(shù)傳遞ECMAScript 中所有函數(shù)的參數(shù)都是按值傳遞的。也就是說,把函數(shù)外部的值復(fù)制給函數(shù)內(nèi)部的參數(shù),就和把值從一個(gè)變量復(fù)制到另一個(gè)變量一樣。基本類型值的傳遞如同基本類型變量的復(fù)制一樣,而引用類型值的傳遞,則如同引用類型變量的復(fù)制一樣。-- 《JavaScript高級(jí)程序設(shè)計(jì)》
紅寶書上講所有函數(shù)的參數(shù)都是按值傳遞的,到底是不是呢?讓我們分析下上面的栗子:
按值傳遞JavaScript中基本類型作為參數(shù)的策略為 按值傳遞(call by value):
function foo(a) { a = a * 10; } var num = 10; foo(num); console.log(num); // 10 沒有變化
這里看到函數(shù)內(nèi)部參數(shù)的改變并沒有影響到外部變量。按值傳遞沒錯(cuò)。
按共享傳遞JavaScript中對(duì)象作為參數(shù)傳遞的策略為 按共享傳遞(call by sharing):
修改參數(shù)的屬性將會(huì)影響到外部對(duì)象
重新賦值將不會(huì)影響到外部對(duì)象
按上面栗子函數(shù)內(nèi)部修改了參數(shù)b的屬性item,會(huì)影響到函數(shù)外部對(duì)象,因而obj1的屬性item也變了。
function bar(b) { b.item = "changed"; console.log(b === obj1) // true } var obj1 = {item: "unchanged"}; bar(obj1); console.log(obj1.item); // changed 修改參數(shù)的屬性將會(huì)影響到外部對(duì)象
從b === obj1打印結(jié)果為true可以看出,函數(shù)內(nèi)部修改了參數(shù)的屬性并沒有影響到參數(shù)的引用。b和obj1共享一個(gè)對(duì)象地址,所以修改參數(shù)的屬性將會(huì)影響到外部對(duì)象。
而將參數(shù)c重新賦值一個(gè)新對(duì)象,將不會(huì)影響到外部對(duì)象。
function baz(c) { c = {item: "changed"}; console.log(c === obj2) // false } var obj2 = {item: "unchanged"}; baz(obj2); console.log(obj2.item); // unchanged 重新賦值將不會(huì)影響到外部對(duì)象
將參數(shù)c重新賦值一個(gè)新對(duì)象,那么c就綁定到了一個(gè)新的對(duì)象地址,c === obj2打印結(jié)果為false,判斷他們不再共享同一個(gè)對(duì)象地址。它們各自有獨(dú)立的對(duì)象地址。所以重新賦值將不會(huì)影響到外部對(duì)象。
總結(jié)可以說 按共享傳遞 是 按值傳遞 的特例,傳遞的是引用地址的拷貝。所以紅寶書上說的也沒錯(cuò)。
可以把 ECMAScript 函數(shù)的參數(shù)想象成局部變量。-- 《JavaScript高級(jí)程序設(shè)計(jì)》延伸 - 惰性求值
前面了解到了所有函數(shù)的參數(shù)都是按值傳遞的。JavaScript 中參數(shù)是必須先求值再作為實(shí)參傳入函數(shù)的。但是在ES6中有一個(gè)特例。
參數(shù)默認(rèn)值不是傳值的,而是每次都重新計(jì)算默認(rèn)值表達(dá)式的值。也就是說,參數(shù)默認(rèn)值是惰性求值的。 -- 《ECMAScript 6 入門》
let x = 99; function foo(p = x + 1) { console.log(p); } foo() // 100 x = 100; foo() // 101
上面代碼中,參數(shù)p的默認(rèn)值是x + 1。這時(shí),每次調(diào)用函數(shù)foo,都會(huì)重新計(jì)算x + 1,而不是默認(rèn)p等于 100。
參考求值策略
Is JavaScript a pass-by-reference or pass-by-value language?
ES6 中函數(shù)參數(shù)的默認(rèn)值
文章版權(quán)歸作者所有,未經(jīng)允許請(qǐng)勿轉(zhuǎn)載,若此文章存在違規(guī)行為,您可以聯(lián)系管理員刪除。
轉(zhuǎn)載請(qǐng)注明本文地址:http://systransis.cn/yun/92452.html
摘要:我將這個(gè)策略稱之為閑置直到緊急。請(qǐng)注意,在腳本執(zhí)行時(shí),它作為單個(gè)任務(wù)需要毫秒才能運(yùn)行完成。很明顯,解決方案是將這些代碼分解為多個(gè)任務(wù)。原因如下推遲組件初始化僅在組件尚未渲染時(shí)才有用。這稱為輸入優(yōu)先級(jí)。 showImg(https://img.alicdn.com/tfs/TB1u.rsepzqK1RjSZFzXXXjrpXa-1919-913.png); Idle Until Urge...
摘要:按引用傳遞時(shí),函數(shù)的形參接收實(shí)參的隱式引用,而不再是副本。探究值的傳遞方式的基本類型,是按值傳遞的。但這樣是否說明的對(duì)象是按引用傳遞的呢我們?cè)倏聪旅娴睦尤匀皇遣⑽幢恍薷臑槿绻前匆脗鬟f,修改形參的值,應(yīng)該影響到實(shí)參才對(duì)。 最近遇到個(gè)有趣的問題:JS中的值是按值傳遞,還是按引用傳遞呢? 在分析這個(gè)問題之前,我們需了解什么是按值傳遞(call by value),什么是按引用傳遞(ca...
摘要:在開始解析之前,先通過詞法分析器運(yùn)行源碼,這會(huì)將源碼打散成語(yǔ)法中全大寫的部分。我們基于每個(gè)規(guī)則的名稱的左側(cè)為其創(chuàng)建一個(gè)方法,再來看右側(cè)內(nèi)容如果是全大寫的單詞,說明它是一個(gè)終止符即一個(gè),詞法分析器會(huì)用到它。 本文轉(zhuǎn)載自:眾成翻譯譯者:文藺鏈接:http://www.zcfy.cc/article/661原文:http://tadeuzagallo.com/blog/writing-a-l...
摘要:來源編程精解中文第三版翻譯項(xiàng)目原文譯者飛龍協(xié)議自豪地采用谷歌翻譯部分參考了編程精解第版確定編程語(yǔ)言中的表達(dá)式含義的求值器只是另一個(gè)程序。若文本不是一個(gè)合法程序,解析器應(yīng)該指出錯(cuò)誤。 來源:ApacheCN『JavaScript 編程精解 中文第三版』翻譯項(xiàng)目原文:Project: A Programming Language 譯者:飛龍 協(xié)議:CC BY-NC-SA 4.0 自豪地采用...
摘要:每個(gè)候選項(xiàng)都是大括號(hào)中的語(yǔ)句序列。短路運(yùn)算符有一個(gè)很重要的功能它們并不真的需要布爾值操作數(shù),注意換句話說,不會(huì)將數(shù)字轉(zhuǎn)換為布爾值。練習(xí)對(duì)表達(dá)式求值。首先對(duì)求值,轉(zhuǎn)換為繼續(xù)對(duì)右邊表達(dá)式求值,為,造成短路,不對(duì)進(jìn)行計(jì)算,返回對(duì)表達(dá)式求值。 4.1 聲明語(yǔ)句 聲明語(yǔ)句也叫變量語(yǔ)句,這種語(yǔ)句會(huì)創(chuàng)建新變量??梢栽诼暶髯兞繒r(shí)給出初始值,如果沒有明確給出,變量的值就是undefined。 ...
閱讀 1673·2023-04-26 02:43
閱讀 3104·2021-11-11 16:54
閱讀 1389·2021-09-23 11:54
閱讀 1207·2021-09-23 11:22
閱讀 2392·2021-08-23 09:45
閱讀 875·2019-08-30 15:54
閱讀 3127·2019-08-30 15:53
閱讀 3214·2019-08-30 15:53