亚洲中字慕日产2020,大陆极品少妇内射AAAAAA,无码av大香线蕉伊人久久,久久精品国产亚洲av麻豆网站

資訊專欄INFORMATION COLUMN

JavaScript中的求值策略

MrZONT / 2629人閱讀

摘要:關于的求值策略,問中函數的參數傳遞是按值傳遞還是按引用傳遞回答很經典。所以不能說中函數的參數傳遞嚴格按值傳遞或按引入傳遞。中還采用一種參數傳遞策略,叫按共享傳遞。中參數是必須先求值再作為實參傳入函數的。參考求值策略中函數參數的默認值

最近在研究 lambda 演算中的 η-變換 在 JavaScript 中的應用,偶然在 stackoverflow 上看到一個比較有意思的問題。關于 JavaScript 的求值策略,問JS中函數的參數傳遞是按值傳遞還是按引用傳遞?回答很經典。

一栗以蔽之
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中函數的參數傳遞是按值傳遞,那么在函數changeStuff內部改變b.item的值將不會影響外部的obj1對象的值。

如果說JS中函數的參數傳遞是按引入傳遞,那函數changeStuff內部所做的改變將會影響到函數外部所有的變量定義,num將會變成100、obj2.item將會變成changed。很顯然實際不是這樣子的。

所以不能說JS中函數的參數傳遞嚴格按值傳遞按引入傳遞。總的來說函數的參數都是按值傳遞的。JS中還采用一種參數傳遞策略,叫按共享傳遞。這要取決于參數的類型。

如果參數是基本類型,那么是按值傳遞的;

如果參數是引用類型,那么是按共享傳遞的。

參數傳遞
ECMAScript 中所有函數的參數都是按值傳遞的。也就是說,把函數外部的值復制給函數內部的參數,就和把值從一個變量復制到另一個變量一樣。基本類型值的傳遞如同基本類型變量的復制一樣,而引用類型值的傳遞,則如同引用類型變量的復制一樣。-- 《JavaScript高級程序設計》

紅寶書上講所有函數的參數都是按值傳遞的,到底是不是呢?讓我們分析下上面的栗子:

按值傳遞

JavaScript中基本類型作為參數的策略為 按值傳遞(call by value):

function foo(a) {
  a = a * 10;
}

var num = 10;

foo(num);

console.log(num); // 10 沒有變化

這里看到函數內部參數的改變并沒有影響到外部變量。按值傳遞沒錯。

按共享傳遞

JavaScript中對象作為參數傳遞的策略為 按共享傳遞(call by sharing):

修改參數的屬性將會影響到外部對象

重新賦值將不會影響到外部對象

按上面栗子函數內部修改了參數b的屬性item,會影響到函數外部對象,因而obj1的屬性item也變了。

function bar(b) {
  b.item = "changed";
  console.log(b === obj1) // true
}

var obj1 = {item: "unchanged"};

bar(obj1);

console.log(obj1.item);   // changed 修改參數的屬性將會影響到外部對象

b === obj1打印結果為true可以看出,函數內部修改了參數的屬性并沒有影響到參數的引用。bobj1共享一個對象地址,所以修改參數的屬性將會影響到外部對象。

而將參數c重新賦值一個新對象,將不會影響到外部對象。

function baz(c) {
  c = {item: "changed"};
  console.log(c === obj2) // false
}

var obj2 = {item: "unchanged"};

baz(obj2);

console.log(obj2.item);   // unchanged 重新賦值將不會影響到外部對象

將參數c重新賦值一個新對象,那么c就綁定到了一個新的對象地址,c === obj2打印結果為false,判斷他們不再共享同一個對象地址。它們各自有獨立的對象地址。所以重新賦值將不會影響到外部對象。

總結

可以說 按共享傳遞按值傳遞 的特例,傳遞的是引用地址的拷貝。所以紅寶書上說的也沒錯。

可以把 ECMAScript 函數的參數想象成局部變量。-- 《JavaScript高級程序設計》
延伸 - 惰性求值

前面了解到了所有函數的參數都是按值傳遞的。JavaScript 中參數是必須先求值再作為實參傳入函數的。但是在ES6中有一個特例。

參數默認值不是傳值的,而是每次都重新計算默認值表達式的值。也就是說,參數默認值是惰性求值的。 -- 《ECMAScript 6 入門》
let x = 99;
function foo(p = x + 1) {
  console.log(p);
}

foo() // 100

x = 100;
foo() // 101

上面代碼中,參數p的默認值是x + 1。這時,每次調用函數foo,都會重新計算x + 1,而不是默認p等于 100。

參考

求值策略

Is JavaScript a pass-by-reference or pass-by-value language?

ES6 中函數參數的默認值

文章版權歸作者所有,未經允許請勿轉載,若此文章存在違規(guī)行為,您可以聯(lián)系管理員刪除。

轉載請注明本文地址:http://www.ezyhdfw.cn/yun/92452.html

相關文章

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

    摘要:我將這個策略稱之為閑置直到緊急。請注意,在腳本執(zhí)行時,它作為單個任務需要毫秒才能運行完成。很明顯,解決方案是將這些代碼分解為多個任務。原因如下推遲組件初始化僅在組件尚未渲染時才有用。這稱為輸入優(yōu)先級。 showImg(https://img.alicdn.com/tfs/TB1u.rsepzqK1RjSZFzXXXjrpXa-1919-913.png); Idle Until Urge...

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

    摘要:按引用傳遞時,函數的形參接收實參的隱式引用,而不再是副本。探究值的傳遞方式的基本類型,是按值傳遞的。但這樣是否說明的對象是按引用傳遞的呢我們再看下面的例子仍然是并未被修改為如果是按引用傳遞,修改形參的值,應該影響到實參才對。 最近遇到個有趣的問題:JS中的值是按值傳遞,還是按引用傳遞呢? 在分析這個問題之前,我們需了解什么是按值傳遞(call by value),什么是按引用傳遞(ca...

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

    摘要:在開始解析之前,先通過詞法分析器運行源碼,這會將源碼打散成語法中全大寫的部分。我們基于每個規(guī)則的名稱的左側為其創(chuàng)建一個方法,再來看右側內容如果是全大寫的單詞,說明它是一個終止符即一個,詞法分析器會用到它。 本文轉載自:眾成翻譯譯者:文藺鏈接:http://www.zcfy.cc/article/661原文:http://tadeuzagallo.com/blog/writing-a-l...

    KitorinZero 評論0 收藏0
  • JavaScript 編程精解 中文第三版 十二、項目:編程語言

    摘要:來源編程精解中文第三版翻譯項目原文譯者飛龍協(xié)議自豪地采用谷歌翻譯部分參考了編程精解第版確定編程語言中的表達式含義的求值器只是另一個程序。若文本不是一個合法程序,解析器應該指出錯誤。 來源:ApacheCN『JavaScript 編程精解 中文第三版』翻譯項目原文:Project: A Programming Language 譯者:飛龍 協(xié)議:CC BY-NC-SA 4.0 自豪地采用...

    Near_Li 評論0 收藏0
  • JavaScript程序設計》—— 第四章 表達式語句

    摘要:每個候選項都是大括號中的語句序列。短路運算符有一個很重要的功能它們并不真的需要布爾值操作數,注意換句話說,不會將數字轉換為布爾值。練習對表達式求值。首先對求值,轉換為繼續(xù)對右邊表達式求值,為,造成短路,不對進行計算,返回對表達式求值。 4.1 聲明語句 聲明語句也叫變量語句,這種語句會創(chuàng)建新變量??梢栽诼暶髯兞繒r給出初始值,如果沒有明確給出,變量的值就是undefined。 ...

    solocoder 評論0 收藏0

發(fā)表評論

0條評論

最新活動
閱讀需要支付1元查看
<