欧美bbbwbbbw肥妇,免费乱码人妻系列日韩,一级黄片

詳細(xì)討論JavaScript中的求值策略

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

最近在研究 lambda演算 中的 η-變換 在JavaScript中的應(yīng)用,偶然在 stackoverflow 上看到一個(gè)比較有意思的問(wèn)題。關(guān)于JavaScript的求值策略,問(wèn)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

如果說(shuō)js中函數(shù)的參數(shù)傳遞是按值傳遞,那么在函數(shù)changeStuff內(nèi)部改變b.item的值將不會(huì)影響外部的obj1對(duì)象的值。

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

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

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

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

參數(shù)傳遞

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

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

按值傳遞

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

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

var num = 10;

foo(num);

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

這里看到函數(shù)內(nèi)部參數(shù)的改變并沒(méi)有影響到外部變量。按值傳遞沒(méi)錯(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ù)的屬性并沒(méi)有影響到參數(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é)

可以說(shuō)按共享傳遞是按值傳遞的特例,傳遞的是引用地址的拷貝。所以紅寶書(shū)上說(shuō)的也沒(méi)錯(cuò)。

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

延伸 - 惰性求值

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

參數(shù)默認(rèn)值不是傳值的,而是每次都重新計(jì)算默認(rèn)值表達(dá)式的值。也就是說(shuō),參數(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

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

相關(guān)文章

  • 原生JS實(shí)現(xiàn)拖拽位置預(yù)覽

    原生JS實(shí)現(xiàn)拖拽位置預(yù)覽

    這篇文章主要為大家詳細(xì)介紹了原生JS實(shí)現(xiàn)拖拽位置預(yù)覽,文中示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下
    2021-10-10
  • Javascript之JSBridge初探

    Javascript之JSBridge初探

    這篇文章主要介紹了Javascript的JSBridge,對(duì)JSBridge感興趣的同學(xué),可以參考下
    2021-04-04
  • JavaScript中的聲明提升實(shí)例詳解

    JavaScript中的聲明提升實(shí)例詳解

    這篇文章主要為大家介紹了JavaScript中的聲明提升實(shí)例詳解,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪
    2022-11-11
  • js + css實(shí)現(xiàn)標(biāo)簽內(nèi)容切換功能(實(shí)例講解)

    js + css實(shí)現(xiàn)標(biāo)簽內(nèi)容切換功能(實(shí)例講解)

    下面小編就為大家?guī)?lái)一篇js + css實(shí)現(xiàn)標(biāo)簽內(nèi)容切換功能(實(shí)例講解)。小編覺(jué)得挺不錯(cuò)的,現(xiàn)在就分享給大家,也給大家做個(gè)參考。一起跟隨小編過(guò)來(lái)看看吧
    2017-10-10
  • 淺談js promise看這篇足夠了

    淺談js promise看這篇足夠了

    下面小編就為大家分享一篇淺談js promise的使用。具有很好的參考價(jià)值,看完這篇都懂了。希望對(duì)大家有所幫助。一起跟隨小編過(guò)來(lái)看看吧
    2018-02-02
  • 點(diǎn)擊標(biāo)簽切換和自動(dòng)切換DIV選項(xiàng)卡

    點(diǎn)擊標(biāo)簽切換和自動(dòng)切換DIV選項(xiàng)卡

    點(diǎn)擊標(biāo)簽切換DIV的效果,在很多地方都有見(jiàn)到過(guò),而且實(shí)現(xiàn)的方法有很多,本例介紹的這個(gè)可以切換和自動(dòng)切換DIV選項(xiàng)卡
    2014-08-08
  • javascript生成大小寫(xiě)字母

    javascript生成大小寫(xiě)字母

    本文給大家分享的是javascript生成大寫(xiě)小寫(xiě)字母的代碼,十分的簡(jiǎn)單實(shí)用,主要用到了str.charCodeAt()和 String.fromCharCode()方法,有需要的小伙伴可以參考下。
    2015-07-07
  • getElementByIdx_x js自定義getElementById函數(shù)

    getElementByIdx_x js自定義getElementById函數(shù)

    最近看JS代碼,發(fā)現(xiàn)不少人問(wèn)getElementByIdx_x是什么函數(shù),其實(shí)就是個(gè)getElementById自定義函數(shù)
    2012-01-01
  • JavaScript 錯(cuò)誤捕獲與處理的完整指南

    JavaScript 錯(cuò)誤捕獲與處理的完整指南

    在JavaScript中捕獲錯(cuò)誤通常有四種方式,try-catch 語(yǔ)句塊,Promise 的 catch 方法,throw 語(yǔ)句以及window.onerror事件處理程序,并通過(guò)代碼示例給大家講解的非常詳細(xì),需要的朋友可以參考下
    2024-02-02
  • JS操作json對(duì)象key、value的常用方法分析

    JS操作json對(duì)象key、value的常用方法分析

    這篇文章主要介紹了JS操作json對(duì)象key、value的常用方法,結(jié)合實(shí)例形式分析了js操作json對(duì)象鍵值對(duì)遍歷及增刪的相關(guān)操作技巧,需要的朋友可以參考下
    2019-10-10

最新評(píng)論