gpt4 book ai didi

JavaScript 参数值 'becomes' 传递给构造函数时未定义

转载 作者:行者123 更新时间:2023-12-01 03:58:43 27 4
gpt4 key购买 nike

我正在创建一个 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
};

onload 管理代码似乎运行良好,并且逐步执行,代码执行完全符合预期,直到 document.DeleteButtons.push(new DeleteButton(this)); - 这里的“this”是正如我所期望的,DOM 元素,但是一旦调试器进入 Controller ,该值就未定义。

这是我遇到的一些奇怪的范围界定痛苦吗?

最佳答案

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

并没有像你想象的那样做。 jQuery 依赖于能够设置回调函数的 this 值。但是箭头函数没有自己的this,因此jQuery无法设置this值。

在箭头函数内 this 将引用 thisrenderDeleteButtons 中引用的任何内容,它可能是 JsComponentManager.

如果将一个函数传递给另一个函数,并且该函数必须设置 this 值,则不能使用箭头函数。使用函数表达式代替:

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

另请参阅:Arrow function vs function declaration / expressions: Are they equivalent / exchangeable?

<小时/>

也许这有助于演示箭头函数和函数声明/表达式之间的区别:

// 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();

关于JavaScript 参数值 'becomes' 传递给构造函数时未定义,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/42397161/

27 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com