第七色在线视频,2021少妇久久久久久久久久,亚洲欧洲精品成人久久av18,亚洲国产精品特色大片观看完整版,孙宇晨将参加特朗普的晚宴

為了賬號安全,請及時綁定郵箱和手機立即綁定
已解決430363個問題,去搜搜看,總會有你想問的

當引用在 Javascript 中脫離上下文時,按引用捕獲是否會變成按值捕獲?

當引用在 Javascript 中脫離上下文時,按引用捕獲是否會變成按值捕獲?

瀟瀟雨雨 2022-12-29 15:22:33
以下 Javascript 程序:function f() {  function g() { console.log(x); }  let x = 0;  g();  // prints 0  x = 1;  g();  // prints 1  return g;}let g = f();g();  // prints 1輸出:011因此,似乎首先通過引用g捕獲(因為在內部,然后在反彈時打?。?,這意味著閉包環(huán)境看起來像,然后通過值(因為在外部,在主體末尾脫離上下文時打?。?,這意味著閉包環(huán)境看起來像.x fg()01xg{'x': x}fg()1xfg{'x': 1}我試圖將此行為與 C++ lambda 相關聯(lián),后者提供按引用和按值捕獲,但與 Javascript 相反,不允許按引用捕獲通過轉換為按值捕獲(相反,調用lambda 變成未定義的行為)。這是對 Javascript 捕獲的正確解釋嗎?如果這個解釋是正確的,那將清楚地解釋塊作用域變量 ( let) 的捕獲是如何在for循環(huán)中工作的:let l = [];for (let x = 0; x < 3; ++x) {  l.push(function () { console.log(x); });}l[0]();  // prints 0l[1]();  // prints 1l[2]();  // prints 2
查看完整描述

2 回答

?
UYOU

TA貢獻1878條經驗 獲得超4個贊

在 JavaScript 中,無論 g() 是否從 f() 內部調用,當 g() 引用表達式中的變量 x 時發(fā)生的事情實際上沒有區(qū)別。只有一個變量x,無論何時運行代碼,獲取它都是相同的內部操作g()。


JavaScript 與 C++ 有很大的不同;表面上的相似性可能具有欺騙性。此外,在討論JavaScript 語義時很少使用術語“捕獲”(根據我的經驗,例如在 Stack Overflow 上),盡管規(guī)范在其詳盡的描述中使用了它來描述進入范圍時發(fā)生的情況。這里的相關詞是閉包,如“x 在 g() 的閉包中。(我對術語很草率,所以有人可能會改進我的措辭。)


更多:注意,我們可以修改g()來演示,x仍然不僅可以訪問獲取其值,還可以修改:


    function f() {

      function g() { console.log(x = x + 1); }

      let x = 0;

      g();  // prints 1

      x = 1;

      g();  // prints 2

      return g;

    }

    

    g = f();

    g();

    g();

    g();

變量x繼續(xù)表現得像普通變量一樣。



查看完整回答
反對 回復 2022-12-29
?
慕沐林林

TA貢獻2016條經驗 獲得超9個贊

簡而言之

你幾乎是正確的,除了它超出范圍時它是如何工作的。

更多細節(jié)

如何在 JavaScript 中“捕獲”變量?

JavaScript 使用詞法環(huán)境來確定哪個函數使用哪個變量。詞法環(huán)境由環(huán)境記錄表示。在你的情況下:

  • 有一個全球環(huán)境;

  • 該函數f()定義了它的詞法環(huán)境,在其中x被定義,即使它在 之后g();

  • 內部函數g()定義了它的詞法環(huán)境,它是空的。

所以g()使用x. 由于那里沒有綁定x,JavaScriptx在封閉環(huán)境中查找。由于它在其中找到,因此xing()將使用 in 的x綁定f()。這看起來像詞法范圍綁定。

如果稍后您在調用x的環(huán)境中定義一個,仍然會綁定到in :g()g()xf()

function f() {

  function g() { console.log(x); }

  let x = 0;

  g();  // prints 0

  x = 1;

  g();  // prints 1

  return g;

}


let x = 4;

let g = f();

g();  // prints 1 (the last known value in f before returning)

在線演示

這表明綁定是靜態(tài)的,并且將始終在定義x的詞法范圍內引用已知的g()

這篇優(yōu)秀的文章用非常漂亮的圖形詳細解釋了它是如何工作的。它適用于閉包(即具有執(zhí)行上下文的匿名函數),但也適用于普通函數。

為什么超出范圍的變量的值會被保留?

如何解釋這種非常特殊的行為,即x只要x仍在范圍內,JavaScript 將始終采用當前值(如 C++ 中的引用),而在超出范圍時它將采用最后一個已知值x(當超出范圍的引用時) C++ 將是 UB)?當變量消失時,JavaScript 是否將值復制到閉包中?不,比這更簡單!

這與垃圾收集有關:g()返回到外部上下文。由于g()使用了xin f(),垃圾收集器將意識到這個x對象f()仍在使用中。因此,只要g()可訪問,xinf()就會保持活動狀態(tài),并保持其仍處于活動狀態(tài)的綁定可訪問。所以不需要復制值:x對象將保持不變(未修改)。

作為不是拷貝的證明,你可以研究下面的代碼。f()它在能夠更改(相同)的上下文中定義了第二個函數x

let h;


function f() {

  function g() { console.log(x); }

  h = function () { x = 27; }

  let x = 0;

  g();  // prints 0

  x = 1;

  g();  // prints 1

  x = 3;

  return g;

}


let x = 4;

let g = f();

g();  // prints 3

h();

g();  // prints 27

在線演示

編輯:在稍微復雜的上下文中解釋這種現象的附加獎勵文章。有趣的是,它解釋說如果不采取預防措施,這種情況會導致內存泄漏。


查看完整回答
反對 回復 2022-12-29
  • 2 回答
  • 0 關注
  • 81 瀏覽
慕課專欄
更多

添加回答

舉報

0/150
提交
取消
微信客服

購課補貼
聯(lián)系客服咨詢優(yōu)惠詳情

幫助反饋 APP下載

慕課網APP
您的移動學習伙伴

公眾號

掃描二維碼
關注慕課網微信公眾號