💎一站式轻松地调用各大LLM模型接口,支持GPT4、智谱、星火、月之暗面及文生图 广告
[TOC] ## 实现 JS 对象的深拷贝 备注: 递归容易造成爆栈,尾部调用(需要了解一下)可以解决递归的这个问题,Chrome 的 V8 引擎做了尾部调用优化,我们在写代码的时候也要注意尾部调用写法。递归的爆栈问题可以通过将递归改写成枚举的方式来解决,就是通过for或者while来代替递归。 ## 实现js方法对对url参数的解析 ,延伸url参数的拼接 ## 实现一个简单的模版引擎 列:我叫a,年龄b,性别c; let data = { name: '小明', age: 18, } 没有定义的返回undefined ## 如何快速让字符串变成已千为精度的数字 ## 如何判断当前的环境是node还是浏览器 通过判断global 对象是否是window,window的话就是浏览器中.直接控制台输出查看window是有值的还是未定义的。 ## 对象相等判断 简单写出一个方法判断两个对象相等,假设只具有一层属性结构,且均为基本值。基本逻辑很简单,判断两个对象的属性数量相同,并且a具有的属性另一个属性也具有并且值相同即可。 ``` function isEqual(a, other){ var len = Object.keys(a); if(len !== Object.keys(b)) return false; while(len--){ key = keys[len] if (!(b.hasOwnProperty(key) && a[key] === b[key]))) return false; } return true } ``` 备注:如果你想了解更多,欢迎去看 - [eq写法分析](https://github.com/mqyqingfeng/Blog/issues/41) - [lodash库:baseIsEqualDeep](https://github.com/lodash/lodash/blob/master/.internal/baseIsEqualDeep.js) ## 闭包 - 优点 使用闭包主要是为了设计私有的方法和变量,可以避免全局变量的污染 - 缺点 闭包会常驻内存,会增大内存使用量,使用不当很容易造成内存泄露。在js中,函数即闭包,只有函数才会产生作用域的概念 - 闭包的特点 1.函数嵌套函数 2.函数内部可以引用外部的参数和变量 3.参数和变量不会被垃圾回收机制回收 ## 浮点数精度问题 ### 问题 - 计算不准确 - 超出表示范围,大数危机 首先要搞清楚 JavaScript 如何存储小数。和其它语言如 Java 和 Python 不同,JavaScript 中所有数字包括整数和小数都只有一种类型 — `Number`。它的实现遵循 [IEEE 754](http://grouper.ieee.org/groups/754/) 标准,使用 64 位固定长度来表示,也就是标准的 double 双精度浮点数(相关的还有float 32位单精度)。 这样的存储结构优点是可以归一化处理整数和小数,节省存储空间。 解决方案: ### **1 数据展示类** 当你拿到 `1.4000000000000001` 这样的数据要展示时,建议使用 `toPrecision` 凑整并 `parseFloat` 转成数字后再显示,如下: ``` parseFloat(1.4000000000000001.toPrecision(12)) === 1.4 // True ``` 封装成方法就是: ```js function strip(num, precision = 12) { return +parseFloat(num.toPrecision(precision)); } ``` 为什么选择 `12` 做为默认精度?这是一个经验的选择,一般选12就能解决掉大部分0001和0009问题,而且大部分情况下也够用了,如果你需要更精确可以调高。 ### **2 数据运算类** 对于运算类操作,如 `+-*/`,就不能使用 `toPrecision` 了。正确的做法是把小数转成整数后再运算。以加法为例: ```js /** * 精确加法 */ function add(num1, num2) { const num1Digits = (num1.toString().split('.')[1] || '').length; const num2Digits = (num2.toString().split('.')[1] || '').length; const baseNum = Math.pow(10, Math.max(num1Digits, num2Digits)); return (num1 * baseNum + num2 * baseNum) / baseNum; } ``` 以上方法能适用于大部分场景。遇到科学计数法如 `2.3e+1`(当数字精度大于21时,数字会强制转为科学计数法形式显示)时还需要特别处理一下。 能读到这里,说明你非常有耐心,那我就放个福利吧。遇到浮点数误差问题时可以直接使用 https://github.com/dt-fe/number-precision 完美支持浮点数的加减乘除、四舍五入等运算。非常小只有1K,远小于绝大多数同类库(如Math.js、BigDecimal.js),100%测试全覆盖,代码可读性强,不妨在你的应用里用起来! ### **3 参考推荐文章**: - [浮点数精度](https://github.com/camsong/blog/issues/9) ## null与undefined的区别 null是一个表示"无"的对象,转为数值时为0;undefined是一个表示"无"的原始值,转为数值时为NaN。 当声明的变量还未被初始化时,变量的默认值为undefined。 null用来表示尚未存在的对象,常用来表示函数企图返回一个不存在的对象。 * undefined表示"缺少值",就是此处应该有一个值,但是还没有定义。典型用法是: (1)变量被声明了,但没有赋值时,就等于undefined。 (2) 调用函数时,应该提供的参数没有提供,该参数等于undefined。 (3)对象没有赋值的属性,该属性的值为undefined。 (4)函数没有返回值时,默认返回undefined。 * null表示"没有对象",即该处不应该有值。典型用法是: (1) 作为函数的参数,表示该函数的参数不是对象。 (2) 作为对象原型链的终点。