如何将 jQuery 代码翻译成 Vanilla JS
How to Translate jQuery code into Vanilla JS
我通常使用 jQuery 作为完成任务的拐杖,然后继续下一个问题。然而,随着 Rails 6 引入 Stimulus,我想更好地编写 vanilla JS。我在重写下面的 $.map
和 $.each
行时遇到困难:
handleSuccess(data) {
const items = $.map(data, notification => { return notification.template })
let unreadCount = 0
$.each(data, (i, notification) => {
if (notification.unread) {
unreadCount += 1
}
});
this.unreadCountTarget.innerHTML = unreadCount
this.itemsTarget.innerHTML = items
}
我自己的尝试并没有真正奏效。
items.forEach(data, (i, notification) => {
if (notification.unread) {
unreadCount += 1
}
});
items.forEach(element, (i, notification) => {
if (notification.unread) {
unreadCount += 1
}
});
在您的情况下,您可以将 $.map()
转换为 Array.map()
, and convert the counter and the $.each()
to an Array.reduce()
调用。通常 $.each()
被转换为 Array.forEach()
,但在这种情况下,您想要获取一个数组,并将其转换为数字,而这种转换通常是通过归约来完成的。
注意:您自己的代码中的问题是由参数的顺序引起的 - $.each(index, item)
与 Array.forEach(item, index)
。
示例(未测试)- 评论不足 jQuery
handleSuccess(data) {
// const items = $.map(data, notification => { return notification.template })
const items = data.map(notification => notification.template)
// $.each(data, (i, notification) => { if (notification.unread) { unreadCount += 1 }});
const unreadCount = data.reduce((count, notification, i) => notification.unread ? count + 1 : count, 0)
this.unreadCountTarget.innerHTML = unreadCount
this.itemsTarget.innerHTML = items
}
JavaScript 有自己的本地地图功能(很久没有了,因此 jQuery 垫片),它与 jQuery 的非常相似。事实上,Array.prototype.map() 和 Array.prototype.forEach() 非常相似,具有相似的接口,只需以数组名称开始调用即可。所以不是 jQuery $.map(data, notification => { return notification.template })
,而是 data.map(notification => notification.template)
或类似的。原生 map() 和 forEach() 之间的唯一区别是 forEach() 将函数应用于数组中的每个项目,而 map() 更进一步,如果调用 returns 一个新的结果值数组正确。
https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/map
https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/forEach
试试这个:
handleSuccess(data){
const items = data.map(notification => notification.template)
let unreadCount = items.reduce(( total, curr) => curr.unread ? total +=1 : total)
this.unreadCountTarget.innerHTML = unreadCount
this.itemsTarget.innerHTML = items
}
您的代码的最后两行未更改。
我通常使用 jQuery 作为完成任务的拐杖,然后继续下一个问题。然而,随着 Rails 6 引入 Stimulus,我想更好地编写 vanilla JS。我在重写下面的 $.map
和 $.each
行时遇到困难:
handleSuccess(data) {
const items = $.map(data, notification => { return notification.template })
let unreadCount = 0
$.each(data, (i, notification) => {
if (notification.unread) {
unreadCount += 1
}
});
this.unreadCountTarget.innerHTML = unreadCount
this.itemsTarget.innerHTML = items
}
我自己的尝试并没有真正奏效。
items.forEach(data, (i, notification) => {
if (notification.unread) {
unreadCount += 1
}
});
items.forEach(element, (i, notification) => {
if (notification.unread) {
unreadCount += 1
}
});
在您的情况下,您可以将 $.map()
转换为 Array.map()
, and convert the counter and the $.each()
to an Array.reduce()
调用。通常 $.each()
被转换为 Array.forEach()
,但在这种情况下,您想要获取一个数组,并将其转换为数字,而这种转换通常是通过归约来完成的。
注意:您自己的代码中的问题是由参数的顺序引起的 - $.each(index, item)
与 Array.forEach(item, index)
。
示例(未测试)- 评论不足 jQuery
handleSuccess(data) {
// const items = $.map(data, notification => { return notification.template })
const items = data.map(notification => notification.template)
// $.each(data, (i, notification) => { if (notification.unread) { unreadCount += 1 }});
const unreadCount = data.reduce((count, notification, i) => notification.unread ? count + 1 : count, 0)
this.unreadCountTarget.innerHTML = unreadCount
this.itemsTarget.innerHTML = items
}
JavaScript 有自己的本地地图功能(很久没有了,因此 jQuery 垫片),它与 jQuery 的非常相似。事实上,Array.prototype.map() 和 Array.prototype.forEach() 非常相似,具有相似的接口,只需以数组名称开始调用即可。所以不是 jQuery $.map(data, notification => { return notification.template })
,而是 data.map(notification => notification.template)
或类似的。原生 map() 和 forEach() 之间的唯一区别是 forEach() 将函数应用于数组中的每个项目,而 map() 更进一步,如果调用 returns 一个新的结果值数组正确。
https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/map https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/forEach
试试这个:
handleSuccess(data){
const items = data.map(notification => notification.template)
let unreadCount = items.reduce(( total, curr) => curr.unread ? total +=1 : total)
this.unreadCountTarget.innerHTML = unreadCount
this.itemsTarget.innerHTML = items
}
您的代码的最后两行未更改。