![](/img/trans.png)
[英]JavaScript parameter value becomes undefined when passed through prototype chain
[英]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.