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

詳細討論JavaScript中的求值策略

 更新時間:2021年04月27日 14:10:23   作者:淺笑·  
這篇文章主要介紹了詳細討論JavaScript中的求值策略,對求值策略感興趣的同學,可以參考下

最近在研究 lambda演算 中的 η-變換 在JavaScript中的應用,偶然在 stackoverflow 上看到一個比較有意思的問題。關于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的值將不會影響外部的obj1對象的值。

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

所以不能說JS中函數(shù)的參數(shù)傳遞嚴格按值傳遞或按引入傳遞??偟膩碚f函數(shù)的參數(shù)都是按值傳遞的。JS中還采用一種參數(shù)傳遞策略,叫按共享傳遞。這要取決于參數(shù)的類型。

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

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

參數(shù)傳遞

ECMAScript 中所有函數(shù)的參數(shù)都是按值傳遞的。也就是說,把函數(shù)外部的值復制給函數(shù)內(nèi)部的參數(shù),就和把值從一個變量復制到另一個變量一樣?;绢愋椭档膫鬟f如同基本類型變量的復制一樣,而引用類型值的傳遞,則如同引用類型變量的復制一樣。-- 《JavaScript高級程序設計》

紅寶書上講所有函數(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ù)的改變并沒有影響到外部變量。按值傳遞沒錯。

按共享傳遞

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

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

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

按上面栗子函數(shù)內(nèi)部修改了參數(shù)b的屬性item,會影響到函數(shù)外部對象,因而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ù)的屬性將會影響到外部對象

從b === obj1打印結(jié)果為true可以看出,函數(shù)內(nèi)部修改了參數(shù)的屬性并沒有影響到參數(shù)的引用。b和obj1共享一個對象地址,所以修改參數(shù)的屬性將會影響到外部對象。

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

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

var obj2 = {item: "unchanged"};

baz(obj2);

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

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

總結(jié)

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

可以把 ECMAScript 函數(shù)的參數(shù)想象成局部變量。-- 《JavaScript高級程序設計》

延伸 - 惰性求值

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

參數(shù)默認值不是傳值的,而是每次都重新計算默認值表達式的值。也就是說,參數(shù)默認值是惰性求值的。 -- 《ECMAScript 6 入門》

let x = 99;
function foo(p = x + 1) {
  console.log(p);
}

foo() // 100

x = 100;
foo() // 101

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

以上就是詳細討論JavaScript中的求值策略的詳細內(nèi)容,更多關于JavaScript求值策略的資料請關注腳本之家其它相關文章!

相關文章

最新評論

滨州市| 天气| 安吉县| 新竹县| 阜城县| 治县。| 万安县| 清镇市| 驻马店市| 登封市| 武山县| 西林县| 和硕县| 鱼台县| 卓尼县| 将乐县| 会同县| 衡南县| 都江堰市| 宜兰市| 奎屯市| 浪卡子县| 宝清县| 宁远县| 曲阜市| 灵山县| 凌云县| 九江县| 车致| 鄂尔多斯市| 无锡市| 北票市| 宕昌县| 湄潭县| 连州市| 莱阳市| 涡阳县| 吉首市| 长治县| 阿合奇县| 金沙县|