一、依赖安装问题
当前还有很多老的项目在运行,接手老项目的时候,除了要切换旧的node版本之外,还要注意依赖列表里面有没有node-sass这样的依赖包,如果有的话,可以先直接尝试修改node-sass版本到最新,进行依赖安装
二、nvm下载不到老版本的nodejs
我当前的解决方案是卸载nvm,去nodejs中文网,找到老版本库,手动安装对应版本,之后再装回nvm,为了后续维护方便,现在都习惯在文件目录下创建一个 .nvmrc文件,记录当前项目对应的版本号
// .nvmrc
14.17.6
三、调试技巧
1、浏览器控制台调试
- 最常用的console面板,新手最开始都只关注console语句左侧输出的内容,还会在输出语句中加一个自定义的标识,但是却忽略了语句输出的右侧有console语句执行的位置信息,点击可以直接跳转source面板看到输出语句在源码中的位置
- network面板,最开始关注的是请求的地址、请求方式是否正确;熟练了之后会关注地址栏传参方式,get请求数据通过query方式拼接到地址后边,post请求一般会在请求体里面,在request面板里面可以预览,符合rest规范的接口设计会直接在地址中隐性的传递参数,也有愚蠢的后端会使用post请求,但是参数要求地址栏拼接。在请求头信息里面可以查看身份验证用的token,cookie是否正确携带,在响应头信息中可以看到后端接口是否设置了Access-Control-Allow-Origin: *, 允许跨域;Cache-Control:no-cache,针对get请求跨域的问题;同样,每一条请求右侧都会有地址信息,可以直接看到请求发起的函数位置
- source面板,可以看到源代码,未经压缩的代码,在这个面板可以直接看到原始信息
- vue devtools调试面板,在某些愚蠢的框架封装,比如avue的表单,需求里面又涉及到表单分列时,avue的设置就会让人崩溃,这时候就可以使用vue devtools查看对用表单项的el-row相关配置,加快调试
2、微信小程序调试
- 微信开发者工具里面,可以对小程序拉起的各种情况进行模拟,比如页面跳转,扫码进入,h5页面直接跳转进入等等的情况都可以对跳入参数进行模拟
- 在学习的过程中,会注意到地址烂query形式的传参,虽然刷新之后,信息不会丢失,但是一不小心就会造成地址超长,导致数据丢失,json解析失败,导致生产bug,所以一般情况下,除了传递id之类的固定长度的信息,其余情况下不建议使用路径传参,这个建议同样适用于浏览器
- 苹果系统下的小程序对某些样式支持不完整,所以在上线之前尽量同时使用安卓和ios对页面进行检查
3、React Native调试
使用console语句,可以直接在yarn run android命令运行拉起的cmd窗口中查看到console语句的输出结果,在界面按住ctrl + M可以进行强制重载等命令
- react native环境安装折腾半天,非常容易出问题;
- 开发过程中很多组件库已经停止维护了,正在维护的组件库也有很多bug,使用完全不和ant design一样,文档清晰,使用简洁,很多东西使用有很大的问题;
- 动画库,看起来效果是实现了,但是真机上运行看着卡卡的,跟原生安卓程序差距很大;
- 调试方面,能拉起的chrome调试工具看不到element和network,参考性为0.官方推荐的fiddle,安装包下载不下来,github上自己找一个安装包下来,安装后界面一片空白,react-native-debugger库也完全没法用,现在已经放弃了调试;
- 总结:现在完全不推荐react-native
四、js本身缺陷
1、精度问题
js进行整数运算的时候,不会有问题,但是进行浮点数运算的时候,就得不到正确的答案,根据生产经验,只要项目中涉及到计算,就肯定会存在精度问题,我常用的解决方式是使用big.js库,库本身很小,使用简单
import Big from 'big.js';
const x = new Big(123.4567)
x.plus(1) // 加法 1234.4567
x.minus(1) // 减法 122.4567
x.times(0.1) // 乘法 12.34567
x.div(10) // 除法 12.34567
big.js本身还有个toFixed方法,和js原生的toFixed方法一样,实行的都是银行家舍入法,而不是正常的四舍五入,在实际生产中会存在问题,解决方法见第四条
2、jsp或非严格模式下可能会存在的隐性进进制转换
在维护jsp项目的时候,某一次发现在传递给后端id进行数据操作的时候,偶然会出现id错误的情况,仔细检查后发现,是由于有点id会以0开头,js运行的时候默认进行了进制转换,解决方式是使用es6的模版字符串对可以参数进行包裹,确保传递给后端的数据不会变成八进制
3、恒等判断
== 运算和===运算符的区别简单来说就是==运算符会对符号两边的数据进行默认转换,在实际运行中,==可能会出现判断结果不符合预期,所以实际运行中建议都使用===运算符进行比较,手动的对可能会出现问题的变量进行类型转换,比如string和number
4、js原生api toFixed()方法的问题
原生toFixed方法并不是四舍五入,而是银行家舍入法,实际生产会出现问题,解决方案,使用Math.round()api进行转换
function round(number, precision) {
return Math.round(+number + "e" + precision) / Math.pow(10, precision);
}
round(1.005, 2); //1.01
五、将变量转换成字符串
1、toString() 方法,这个方法对number,boolean,symbol, array,function类型的数据有效
const num = 456
const strNum = num.toString() // '456'
const bool = true
const strBool = bool.toString() // 'true'
const arr = [1,2,3]
const strArr = arr.toString() // '1,2,3'
const fn = function () {
return 1
}
const strFn = fn.toString() // 'function () { return 1 }'
const syb = Symbol('test')
const strSymb = syb.toString() // 'Symbol('test')'
2、String()构造函数方法,此方法对number, boolean, null, undefined, symbol, array, function类型的数据有效
const num = 123
const strNum = String(num) // '123'
const bool = true
const strBool = String(bool) // 'bool'
const arr = [1,2,3]
const strArr = String(arr) // '1,2,3'
const fn = function () {
return 1
}
const strFn = String(fn) // 'function () { return 1 }'
const syb = Symbol('test')
const strSymb = String(syb) // 'Symbol('test')'
const nu = null
const strNu = String(nu) // 'null'
const ud = undefined
const strUd = String(ud) // 'undefined'
3、es6的模板字符串方法,效果和String一样,对null, undefined也有效
这种方法在解决jsp代码里面,后端返回的id如果以0开头,浏览器解析函数时,自动将数据以八进制解析,接口传数据的时候又转换成十进制导致数据传递错误的场景里面有奇效。
function(`${id}`) {
// 借用id对后台进行数据转换的操作
}
const arr = [1,2,3]
const strArr = `${arr}` // '1,2,3'
... // 其余类型省略
4、对object类型的数据转换字符串
// [object object]类型的数据,使用JSON方法转换字符串
const obj = { name: 'test' }
const strObj = JSON.stringify(obj) // '{"name":"test"}'
5、利用字符串拼串 + ’‘
const num = 123
num + '' // '123'
六、TypeScript相关
1、types类型声明文件不写到src文件下,单独出来
{
"compilerOptions": {
"baseUrl": ".",
"paths": {
"@/*": ["src/*"],
}
},
"include": ["src/**/*", "types/**/*.d.ts", "components/**/*"]
}
2、类型声明关键字是使用type还是interface
A、两个关键字在功能实现方面都可以进行类型约束和类似“继承”的效果,但是在vscode里面,interface声明的类型鼠标放上去只能看到一个类型名,而type声明可以看到具体类型,在可视化方面,更推荐type关键字。
B、type和interface实现继承
interface关键字需要使用extends关键字实现继承,如果继承过来的属性和新加的属性冲突,会报错
type关键字的“继承”使用&操作符,如果类型声明冲突,冲突字段的类型会变成never