成人国产在线小视频_日韩寡妇人妻调教在线播放_色成人www永久在线观看_2018国产精品久久_亚洲欧美高清在线30p_亚洲少妇综合一区_黄色在线播放国产_亚洲另类技巧小说校园_国产主播xx日韩_a级毛片在线免费

資訊專欄INFORMATION COLUMN

JavaScript中的求值策略

MrZONT / 2580人閱讀

摘要:關(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ù)的引用。bobj1共享一個(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

相關(guān)文章

  • 「譯」代碼優(yōu)化策略 — Idle Until Urgent

    摘要:我將這個(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...

    Ashin 評(píng)論0 收藏0
  • JS中的值是按值傳遞,還是按引用傳遞呢?

    摘要:按引用傳遞時(shí),函數(shù)的形參接收實(shí)參的隱式引用,而不再是副本。探究值的傳遞方式的基本類型,是按值傳遞的。但這樣是否說明的對(duì)象是按引用傳遞的呢我們?cè)倏聪旅娴睦尤匀皇遣⑽幢恍薷臑槿绻前匆脗鬟f,修改形參的值,應(yīng)該影響到實(shí)參才對(duì)。 最近遇到個(gè)有趣的問題:JS中的值是按值傳遞,還是按引用傳遞呢? 在分析這個(gè)問題之前,我們需了解什么是按值傳遞(call by value),什么是按引用傳遞(ca...

    Jochen 評(píng)論0 收藏0
  • 【譯】小二百行 JavaScript 打造 lambda 演算解釋器

    摘要:在開始解析之前,先通過詞法分析器運(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...

    KitorinZero 評(píng)論0 收藏0
  • JavaScript 編程精解 中文第三版 十二、項(xiàng)目:編程語(yǔ)言

    摘要:來源編程精解中文第三版翻譯項(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 自豪地采用...

    Near_Li 評(píng)論0 收藏0
  • JavaScript程序設(shè)計(jì)》—— 第四章 表達(dá)式語(yǔ)句

    摘要:每個(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。 ...

    solocoder 評(píng)論0 收藏0

發(fā)表評(píng)論

0條評(píng)論

最新活動(dòng)
閱讀需要支付1元查看
<