读书笔记--记忆函数、数组映射、修改页面标题、数组填充、纯函数、flex:1、字符串方法

126 阅读9分钟

记录平时看逛掘金和阅读微信公众号积累和总结的一些知识点,方便以后温习、学习。

1. js 记忆函数

这个开发中目前还没使用过,但其思想值得借鉴。

  1. 前置知识点说明,如下代码
let obj={ DutyDay: 19, HolidayPersonName: "陈丹丹" };
let key='DutyDay'
if(key in obj){
console.log('key',key);
}
  • 代码使用 if 语句和 in 操作符来检查 key 变量所表示的属性名是否存在于 obj 对象中。
  • in 操作符用于判断一个属性是否存在于某个对象中,如果属性存在,则返回 true;如果不存在,则返回 false
  1. 什么是 Memoization?

Memoization(记忆化)是一种优化技术,主要用于加速计算机程序。它通过存储耗时函数的计算结果,在相同输入再次传递时,直接返回缓存的结果,从而避免重复计算。

  1. 相关代码实现如下:
 function memoize (callback) {
      //用于存储计算结果。
      let cache = {};
      return function (...args) {
        console.log('args', args);
        const key = args.toString();
        if (key in cache) {
          console.log('从缓存中返回结果', key);
          console.log('cache', cache);
          //将参数数组 `args` 转换为字符串 `key`,作为缓存的键
          return cache[key];
        } else {
          console.log('计算结果');
          const result = callback(...args);
          cache[key] = result;
          return result;
        }
      };
    }

    function multiply (a, b) {
      return a * b;
    }

    const memoMultiplication = memoize(multiply);
    console.log(memoMultiplication(10, 10));
    console.log(memoMultiplication(10, 10));
  1. 优化函数

因为这可能会导致缓存键的冲突(尤其是当参数包含对象或数组时,这些对象的 toString() 方法可能不会返回唯一标识它们的字符串),并且可能无法充分利用缓存的潜力。

  • 为了将 memoize 函数转化为最佳实践,我们可以使用一种更可靠的方法来生成缓存键。一种常见的做法是使用 JSON.stringify() 来序列化参数数组,但这仍然有潜在的问题,比如对象的属性顺序可能会改变,或者包含循环引用的对象无法被正确序列化。不过,对于大多数简单情况,这种方法是足够的。
 function memoize (callback) {
      let cache = {};
      return function (...args) {
        // 使用 JSON.stringify 来序列化参数数组,作为缓存的键  
        const key = JSON.stringify(args);
        if (key in cache) {
          console.log('从缓存中返回结果', key);
          return cache[key];
        } else {
          console.log('计算结果');
          const result = callback(...args);
          cache[key] = result;
          return result;
        }
      };
    }

    function multiply (a, b) {
      return a * b;
    }

    const memoMultiplication = memoize(multiply);
    console.log(memoMultiplication(10, 10)); // 缓存并返回结果  
  • 另一种更健壮的方法是使用某种形式的哈希函数来生成键。JavaScript 中没有内置的哈希函数,但我们可以使用第三方库(如 crypto 模块中的 createHash 函数,或者像 lodash 的 _.hashCode 这样的函数,尽管后者可能不是为安全性设计的)
 const crypto = require('crypto');

    function memoize (callback) {
      let cache = {};
      return function (...args) {
        // 使用 SHA-256 哈希函数来生成缓存键  
        const hash = crypto.createHash('sha256').update(JSON.stringify(args)).digest('hex');
        if (hash in cache) {
          console.log('从缓存中返回结果', hash);
          return cache[hash];
        } else {
          console.log('计算结果');
          const result = callback(...args);
          cache[hash] = result;
          return result;
        }
      };
    }

文章参考链接

2. 数组映射

  1. 前置知识点: JavaScript fromCharCode() 方法 parseInt() 函数
  • fromCharCode() 可接受一个指定的 Unicode 值,然后返回一个字符串。
let n = String.fromCharCode(65);
console.log('n',n)//A
  • parseInt() 函数可解析一个字符串,并返回一个整数。
  1. 问题说明:arr=['0', '1', '2']转成字符串ABC,将数组中的每个元素(这些元素目前是字符串形式的数字)映射到对应的字母上。

  2. 解决代码思路:

let arr = ['0', '1', '2','3','4'];  
  
// 使用map方法将每个元素映射到对应的字母  
let mappedArr = arr.map(function(item, index) {  
    // 字符'A'的ASCII码是65,因此我们通过加上index(0, 1, 2...)来获取对应的字母  
    console.log('parseInt',parseInt(item, 10));
    return String.fromCharCode(65 + parseInt(item, 10));  
});  
  console.log('mappedArr',mappedArr);
// 使用join方法将数组转换成字符串  
let result = mappedArr.join('');  
  
console.log(result); // 输出: ABCDE

3. 修改页面标题

通过htmlWebpackPlugin.options.title修改页面标题的两种方法

我们通过Vue CLI创建项目时,会自动生成public文件夹包含index.html文件,其中的title是<%= htmlWebpackPlugin.options.title %>表示,这是一种jsp语法,那么在使用当前表达式情况下如何修改title呢?

下面写出两种方法:

  1. vue.config.js 中使用 pages 字段

可以使用 pages 字段来定义的标题。首先要有vue.config.js文件,没有的话在根目录创建,并将 pages 字段添加到exports中,如下所示:

module.exports = {
  pages: {
    index: {
      entry: 'src/main.js', // 入口文件
      title: '你的标题'
    }
  }
}

  1. 链接 Webpack

同样在vue.config.js文件中,可以通过链接webpack修改title,如下所示:

module.exports = {
  chainWebpack: config => {
    config
      .plugin('html')
      .tap(args => {
        args[0].title = "你的标题";
        return args
    })
  }
}

ps: 修改完配置后,需要重新启动项目配置才会生效

4. 数组填充

数组实例的fill(), fill使用给定值填充一个数组。

  • Array.fill(target, start = 0, end = this.length)
  • 用途:常用于空数组的初始化。 参数解读:
    • target:填充数组的值。
    • start:填充的起始位置。
    • end:填充的结束位置。
	let list = [1,2,3,4];
	list.fill(7);  		// list = [7,7,7,7]
	list.fill(8,1,3) 	// list = [7,8,8,7]

5. 纯函数

纯函数(Pure Function)是函数式编程中的一个基本概念。它具有以下两个主要特点:

  1. 无副作用(No Side Effects) :纯函数在执行过程中不会对外部环境产生影响,即不会改变外部状态,也不会产生外部可见的变化,如修改全局变量、修改输入参数、输出到控制台、抛出异常、进行 I/O 操作等。
  2. 可预测性(Predictable) :对于相同的输入,纯函数总是返回相同的输出。这意味着函数的行为不依赖于程序中的状态变化,每次调用时,只要输入参数相同,输出的结果也必然相同。

1. 数组新增纯函数API

在 JavaScript 中,许多数组方法都是纯函数,例如:mapfilterslice 等,它们不会改变原始数组,而是返回一个新的数组。

最近,JavaScript 为数组操作带来了几个新的纯函数 API,它们是Array.toSorted()Array.toReversed()Array.toSpliced()以及Array.with()

这些新方法不仅保持了纯函数的特性,还提供了更多灵活的操作方式。

  1. Array.toSorted()

Array.toSorted()sort()方法的纯函数版本。

它返回一个新数组,其元素按升序排列,而原数组保持不变。

这个方法接受一个可选的比较函数,允许你自定义排序逻辑。

const numbers = [53281];
const sortedNumbers = numbers.toSorted();
console.log(sortedNumbers); // [1, 2, 3, 5, 8]
console.log(numbers); // [5, 3, 2, 8, 1] 原数组未改变
  1. Array.toReversed()

Array.toReversed()reverse()方法的纯函数版本。

它返回一个新数组,其元素顺序与原数组相反,原数组同样保持不变。

const items = [1234];
const reversedItems = items.toReversed();
console.log(reversedItems); // [4, 3, 2, 1]
console.log(items);         // [1, 2, 3, 4] 原数组未改变
  1. Array.toSpliced()

Array.toSpliced()splice()方法的纯函数版本。

它返回一个新数组,根据指定的索引和删除数量,以及可选的添加元素,来生成新数组。原数组同样不会受到影响。

const fruits = ["Banana""Orange""Apple""Mango"];
const newFruits = fruits.toSpliced(11"Lemon");
console.log(newFruits); // ["Banana", "Lemon", "Apple", "Mango"]
console.log(fruits);     // ["Banana", "Orange", "Apple", "Mango"] 原数组未改变
  1. Array.with()

Array.with()是一个新的纯函数,用于替换数组中指定索引处的元素。

它返回一个新数组,其中指定索引处的元素被替换为新值,而原数组保持不变。

const arr = [12345];
const newArr = arr.with(26);
console.log(newArr); // [1, 2, 6, 4, 5]
console.log(arr);    // [1, 2, 3, 4, 5] 原数组未改变

6.flex: 1有什么用

Flex 属性是一个复合属性,包含以下三个子属性:

  1. flex-grow:决定元素在容器中剩余空间的分配比例。默认值为 0,表示元素不会扩展。当设置为正数时,元素会按照设定比例扩展。
  2. flex-shrink:决定元素在空间不足时的收缩比例。默认值为 1,表示元素会按比例收缩。当设置为 0 时,元素不会收缩。
  3. flex-basis:定义元素在分配多余空间之前所占据的主轴空间。默认值为 auto,表示元素占据其本来大小。

flex: 1的作用

将一个元素的 flex 属性设置为 1,相当于将其分配了一个相对于其他元素相同的可伸缩空间。换句话说,flex: 1 会使该元素尽可能地占据父容器中的剩余空间,同时保持其他元素的相对位置和大小。

具体来说:

flex: 1; /* 等同于 flex: 1 1 0%; */
  • 「flex-grow」 设置为 1,表示元素会扩展,填满所有可用的额外空间。
  • 「flex-shrink」 设置为 1,表示元素会在空间不足时收缩,避免溢出。
  • 「flex-basis」 设置为 0%,表示元素在分配额外空间前不占用空间。

.navbar {  
display: flex;  
}  
  
.navbar a {  
flex: 1;  
border: 1px solid #ccc;  
padding: 10px;  
text-align: center;  
}
<nav class="navbar">  
<a href="#">标签 1</a>  
<a href="#">标签 2</a>  
<a href="#">标签 3</a>  
</nav>

通过设置链接的 flex 属性为 1,实现了它们的平均分配。无论导航栏的宽度如何变化,链接都会自动调整大小,以适应父容器的空间。

此笔记来源于这篇文章

7. 14种字符串方法

  1. valueOf()
  • 用于取出字符串对象中的值
const str = new String("str");
console.log(str.valueOf()) //str
  1. trimStart() /trimEnd() / trim()
  • 用于去除字符串的空格
const str = "  rich  "
console.log(str.trimStart())//rich  去除前空格
console.log(str.trimEnd())//  rich去除后空格
console.log(str.trim())//rich去除所有空格
  1. substring(startindex,endindex)
  • 截取字符串 [startIndex,endIndex)
const str = "l love you" 
console.log(str.substring(0,4))//l lo 
  1. startsWith(str,开始位置)/endsWith(str,结束位置)
  • 判断字符串是否以str开始或者结尾(在对应的开始位置或者结束位置)
const str = "l love you!"
console.log(str.startsWith("l"))//true
console.log(str.startsWith("l",1))//false
console.log(str.startsWith("l",0))//true
console.log(str.endsWith("!"))//true
console.log(str.endsWith("!", 10))//false
console.log(str.endsWith("!", 11))//true
  1. split(分割字符串,返回数量)
  • 用于分割字符串
const str = "str1-str2-str3";
console.log(str.split("-"))//['str1', 'str2', 'str3']
console.log(str.split("-", 2))//['str1', 'str2']
  1. slice(startindex,endindex)
  • 截取字符串 [startIndex,endIndex)
const str="l love you!"
console.log(str.slice(0,6))//l love
  1. padStart(length,content)/padEnd(length,content)
  • 填充字符串
const str = "you"
console.log(str.padStart(5, '*'))//**you
console.log(str.padEnd(5, '*'))//you**
  1. includes(str,开始位置)
  • 判断字符串是否包含某一字符串
const str= "l love you!";
console.log(str.includes("love"))//true
console.log(str.includes("love", 2))//true
console.log(str.includes("love", 3))//false
  1. concat(str1,str2,...)
  • 拼接字符串
const str= "l love you!";
console.log(str.concat(" Do you love me?"))//l love you! Do you love me?
console.log(str.concat(" Do you love me?", "please tell me."))
//l love you! Do you love me?please tell me.
  1. charAt(index)
  • 返回对应索引的字符
const str= "l love you!";
console.log(str.charAt(4))//v
  1. indexOf(str,开始位置)/lastIndexOf(str,开始位置)
  • 返回str的位置 indexOf从头部(开始位置index)开始向右寻找 lastIndexOf从尾部(开始位置index)开始向左寻找
const str= "l love you!";
console.log(str.indexOf("l"))//0
console.log(str.lastIndexOf("l"))//2
console.log(str.indexOf("l", 1))//2
console.log(str.indexOf("l", 3))//-1
console.log(str.lastIndexOf("l",1))//0
console.log(str.lastIndexOf("l",3))//2
  1. repeat(count)
  • 重复次数
const str= "l love you!";
console.log(str.repeat(3))//l love you!l love you!l love you!
  1. replace(正则或者字符串,targetStr)/replaceAll(正则或者字符串,targetStr)
  • 替换字符串
const str= "l love you!";
console.log(str.replace("l", "@"))//@ love you!
console.log(str.replaceAll("l", "@"))//@ @ove you!
  1. toUpperCase()/toLowerCase()
  • 改变大小写
const str= "l love YOU!";
console.log(str.toLowerCase())//l love you!
console.log(str.toUpperCase())//L LOVE YOU!

PS:工作中用过的一些知识点,自己记录的笔记和整理来网络上的资源 ,方便以后复习使用。