前一段时间,我写了一篇标题为“ 7个讨人喜欢的Web开发技巧”的文章。在那里,我描述了一些有趣的技巧,你可以使用3种主要的Web技术之一来实现这些技巧-HTML,CSS和JavaScript。而且,我必须承认-你们似乎很喜欢它!所以,续集来了!

这一次,为了更加一致,我决定只专注于JavaScript。它可能是三者中最有趣最通用的,因此有很多需要讨论的内容。我们将介绍5个在上一篇文章中没有提到的JavaScript技巧。希望你会对它们感兴趣!

在我们进入正文之前有个快速的说明。在上一篇文章中我看到一些回复并想澄清一下。我知道不是所有在这里或之前的内容都是真正有用或值得推荐的做法,但这不是我的目标。我所说的“技巧”这个词的意思是-一个有趣或值得了解的“技巧”。有用只是一个加分项。如果它是100%的有用,我称之为“提示”。希望你能理解。现在,让我们进入正文。

5. switch与范围

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

  1. const useSwitch = value => {
  2. let message = "";
  3. switch (true) {
  4. case value < 0:
  5. message = "lesser than 0";
  6. break;
  7. case value === 0:
  8. message = "0";
  9. break;
  10. case value % 1 !== 0:
  11. message = "a float";
  12. break;
  13. case value > 0 && value <= 9:
  14. message = "higher than 0 and is 1 digit long";
  15. break;
  16. case value >= 10 && value <= 99:
  17. message = "2 digits long";
  18. break;
  19. case value >= 100:
  20. message = "big";
  21. break;
  22. }
  23. console.log(`The value is ${message}`);
  24. };
  25. useSwitch(24); // The value is 2 digits long.

我们简单地用一个的true代替一个实际的值传递给switch语句。这样,我们实质上让它变成了一个大的if-else替代方案。是否使用它完全取决于你的个人喜好或者你遵循的代码规范。如果你觉得这个比if-else链更具有可读性,可以使用它。两种解决方案的性能大致相同。

4. 将函数转成字符串

接下来我们要说的本身不是真正的技巧的东西。将函数字符串化是一个你很可能早就知道的特性。相反,我想让你知道这种功能的一些有趣的用例。

  1. const func = () => {
  2. console.log("This is a function");
  3. }
  4. const stringifiedFunc = `${func}`; /* `() => {
  5. console.log("This is a function");
  6. }` */

首先快速看一下语法方面。你应该知道,将任何JS类型的值转换为字符串时,都会调用特殊的.toString()方法。你可以利用这个事实来实现一个自己的版本的toString方法,并以不同的方式处理将JS值转换为字符串的情况。这个本身可以被认为是一个技巧。;)然而,我想说的是,你可以将值(包括函数)转换为带有ES6模板文字的字符串(如示例中所示),方法是将它们与空字符串文字(””)连接起来,或者通过直接调用.toString()方法。

现在,让我们回到函数。我想指出的是,不能依赖结果字符串来包含函数编写时的所有代码。例如,从ES2019(目前ECMAScript标准的最新修订)开始,. tostring()就意味着要在结果字符串中包含函数体内的所有注释和空白。你可以在我之前的一篇文章中了解更多关于ES2019的新特性。总之,考虑到所有这些,字符串化函数怎样才可以更有用。

不用查看太多,我想引用一个在我最近的项目中使用的巧妙技巧。想象一下,可以通过调用一个函数来创建一种节点。这个函数将另一个函数作为参数,通过运行参数可以配置新的节点。对于包含相同语句的函数,结果节点相同。

遗憾的是,创建新节点是一个缓慢的过程(特别是在考虑大量节点时),你希望至少最小化正在创建的节点的数量。为此,你可以创建一个“缓存”对象,在这个对象中,你可以通过它们的字符串化的配置函数来存储所有已经创建的节点,以防止任何重复的调用——很有趣吧?

当然,即使是很小的空白或注释,基于字符串的函数id也会被认为是不同的,你可以使用一些额外的字符串处理来修复它,但这样会忽略所有我们试图实现的性能提升。

但是,你不应该容忍对象的键与配置函数一样长。你可以通过简单地对这个字符串化函数进行哈希处理来解决这个问题-它不会在性能上花费很多。

  1. // ...
  2. const hash = value => {
  3. let hashed = 0;
  4. for (let i = 0; i < value.length; i += 1) {
  5. hashed = (hashed << 5) - hashed + value.charCodeAt(i);
  6. hashed |= 0;
  7. }
  8. return `${hashed}`;
  9. };
  10. const hashedFunc = hash(stringifiedFunc); // "-1627423388"

我知道我刚刚描述的内容看起来过于具体,无法应用于更一般的用例。当然,这点没错,但是我只是想给你一个可能在现实中用到的像这种技巧的例子。

3.可调用的对象

一个可以调用的对象,一个具有属性的函数,或者任何对象你想调用都不是一件困难的事,这很好地展示了JavaScript的多功能性。

  1. const func = () => {
  2. // ...
  3. };
  4. func.prop = "value";
  5. console.log(func.prop); // "value"

上面的代码段对你来说似乎没有什么特别。你可以在几乎所有JS对象上保存自己的属性,除非使用.freeze().seal().preventExtensions()方法指定的。上面的函数既可以作为普通函数使用,也可以作为包含某种数据的对象使用。

上面的代码片段看起来并不完美。随着时间的推移,为给定的函数分配属性会让人感到重复和混乱。让我们去改变它!

  1. const func = Object.assign(() => {
  2. // ...
  3. }, {
  4. prop: "value"
  5. });
  6. console.log(func.prop); // "value"

现在,我们用Object.assign()方法使代码看起来更优雅。当然,此方法仅在与ES6兼容的环境中(或与转换器一起使用)可用,但是,由于我们还在此处使用箭头功能,因此我认为这是理所当然的。

2.词汇绑定类方法

假如我们有一个类,它有很多字段和方法。你可以想象自己在这种情况下,不是吗?如果在某个时刻,你只需要所有类属性和方法中的一个小子集呢?也许你可以使用ES6的解构赋值使你的代码看起来更好?遗憾的是,这并不容易——看看。

  1. class Example {
  2. method() {
  3. console.log(this);
  4. }
  5. }
  6. const instance = new Example();
  7. const { method } = instance;
  8. method(); // undefined

你可以看到,当我们提取了这个方法,这个值变成了undefined。这是可以预想到的行为,它的值受运行时限制,由调用函数的方式和位置决定。我在之前的文章中讨论过这个问题。

不过,有个解决方案-.bind()

  1. class Example {
  2. constructor() {
  3. this.method = this.method.bind(this);
  4. }
  5. method() {
  6. console.log(this);
  7. }
  8. }
  9. const instance = new Example();
  10. const { method } = instance;
  11. method(); // Example {}

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

  1. class Example {
  2. method = () => {
  3. console.log(this);
  4. }
  5. }
  6. // ...

看起来我们办到了!一个更加简短和简单的方式在类中使用词汇绑定。上面的语法也可以在最新的绿色浏览器里工作,如果有必要还可以进行转换,所以请尽情使用!

1.constructor返回值

列表里的最后一条也和类有关。你可能听过从构造函数返回自定义值得可能性。这不是一个非常流行或推荐的做法,但是它可以使你获得一些有趣的结果。还记得前面我提出的缓存节点的例子吗?让我们以此为基础!

  1. // ...
  2. const cache = {};
  3. class Node {
  4. constructor(config) {
  5. const id = hash(`${config}`);
  6. if (cache[id]) {
  7. return cache[id];
  8. } else {
  9. cache[id] = this;
  10. config();
  11. }
  12. }
  13. }
  14. const node = new Node(() => {});
  15. const nodeReference = new Node(() => {});
  16. const secondNode = new Node(() => {
  17. console.log("Hello");
  18. });
  19. console.log(node === nodeReference, node === secondNode); // true, false

我们的节点现在具有类的形式,并且和以前一样,可以使用字符串化和哈希配置函数进行缓存。看到所有片段在一起真是太好了!

新的东西?

所以,就是列表这些。我知道这不是你看过最长的一个,但是,至少我让你感兴趣了,对吧?无论如何,请在评论区告诉上面哪些技巧是你所不知道的。如果你想看到更多关于这种类型的文章,你还可以分享对于他们的看法。

公告

最后,我有一个简短的通知——我要开始我自己的Reddit社区了!它叫做r/Areknawo,我希望它成为这个博客的读者(像你一样的人)讨论各种帖子、博客相关的东西,以及其他网络开发、设计或技术相关的东西的地方。如果你想表达你的支持,只要去那里,成为一个成员,然后找个时间过来。,)

所以,如果你喜欢这个博客,可以考虑在TwitterFacebookReddit上关注我以了解最新的内容。如果你喜欢时事通讯,在文章下面有一个表格,你可以用它来注册。和往常一样,感谢你阅读这篇文章,祝你有一个快乐的一天!

原文地址:https://areknawo.com/5-interesting-and-not-necessarily-useful-javascript-tricks/