随着ES6的采取,我渴望放弃jQuery并使用本机JS为我的网站构建保持快速和轻量级。也是为了提高我的JS技能,因为我是那些直接使用jQuery的人之一。
我正在构建一个小小的库,以便在函数中使用更常用的javascript来保持文件的小。
function $(elm) {
var elm = document.querySelectorAll(elm);
this.forEach = function(f) {
[].forEach.call(elm, f);
}
return elm;
}
function slider() {
$(".slider").forEach(function() {
alert("Hello");
});
}
slider();
这在Chrome等中效果很好..但在IE10 / 11中我收到了错误
Object不支持此属性或方法“forEach”
引用$(“。slider”)。forEach
有什么想法吗?
答案 0 :(得分:4)
您将forEach
添加到window
对象,而不是添加到您返回的对象;你将$
称为函数,而不是构造函数。由于您使用松散模式(显然),函数调用中的this
是对全局对象的引用(在浏览器上也可以作为window
访问)。您将querySelectorAll
的集合保持不变。
它在Chrome上运行的原因是querySelectorAll
返回的集合有自己的forEach
(这是一个相当新的补充)。
为此,有四个选项:
返回一个对象并向其添加forEach
,将元素从QSA集合复制到该对象。 E.g:
function $(selector) {
const result = Array.from(document.querySelectorAll(selector));
result.forEach = Array.prototype.forEach;
// Perhaps map, filter, etc.; add in a loop?
return result;
}
或者在ES5中:
var $ = (function() {
var methods = Array.prototype;
function $(selector) {
var result = methods.slice.call(document.querySelectorAll(selector));
result.forEach = methods.forEach;
// Perhaps map, filter, etc.; add in a loop?
return result;
}
return $;
})();
将forEach
添加到NodeList
原型(如果它尚未存在)并直接在forEach
的集合中使用querySelectorAll
。例如:
if (typeof NodeList !== "undefined" &&
NodeList.prototype &&
!NodeList.prototype.forEach) {
// Yes, direct assignment is fine here, no need for `Object.defineProperty`
NodeList.prototype.forEach = Array.prototype.forEach;
}
(上面不需要Object.defineProperty
,enumerable
[令人惊讶],configurable
和writable
在Chrome和Firefox上都是true
,所以我们可以像上面那样直接分配。)
...当然,你的$
只不过是
function $(selector) {
return document.querySelectorAll(selector);
}
(首先。如果你想添加更多功能,你可能想要采用#1的方式。)
返回一个数组:
function $(selector) {
return Array.from(document.querySelectorAll(selector));
}
或者在ES5中:
function $(selector) {
return Array.prototype.slice.call(document.querySelectorAll(selector));
}
子类Array
(无法在ES2015之前的JavaScript引擎上完全填充),因此您可以在Array
的功能之上添加自己的功能:
class MyThingy extends Array {
// Perhaps further methods here
}
function $(selector) {
return MyThingy.from(document.querySelectorAll(selector));
}
此处没有ES5选项,您至少需要进行转换和填充。
如果您要添加Array
提供的功能以外的其他功能,我非常喜欢#4,而不仅仅是填充#34;所以"好。它可能足以满足您的目的。