簡體   English   中英

我的函數以某種方式無法訪問其父閉包並且缺少變量。怎么樣?

[英]My function somehow doesn’t have access to its parent closure & is missing variables. How?

在我的頂級函數中,我使用require.js導入一些依賴項。 他們在那里,沒問題。 在這個函數中,我定義了一個回調函數,並嘗試使用通過require.js導入的一些變量,即父閉包中的變量。

他們只是不在那里,正如一個斷點和偷看Chrome檢查員的Scope Variables面板所證實的那樣。

據我所知, fn.apply和朋友只設置上下文至於this去,不是他們可以摧毀一個封閉的引用或改變作用域鏈。

define([
    'backbone',
    'backbone.vent',
    'app/utils/foo',
    'app/services/intent'
], function(Backbone, Vent, Foo) {
    'use strict';

    // Backbone, Vent, and Foo are defined here

    Vent.on('myevent', function(options) {
        // Backbone is defined here, but not Vent or Foo.
    });
});

這怎么可能呢?

我該如何解決?

我懷疑你設置斷點的函數包含對Backbone的引用,但不包含VentFoo

在JS運行時,閉包有些昂貴。 它要求引擎以這樣一種方式包裝對象:它保留對這些變量的內部引用,以便在執行函數時正確解析它們。 因此,出於性能原因,Chrome(以及我懷疑大多數其他引擎)都傾向於優化編譯腳本時未實際使用的任何閉包變量。 這可能會在調試時導致一些令人困惑的事情,但這是可以預料的。

請考慮以下示例(注意xyz在外部函數的范圍內定義,而不是在全局范圍內):

 window.onload = function() { var x = 1, y = 2, z = 3; (function() { debugger; x++; })(); } 

替代JSFiddle演示

如果您嘗試在此腳本命中debugger指令時在控制台上輸出xy ,那么您將看到:

控制台輸出

如果你看一下Scope Variable面板,你會看到:

范圍變量

為什么? 因為Chrome已確定yz未在函數中使用,因此編譯代碼不需要保留對變量的引用。 如果在腳本中添加對y的引用,則編譯器將保留對它的引用,並且在調試器中將不再undefined該名稱。

如果你在你的閉包中使用eval(),Chrome將不會使用任何性能優化,這意味着你可以看到y的值

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM