Javascript:重新创建 Array.from?

发布于 2025-01-11 09:01:27 字数 1405 浏览 0 评论 0原文

我遇到了这段代码,用于剥离 Marketo 表单中包含的样式表。我们假设代码作者是一位超级高级工程师。可以使用 Array.from() 来代替定义 arrayFrom(至少在功能上),那么为什么要使用后者呢?

就我而言,我试图理解 arrayFrom 定义(代码块的第一行):

  1. bind() 将 this 设置为提供的值,此处为 [] .slice(为什么?)
  2. call() 允许我们使用 bind 绑定的 this 值调用 getSelection
  3. getSelection() 返回所选文本的 Selection 对象(或 Firefox 中的字符串)。这个我不确定。 在其使用中,arrayFrom 获取样式表数组(或 NodeList)并返回相同样式表的数组(其浅表副本?),与 Array.from 没有什么不同> 被使用,因此 bindcall 的功能位必须是以所需的方式更改 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):

  1. bind() sets this to the provided value, here [].slice (why?)
  2. call() allows us to call getSelection with the this value bound by bind.
  3. 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 if Array.from were used, so the functional bit of bind and call must be to alter the this 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 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

败给现实 2025-01-18 09:01:27

现在我们只使用 Array.from 。但您的问题与所使用的构造有关:

const arrayFrom = getSelection.call.bind([].slice);

首先,这与 getSelection 无关,因为表达式不绑定 that,而是绑定 调用 函数。此 call 函数位于 Function 原型上,因此上面的结果与以下内容相同:

const arrayFrom = Function.prototype.call.bind(Array.prototype.slice);

call 是一个允许一个函数调用另一个函数的函数函数可以为其提供 this 参数。这里我们定义要调用的函数应该是slice。我们将提供给 arrayFrom 的第一个参数将类似于我们提供给 call 的第一个参数,即应调用 slice 的对象。这使其具有与 Array.from 类似的行为。

用这个执行类似操作的函数替换 bind 可能会有所帮助:

function arrayFrom(arrayLike)  {
    return Function.prototype.call.call(Array.prototype.slice, arrayLike);
}

这很令人困惑,但我们用 call 调用 call ,这样我们就可以为其提供一个 this 参数(定义我们要调用的函数),使第二个参数成为调用的 this 参数 (第一个)处理。

Nowadays we would just use Array.from. But your questions are about the construct that is used:

const arrayFrom = getSelection.call.bind([].slice);

First of all, this has nothing to do with getSelection, as the expression is not binding that, but the call function. This call function is on the Function prototype, so the above leads to the same result as:

const arrayFrom = Function.prototype.call.bind(Array.prototype.slice);

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 be slice. The first argument we will provide to arrayFrom will be like the first argument we would provide to call, i.e. the object on which slice should be called. This gives it a similar behaviour as Array.from.

It may help to replace bind by this function that does a similar thing:

function arrayFrom(arrayLike)  {
    return Function.prototype.call.call(Array.prototype.slice, arrayLike);
}

It is confusing, but we invoke call with call so that we can provide a this argument to it (defining the function we want to call), making the second argument the this-argument that call (the first one) deals with.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文