Javascript写代码时容易犯的错误

简介: Javascript写代码时容易犯的错误

Javascript写代码时容易犯的错误


切换变量0和1


JavaScript


// if判断可以这么写


let flag = 0;


if (flag === 0) {


flag = 1;


} else {


flag = 0;


}


// 也可以用三目运算符


flag = flag === 0 ? 1 : 0;


// 也可以使用位异或(^)


flag ^= 1;


一般我建议在js上是尽量少用位运算,为什么呢?因为位运算其实二进制数执行运算,包括与&、或|、异或^、非~、左移<<、右移>>都是整数的逐位运算。然而,不幸的是在js内部所有数字都是双精度浮点数,所以这些运算js会先转为整数再运算,而且代码阅读性也会降低。异或(位值”一样的就为0 不一样就为1)


其实说到位运算,还不得不提一个月更贴,为什么


Apache


console.log(0.1 + 0.2 === 0.3); // false


总结一句就是十进制转二进制的精度丢失,如果想深入了解,推荐一篇文章0.1 + 0.2不等于0.3?为什么JavaScript有这种“骚”操作? 78


!!


继续说位运算中的非,我在项目中看到越来越多的人用!!来判空等操作,针对一般场景也没什么问题,但是毫无节制的使用!!真的有必要吗?比如已知表达式就是一个Boolean值,还需要这样判断吗?


非运算字面比较简单——真就是假,假就是真,不过js的类型特点,还是详细看下:


JavaScript


console.log(!null); // true


console.log(!0); // true


console.log(!1); // false


console.log(!''); // true


console.log(!'a'); // false


console.log(!{}); // false


console.log(!{ a: 'a' }); // false


let a = 0;


if (!!a) {


console.log('no empty');


} else {


console.log('is empty');


}


这里基本涵盖了所有类型(boolean就没必要参与了),可以看到null、undefined、0、’'是true,其它为false,所以我们就明白为什么很多人用这个来判断空字符串了吧,问题却来了0不是空啊,比如常见场景我们Http请求时,要剔除空参数,但如果参数有个0,那就尴尬了吧~即使你真的要将0纳入false范畴,我也更推荐下面的做法:


JavaScript


console.log(Boolean('null'));


console.log(Boolean(0));


console.log(Boolean(1));


console.log(Boolean(''));


console.log(Boolean('a'));


console.log(Boolean({}));


console.log(Boolean({ a: 'a' }));


如果你只是单纯的想判断空,可以使用下面的方法


JavaScript


function isEmpty(str) {


return null == str || '' == str;


}


console.log(isEmpty(0));


console.log(isEmpty(void 0));


console.log(isEmpty(null));


void其实是javascript中的一个函数,接受一个参数,返回值永远是undefined。可以说,使用void目的就是为了得到javascript中的undefined


C++

console.log(void ("hello")) // undefined
console.log(void (0)) // undefined
console.log(void 0) // undefine

//


void(0)和undefined


为什么不直接使用undefined呢?主要有2个原因:


使用void 0比使用undefined能够减少3个字节。虽然这是个优势,个人但感觉意义不大,牺牲了可读性和简单性


C


console.log("undefined".length)


console.log("void 0".length)


2、undefined并不是javascript中的保留字,我们可以使用undefined作为变量名字,然后给它赋值,, 但在chrome 中打印出来的是 undefined


C


undefined === void 0 \ true


isNaN的问题


Number.isNaN() - JavaScript | MDN


猜测下面的值


CoffeeScript


console.log(isNaN('叽里呱啦'));


console.log(Number.isNaN("叽里呱啦"));


交换值


如果用位运算,则


JavaScript


let a = 1;


let b = 2;


a ^= b;


b ^= a;


a ^= b;


console.log(a); // 2


console.log(b); // 1


但与借助中间值,似乎差距不大


JavaScript


let a = 1;


let b = 2;


let c = a;


a = b;


b = c;


console.log(a); // 2


console.log(b); // 1


而现在基本都支持ES6的情况下,其实可以用解构来操作


JavaScript


let a = 1;


let b = 2;


[a, b] = [b, a];


console.log(a); // 2


console.log(b); // 1


解构一般用来如本例的交换值,或者从对象取值,如


Swift


// 从对象中取值


let obj = { a: 1, b: 2, c: 3 };


let { a, b, c } = obj;


console.log(a, b, c); // 1,2,3


// 从数组中取值


let arr = [1, 2, 3, 4, 5];


let [a, , , b, , c] = arr;


console.log(a, b, c); // 1 4 undefined


但解构的作用可不仅仅是如此,还有很多妙处,比如:从数组中取一个值,如果该索引不存在则赋一个默认值


JavaScript


let arr = [1];


let value = 'a';


if (arr.length > 1) {


value = arr[1];


}


console.log(value); // a


而用解构,则仅需


JavaScript


let arr = [1];


let [, value = 'a'] = arr;


console.log(value); // a


清空数组的操作


JavaScript


let arr = [1,2,3];


// 第一种写法


arr = [];


// 第二种写法


arr.length = 0;


两种写法有什么区别呢?


第一种写法其实是赋值一个新数组给变量aar,第二种写法是直接操作原数组。看下面例子


JavaScript


let arr = [1, 2, 3];


let arr2 = arr;


arr = [];


console.log('arr=', arr); // []


console.log('arr2=', arr2); // [ 1, 2, 3 ]


arr = arr2;


arr2.length = 0;


console.log('arr=', arr); // []


console.log('arr2=', arr2); // []


两种写法,很明显不能一棍子说优劣,但如果你的数组不需要使用了,自然应该使用Array.length=0的写法。


For循环length问题


JavaScript


let a =[1,2,3,4];


for(let i=0;i<a.length;i++){


console.log(a[i]);


}


JavaScript


let a =[1,2,3,4];


const len = a.length;


for(let i=0;i<len;i++){


console.log(a[i]);


}


JavaScript


let a =[1,2,3,4];


for(let i=0,len = a.length;i<len;i++){


console.log(a[i]);


}


这三种的优劣比较,显然第三种比较科学


内存堆栈的问题


JavaScript


let a = '111';


let b = '111';


console.log(a == b);


let a1 = { name: '111' };


let a2 = { name: '111' };


console.log(a1 == a2);


当 JavaScript 程序运行时,在非全局作用域中产生的局部变量均储存在栈内存中。


但是,只有原始类型的变量是真正地把值储存在栈内存中。


而引用类型的变量只在栈内存中储存一个引用(reference),这个引用指向堆内存里的真正的值。


💡 原始类型(Primitive type)


原始类型又称基本类型,包括 string、number、bigint、boolean、undefined、null 和 symbol(ES6 新增)。


原始类型的值被称为原始值(Primitive value)。


补充:虽然 typeof null 返回的是 'object',但是 null 真的不是对象,会出现这样的结果其实是 JavaScript 的一个 Bug~


💡 引用类型(Reference type)


除了原始类型外,其余类型都属于引用类型,包括 Object、Array、Function、Date、RegExp、String、Number、Boolean 等等...


实际上 Object 是最基本的引用类型,其他引用类型均继承自 Object。也就是说,所有引用类型的值实际上都是对象。


引用类型的值被称为引用值(Reference value)。


简单来说


在多数情况下,原始类型的数据储存在栈内存,而引用类型的数据(对象)则储存在堆内存


最后翻出一个老梗,前端如何不带脏字吐槽PM


CSS


console.log((!(~+[]) + {})[--[~+""][+[]] * [~+[]] + ~~!+[]] + ({} + [])[[~!+[]] * ~+[]]);


相关文章
|
12天前
|
JavaScript 前端开发 安全
【逆向】Python 调用 JS 代码实战:使用 pyexecjs 与 Node.js 无缝衔接
本文介绍了如何使用 Python 的轻量级库 `pyexecjs` 调用 JavaScript 代码,并结合 Node.js 实现完整的执行流程。内容涵盖环境搭建、基本使用、常见问题解决方案及爬虫逆向分析中的实战技巧,帮助开发者在 Python 中高效处理 JS 逻辑。
|
2月前
|
JavaScript 前端开发 算法
流量分发代码实战|学会用JS控制用户访问路径
流量分发工具(Traffic Distributor),又称跳转器或负载均衡器,可通过JavaScript按预设规则将用户随机引导至不同网站,适用于SEO优化、广告投放、A/B测试等场景。本文分享一段不到百行的JS代码,实现智能、隐蔽的流量控制,并附完整示例与算法解析。
89 1
|
3月前
|
JavaScript 前端开发
怀孕b超单子在线制作,p图一键生成怀孕,JS代码装逼娱乐
模拟B超单的视觉效果,包含随机生成的胎儿图像、医疗文本信息和医院标志。请注意这仅用于前端开发学习
|
3月前
|
JavaScript
JS代码的一些常用优化写法
JS代码的一些常用优化写法
72 0
|
5月前
|
存储 JavaScript 前端开发
在NodeJS中使用npm包进行JS代码的混淆加密
总的来说,使用“javascript-obfuscator”包可以帮助我们在Node.js中轻松地混淆JavaScript代码。通过合理的配置,我们可以使混淆后的代码更难以理解,从而提高代码的保密性。
448 9
|
6月前
|
前端开发 JavaScript
【Javascript系列】Terser除了压缩代码之外,还有优化代码的功能
Terser 是一款广泛应用于前端开发的 JavaScript 解析器和压缩工具,常被视为 Uglify-es 的替代品。它不仅能高效压缩代码体积,还能优化代码逻辑,提升可靠性。例如,在调试中发现,Terser 压缩后的代码对删除功能确认框逻辑进行了优化。常用参数包括 `compress`(启用压缩)、`mangle`(变量名混淆)和 `output`(输出配置)。更多高级用法可参考官方文档。
465 11
|
8月前
|
人工智能 程序员 UED
【01】完成新年倒计时页面-蛇年新年快乐倒计时领取礼物放烟花html代码优雅草科技央千澈写采用html5+div+CSS+JavaScript-优雅草卓伊凡-做一条关于新年的代码分享给你们-为了C站的分拼一下子
【01】完成新年倒计时页面-蛇年新年快乐倒计时领取礼物放烟花html代码优雅草科技央千澈写采用html5+div+CSS+JavaScript-优雅草卓伊凡-做一条关于新年的代码分享给你们-为了C站的分拼一下子
337 21
【01】完成新年倒计时页面-蛇年新年快乐倒计时领取礼物放烟花html代码优雅草科技央千澈写采用html5+div+CSS+JavaScript-优雅草卓伊凡-做一条关于新年的代码分享给你们-为了C站的分拼一下子
|
6月前
|
JavaScript 前端开发 算法
JavaScript 中通过Array.sort() 实现多字段排序、排序稳定性、随机排序洗牌算法、优化排序性能,JS中排序算法的使用详解(附实际应用代码)
Array.sort() 是一个功能强大的方法,通过自定义的比较函数,可以处理各种复杂的排序逻辑。无论是简单的数字排序,还是多字段、嵌套对象、分组排序等高级应用,Array.sort() 都能胜任。同时,通过性能优化技巧(如映射排序)和结合其他数组方法(如 reduce),Array.sort() 可以用来实现高效的数据处理逻辑。 只有锻炼思维才能可持续地解决问题,只有思维才是真正值得学习和分享的核心要素。如果这篇博客能给您带来一点帮助,麻烦您点个赞支持一下,还可以收藏起来以备不时之需,有疑问和错误欢迎在评论区指出~
|
6月前
|
JavaScript 前端开发 API
JavaScript中通过array.map()实现数据转换、创建派生数组、异步数据流处理、复杂API请求、DOM操作、搜索和过滤等,array.map()的使用详解(附实际应用代码)
array.map()可以用来数据转换、创建派生数组、应用函数、链式调用、异步数据流处理、复杂API请求梳理、提供DOM操作、用来搜索和过滤等,比for好用太多了,主要是写法简单,并且非常直观,并且能提升代码的可读性,也就提升了Long Term代码的可维护性。 只有锻炼思维才能可持续地解决问题,只有思维才是真正值得学习和分享的核心要素。如果这篇博客能给您带来一点帮助,麻烦您点个赞支持一下,还可以收藏起来以备不时之需,有疑问和错误欢迎在评论区指出~
|
8月前
|
前端开发 JavaScript
【02】v1.0.1更新增加倒计时完成后的放烟花页面-优化播放器-优化结构目录-蛇年新年快乐倒计时领取礼物放烟花html代码优雅草科技央千澈写采用html5+div+CSS+JavaScript-优雅草卓伊凡-做一条关于新年的代码分享给你们-为了C站的分拼一下子
【02】v1.0.1更新增加倒计时完成后的放烟花页面-优化播放器-优化结构目录-蛇年新年快乐倒计时领取礼物放烟花html代码优雅草科技央千澈写采用html5+div+CSS+JavaScript-优雅草卓伊凡-做一条关于新年的代码分享给你们-为了C站的分拼一下子
199 14
【02】v1.0.1更新增加倒计时完成后的放烟花页面-优化播放器-优化结构目录-蛇年新年快乐倒计时领取礼物放烟花html代码优雅草科技央千澈写采用html5+div+CSS+JavaScript-优雅草卓伊凡-做一条关于新年的代码分享给你们-为了C站的分拼一下子