簡體   English   中英

傳遞給構造函數時,JavaScript參數值'becomes'未定義

[英]JavaScript parameter value 'becomes' undefined when passed to constructor

我正在創建一個JavaScript組件,該組件將基於jQuery結果創建實例,但是,盡管我在調用代碼中逐步執行循環時會填充到傳遞給構造函數的DOM元素,但該元素仍未定義。

這是我的類和構造函數...

export default class DeleteButton {

    /**
     * Creates an instance of DeleteButton.
     * 
     * @param {object} element The DOM element to make into a delete button.
     * 
     * @memberOf DeleteButton
     */
    constructor(element) {        
        this.id = element.getAttribute("data-id");
        if (!this.id) throw new Error("The 'data-id' attribute is required.");

        this.deleteUri = element.getAttribute("data-delete-uri");
        if (!this.deleteUri) throw new Error("The 'data-delete-uri' attribute is required.");

        $(element).click(this.confirmRemove);
    }

    confirmRemove() { // does something }
}

這是調用代碼(這是一個組件管理器,用於處理何時基於URL / DOM狀態等加載組件)...

export default class JsComponentManager {

    constructor(onLoader) {
        this._loader = onLoader;
        this.select = {
            deleteButtons: () => $(".js-delete-button")
        }
        this.result = 0;
    }

    bindComponents() {
        const paths = new PathManager();
        let $deleteButtons = this.select.deleteButtons()
        if ($deleteButtons.length > 0) {
            this._loader.add(this.renderDeleteButtons, $deleteButtons);
        }
    }

    renderDeleteButtons($elements) {
        $elements.each(() => {
            document.DeleteButtons = document.DeleteButtons || [];
            document.DeleteButtons.push(new DeleteButton(this));
        });
    }
}

這使用以下加載程序功能來確保已加載項目...

/**
 * Adds an event to the onload queue.
 * 
 * @param {function} func The function to add to the queue.
 * @param {any} param1 The first (optional) parameter to the function.
 * @param {any} param2 The second (optional) parameter to the function.
 */
var AddLoadEvent = function (func, param1, param2) {
    var oldonload = window.onload;
    if (typeof window.onload !== "function") {
        window.onload = () => { func(param1, param2); };
    } else {
        window.onload = () => {
            if (oldonload) { oldonload(); }
            func(param1, param2);
        };
    }
};

module.exports = {
    add: AddLoadEvent
};

加載管理代碼似乎運行良好,並且逐步完成代碼執行完全符合預期,直到document.DeleteButtons.push(new DeleteButton(this));為止document.DeleteButtons.push(new DeleteButton(this)); -“這”是DOM元素,正如我期望的那樣,但是一旦調試器進入控制器,該值就不會被定義。

這是我走進來的一些奇怪的范圍界定疼痛嗎?

renderDeleteButtons($elements) {
    $elements.each(() => {
        document.DeleteButtons = document.DeleteButtons || [];
        document.DeleteButtons.push(new DeleteButton(this));
    });
}

不按照您的想法去做。 jQuery依賴於能夠設置回調函數的this值。 但是箭頭函數沒有自己的this ,因此jQuery無法設置this值。

里面的箭頭功能this將涉及到任何this是指renderDeleteButtons ,這可能是一個實例JsComponentManager

如果將一個函數傳遞給另一個函數而該函數必須設置this值,則不能使用箭頭函數。 改用函數表達式:

renderDeleteButtons($elements) {
    $elements.each(function() {
        document.DeleteButtons = document.DeleteButtons || [];
        document.DeleteButtons.push(new DeleteButton(this));
    });
}

另請參見: 箭頭函數與函數聲明/表達式:它們是否等效/可互換?


也許這有助於說明箭頭函數與函數聲明/表達式之間的區別:

 // our library: function each(values, callback) { for (var i = 0; i < values.length; i++) { // we use `.call` to explicitly set the value of `this` inside `callback` callback.call(values[i]); } } // Function declaration/expression var obj = { someMethod() { "use strict"; each([1,2,3], function() { console.log('function declaration:', this); }); }, }; // Because we use a function expression, `each` is able to set the value of `this` // so this will log the values 1, 2, 3 obj.someMethod(); // Arrow function obj = { someMethod() { each([1,2,3], () => { "use strict"; console.log('arrow function:', this); }); }, }; // `this` is resolved lexically; whatever `each` sets is ignored // this will log the value of `obj` (the value of `this` inside `someMethod`) obj.someMethod(); 

現在,我通過放棄jQuery.each來完成此工作(由於將元素與“ this”弄混了,這似乎存在嚴重的范圍界定問題,將元素從數組傳遞到其他任何對象)。 我通過使用JS forEach調用來解決此問題,如下所示。 發現jQuery的makeArray方法是關鍵。 這類似於我最初開始的內容,但是我的頭撞到forEach不能在jQuery對象上工作...

renderDeleteButtons($elements) {
    $.makeArray($elements).forEach((el) => {
        document.DeleteButtons = document.DeleteButtons || [];
        document.DeleteButtons.push(new DeleteButton(el));
    });
}

用“ this”做怪異的事情也不會傷害我的感覺(對費利克斯來說)

Arrow函數與函數聲明/表達式中查看Felix關於用'this'進行詞法作用域的額外信息:它們是否等效/可交換?

暫無
暫無

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

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