溫馨提示×

您好,登錄后才能下訂單哦!

密碼登錄×
登錄注冊(cè)×
其他方式登錄
點(diǎn)擊 登錄注冊(cè) 即表示同意《億速云用戶服務(wù)條款》

JavaScript中的求值策略有哪些

發(fā)布時(shí)間:2021-04-27 15:46:23 來源:億速云 閱讀:144 作者:Leah 欄目:開發(fā)技術(shù)

JavaScript中的求值策略有哪些?很多新手對(duì)此不是很清楚,為了幫助大家解決這個(gè)難題,下面小編將為大家詳細(xì)講解,有這方面需求的人可以來學(xué)習(xí)下,希望你能有所收獲。

JavaScript可以做什么

1.可以使網(wǎng)頁具有交互性,例如響應(yīng)用戶點(diǎn)擊,給用戶提供更好的體驗(yàn)。 2.可以處理表單,檢驗(yàn)用戶的輸入,并提供及時(shí)反饋節(jié)省用戶時(shí)間。 3.可以根據(jù)用戶的操作,動(dòng)態(tài)的創(chuàng)建頁面。 4使用JavaScript可以通過設(shè)置cookie存儲(chǔ)在瀏覽器上的一些臨時(shí)信息。

一栗以蔽之

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ì)》

按值傳遞

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

看完上述內(nèi)容是否對(duì)您有幫助呢?如果還想對(duì)相關(guān)知識(shí)有進(jìn)一步的了解或閱讀更多相關(guān)文章,請(qǐng)關(guān)注億速云行業(yè)資訊頻道,感謝您對(duì)億速云的支持。

向AI問一下細(xì)節(jié)

免責(zé)聲明:本站發(fā)布的內(nèi)容(圖片、視頻和文字)以原創(chuàng)、轉(zhuǎn)載和分享為主,文章觀點(diǎn)不代表本網(wǎng)站立場(chǎng),如果涉及侵權(quán)請(qǐng)聯(lián)系站長(zhǎng)郵箱:is@yisu.com進(jìn)行舉報(bào),并提供相關(guān)證據(jù),一經(jīng)查實(shí),將立刻刪除涉嫌侵權(quán)內(nèi)容。

AI