5 个有趣但不一定有用的 Javascript 技巧 5. 使用范围切换 4. 字符串化函数 3. 可调用对象 2. 词汇绑定的类方法 1. 从构造函数返回 有什么新东西吗?

2025-06-08

5 个有趣但不一定有用的 JavaScript 技巧

5. 使用范围切换

4. 字符串化函数

3.可调用对象

2. 词汇绑定的类方法

1. 从构造函数返回

有新东西吗?

这篇文章取自我的博客,因此请务必查看以获取更多最新内容。

不久前,我写了一篇题为“7 个超棒的 Web 开发技巧”的文章。文中我介绍了一些有趣的技巧,你可以使用三大主流 Web 技术——HTML、CSS 和 JavaScript——来实现。而且,我必须承认,你们似乎很喜欢!所以,续篇来了!

这次,为了保持风格一致,我决定只专注于 JavaScript。它可能是这三种语言中最有趣、用途最广的,所以有很多内容可以讲。我们将讲解上一篇文章中没有提到的 5 个 JavaScript 技巧。希望你会觉得它们很有趣!

在开始讲解之前,我想简单说一下。我看到了一些之前帖子的回复,想澄清一下。我知道,这份清单或之前清单上的内容并非都真正有用或值得推荐,但这不是我的目标。我所说的“技巧”就是指那些有趣或值得了解的技巧。“实用性”只是锦上添花。如果它意味着100%有用,那么我会称之为“小贴士”。希望你能理解。现在,我们开始讲解吧!

5. 使用范围切换

从不那么“极端”的技巧开始,我们得到了switch语句。它的大部分用例都归结为字符串或数值匹配。但是,你知道它也可以用于一些更复杂的布尔值吗?来看看吧。

const useSwitch = value => {
  let message = "";

  switch (true) {
    case value < 0:
      message = "lesser than 0";
      break;

    case value === 0:
      message = "0";
      break;

    case value % 1 !== 0:
      message = "a float";
      break;

    case value > 0 && value <= 9:
      message = "higher than 0 and is 1 digit long";
      break;

    case value >= 10 && value <= 99:
      message = "2 digits long";
      break;

    case value >= 100:
      message = "big";
      break;
  }

  console.log(`The value is ${message}`);
};

useSwitch(24); // The value is 2 digits long.
Enter fullscreen mode Exit fullscreen mode

我们不是在语句中传递switch实际变量,而是直接传递true。这样,我们实际上就把它变成了一个if-else替代方案。是否应该使用它完全取决于您的个人偏好或您遵循的代码指南。如果您觉得它比链式语句更易读if-else,那就使用它吧。这两种解决方案的性能大致相同。

4. 字符串化函数

接下来我们要讲的东西本身其实不算什么技巧。将函数字符串化是一个你很可能早就知道的功能。不过,我想让你了解一下这类功能的一些有趣用例。

const func = () => {
  console.log("This is a function");
}
const stringifiedFunc = `${func}`; /* `() => {
  console.log("This is a function");
}` */
Enter fullscreen mode Exit fullscreen mode

首先快速浏览一下语法。你应该知道,当你将任何 JS 类型的值转换为字符串时,.toString()都会调用一个特殊的方法。你可以利用这一点来实现你自己版本的这个方法,并以不同的方式处理将 JS 值转换为字符串。这本身也可以算作一个技巧。;) 无论如何,我想强调的是,你可以使用 ES6 模板字面量(如示例中所示)将值(包括函数)转换为字符串,方法是将它们与空字符串字面量 ( "") 连接起来,或者直接调用该.toString()方法。

现在,让我们回到函数。我想指出的是,你不能依赖结果字符串来包含函数编写时的所有代码。例如,只有 ES2019(目前是 ECMAScript 标准的最新版本)才.toString()要求将函数主体内的所有注释和空格都包含在结果字符串中。你可以在我之前的一篇文章中阅读更多关于 ES2019 特性的内容。总之,考虑到所有这些,将函数字符串化到底有多有用呢?

不想找太远,我想引用一下我在最近的一个业余项目中用过的一个巧妙技巧。想象一下,有一种节点可以通过调用一个函数来创建。这个函数接受另一个函数作为参数,然后运行该函数来配置新节点。对于由相同语句组成的函数,生成的节点是相同的。

遗憾的是,创建新节点的过程非常缓慢(尤其是在数量众多的情况下),您至少希望尽量减少创建的节点数量。为此,您可以创建一个“缓存”对象,将所有已创建的节点通过其字符串化的配置函数存储到其中,以避免任何重复调用——很有意思,不是吗?

当然,即使包含一个很小的空格或注释,字符串化的基于函数的 ID 也会被视为不同。您可以通过一些额外的字符串处理来解决这个问题,但这会忽略我们想要实现的所有性能提升。

但是,您不应该容忍对象键和配置函数一样长。您可以通过简单地字符串化的函数进行哈希处理来轻松解决这个问题——这不会对性能造成太大的影响。

// ...
const hash = value => {
  let hashed = 0;

  for (let i = 0; i < value.length; i += 1) {
    hashed = (hashed << 5) - hashed + value.charCodeAt(i);
    hashed |= 0;
  }

  return `${hashed}`;
};
const hashedFunc = hash(stringifiedFunc); // "-1627423388"
Enter fullscreen mode Exit fullscreen mode

我知道我刚才描述的内容可能看起来有点过于具体,不适合应用于更普遍的用例。当然,这在某种程度上是事实,但我只是想给你一个真实的例子,来说明像这样的技巧能给你带来哪些可能性。

3.可调用对象

可调用对象、具有属性的函数或任何您想要调用的名称都是一个相当简单的想法,它很好地展示了 JavaScript 的多功能性。

const func = () => {
  // ...
};
func.prop = "value";
console.log(func.prop); // "value"
Enter fullscreen mode Exit fullscreen mode

上面的代码片段对你来说应该没什么特别的。你几乎可以在任何 JS 对象上保存自己的属性,除非使用 、 或 方法另有说明.freeze().seal()上面.preventExtensions()的函数现在既可以用作普通函数,也可以用作包含某种数据的对象。

不过,上面的代码片段看起来不太精致。随着时间的推移,为给定函数赋值属性会变得重复且混乱。让我们尝试改变这种情况!

const func = Object.assign(() => {
    // ...
}, {
  prop: "value"
});
console.log(func.prop); // "value"
Enter fullscreen mode Exit fullscreen mode

现在我们使用该Object.assign()方法来让代码看起来更好。当然,这种方法仅在兼容 ES6 的环境中(或使用转译器)可用,但由于我们在这里也使用了箭头函数,所以我就顺理成章地使用了。

2. 词汇绑定的类方法

假设我们有一个包含大量字段和方法的类。你可以想象一下这种情况,不是吗?如果在特定时刻,你只需要所有类属性和方法的一小部分,该怎么办?也许你可以使用 ES6 的解构赋值来让你的代码看起来更好?可惜的是,这并不容易——我们来看一下。

class Example {
  method() {
    console.log(this);
  }
}

const instance = new Example();
const { method } = instance;

method(); // undefined
Enter fullscreen mode Exit fullscreen mode

如你所见,在我们提取方法之后, 的值this变为undefined。这是预期的行为—— 的值this运行时绑定的,由函数调用的方式和位置决定。我在上一篇文章中讨论过这个问题。

不过,还有一种方法可以解决 - .bind()

class Example {
    constructor() {
        this.method = this.method.bind(this);
    }
  method() {
    console.log(this);
  }
}

const instance = new Example();
const { method } = instance;

method(); // Example {}
Enter fullscreen mode Exit fullscreen mode

现在我们的代码已经按预期工作了,尽管它需要添加类构造函数,因此多了几行代码。我们可以让它更短一些吗?

class Example {
  method = () => {
    console.log(this);
  }
}
// ...
Enter fullscreen mode Exit fullscreen mode

看来我们成功了!一个在类中实现词法绑定方法的简洁方法。上面的语法可以在最新的主流浏览器中运行,并且可以根据需要进行转译,尽情享受吧!

1. 从构造函数返回

此列表中的最后一项也与类相关。您可能听说过从构造函数返回自定义值的可能性。这并非一种非常流行或推荐的做法,但它可以实现一些有趣的结果。还记得我之前提到的缓存节点示例吗?让我们以此为基础!

// ...
const cache = {};

class Node {
  constructor(config) {
    const id = hash(`${config}`);

    if (cache[id]) {
      return cache[id];
    } else {
      cache[id] = this;
      config();
    }
  }
}

const node = new Node(() => {});
const nodeReference = new Node(() => {});
const secondNode = new Node(() => {
  console.log("Hello");
});

console.log(node === nodeReference, node === secondNode); // true, false
Enter fullscreen mode Exit fullscreen mode

我们的节点现在有了类的形式,并且像以前一样,可以使用字符串化和散列化的配置函数进行缓存。看到所有部分组合在一起真是太好了!

有新东西吗?

好了,这篇清单就到这里。我知道这不是你见过的最长的,但嘿,至少我成功引起你的兴趣了,对吧?总之,请在评论区告诉我,上面哪些技巧你不知道?你也可以在下面分享你对这类文章的看法,以及你是否想看到更多类似的技巧。;)

所以,如果你喜欢这篇文章,不妨分享它,并在TwitterFacebookReddit上关注我,以便及时了解最新内容。一如既往,感谢你的阅读,祝你拥有美好的一天!

鏂囩珷鏉ユ簮锛�https://dev.to/areknawo/5-interesting-and-not-necessarily-useful-javascript-tricks-47k3
PREV
5 of the best VS Code themes compared - an opinionated review One Dark Pro Material Dracula Official Nord Horizon Is there something missing?
NEXT
小型团队的数据库安全检查表