我正在创建一个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));
- '这个'这是DOM元素,正如我所料,但只要调试器进入控制器,值就是未定义的。
这是一种奇怪的范围内的痛苦我已经走进了吗?
答案 0 :(得分:2)
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));
});
}
另请参阅: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();
&#13;
答案 1 :(得分:0)
我现在通过放弃jQuery.each来解决这个问题(这似乎有严重的范围问题,将元素从数组传递到其他任何东西,因为它混淆了这个&#39;这个&#39;) 。我通过使用JS forEach调用解决了这个问题,如下所示。发现jQuery的makeArray方法是关键。这与我最初开始时的情况类似,但是我正在敲打forEach而不是在jQuery对象上工作......
renderDeleteButtons($elements) {
$.makeArray($elements).forEach((el) => {
document.DeleteButtons = document.DeleteButtons || [];
document.DeleteButtons.push(new DeleteButton(el));
});
}
通过使用&#39;这种奇怪的东西,它也不会伤害我的敏感度。 (对于费利克斯)
请参阅Felix关于词汇范围的额外信息&#39; this&#39;在Arrow function vs function declaration / expressions: Are they equivalent / exchangeable?