Javascript:重新创建 Array.from?
我遇到了这段代码,用于剥离 Marketo 表单中包含的样式表。我们假设代码作者是一位超级高级工程师。可以使用 Array.from() 来代替定义 arrayFrom(至少在功能上),那么为什么要使用后者呢?
就我而言,我试图理解 arrayFrom
定义(代码块的第一行):
- bind() 将
this
设置为提供的值,此处为[] .slice
(为什么?) - call() 允许我们使用
bind
绑定的this
值调用getSelection
。 - getSelection() 返回所选文本的 Selection 对象(或 Firefox 中的字符串)。这个我不确定。 在其使用中,
arrayFrom
获取样式表数组(或 NodeList)并返回相同样式表的数组(其浅表副本?),与Array.from
没有什么不同> 被使用,因此bind
和call
的功能位必须是以所需的方式更改this
值。但不确定它如何作用于[].slice
。
有人吗?我显然错过了一些东西。
const arrayFrom = getSelection.call.bind([].slice);
// remove element styles from <form> and children
const styledEls = arrayFrom(formEl.querySelectorAll("[style]")).concat(
formEl
);
styledEls.forEach(function (el) {
el.removeAttribute("style");
});
// create an array of all stylesheets in document
const styleSheets = arrayFrom(document.styleSheets);
// loop through stylesheets and check for ownerNode properties on each
styleSheets.forEach(function (ss) {
if (
//array of <link/> elements tied to stylesheets
[mktoForms2BaseStyle, mktoForms2ThemeStyle].indexOf(ss.ownerNode) !=
-1 ||
formEl.contains(ss.ownerNode)
) {
ss.disabled = true;
}
});
I came across this code for stripping Marketo forms of their included stylesheets. Let's assume that the code author is a super senior engineer. Array.from()
could have been used instead of defining arrayFrom
(functionally at any rate), so why use the latter?
For my part I'm trying to understand the arrayFrom
definition (first line of the codeblock):
- bind() sets
this
to the provided value, here[].slice
(why?) - call() allows us to call
getSelection
with thethis
value bound bybind
. - getSelection() returns a Selection object (or string in Firefox) of the selected text. This I'm unsure about.
In its use,arrayFrom
gets passed an array (or NodeList) of stylesheets and returns an array of the same stylesheets (a shallow copy thereof?) no differently than ifArray.from
were used, so the functional bit ofbind
andcall
must be to alter thethis
value in a desirable way. Not sure how that acts on[].slice
though.
Anyone? I'm clearly missing something.
const arrayFrom = getSelection.call.bind([].slice);
// remove element styles from <form> and children
const styledEls = arrayFrom(formEl.querySelectorAll("[style]")).concat(
formEl
);
styledEls.forEach(function (el) {
el.removeAttribute("style");
});
// create an array of all stylesheets in document
const styleSheets = arrayFrom(document.styleSheets);
// loop through stylesheets and check for ownerNode properties on each
styleSheets.forEach(function (ss) {
if (
//array of <link/> elements tied to stylesheets
[mktoForms2BaseStyle, mktoForms2ThemeStyle].indexOf(ss.ownerNode) !=
-1 ||
formEl.contains(ss.ownerNode)
) {
ss.disabled = true;
}
});
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(1)
现在我们只使用 Array.from 。但您的问题与所使用的构造有关:
首先,这与
getSelection
无关,因为表达式不绑定 that,而是绑定调用
函数。此call
函数位于Function
原型上,因此上面的结果与以下内容相同:call
是一个允许一个函数调用另一个函数的函数函数可以为其提供 this 参数。这里我们定义要调用的函数应该是slice
。我们将提供给arrayFrom
的第一个参数将类似于我们提供给call
的第一个参数,即应调用slice
的对象。这使其具有与 Array.from 类似的行为。用这个执行类似操作的函数替换
bind
可能会有所帮助:这很令人困惑,但我们用
call
调用call
,这样我们就可以为其提供一个this
参数(定义我们要调用的函数),使第二个参数成为调用的
(第一个)处理。this
参数Nowadays we would just use
Array.from
. But your questions are about the construct that is used:First of all, this has nothing to do with
getSelection
, as the expression is not binding that, but thecall
function. Thiscall
function is on theFunction
prototype, so the above leads to the same result as:call
is a function that allows one to call another function with the possibility to provide a this-argument to it. Here we define that the function to be called should beslice
. The first argument we will provide toarrayFrom
will be like the first argument we would provide tocall
, i.e. the object on whichslice
should be called. This gives it a similar behaviour asArray.from
.It may help to replace
bind
by this function that does a similar thing:It is confusing, but we invoke
call
withcall
so that we can provide athis
argument to it (defining the function we want to call), making the second argument thethis
-argument thatcall
(the first one) deals with.