Javascript容易犯的错误

简介: Javascript容易犯的错误

Javascript写代码时容易犯的错误

切换变量0和1

// if判断可以这么写
let flag = 0;
if (flag === 0) {
flag = 1;
} else {
flag = 0;
}
// 也可以用三目运算符
flag = flag === 0 ? 1 : 0;
// 也可以使用位异或(^)
flag ^= 1;


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


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

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

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

!!

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

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

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范畴,我也更推荐下面的做法:

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' }));

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

function isEmpty(str) {
return null == str || '' == str;
}
console.log(isEmpty(0));
console.log(isEmpty(void 0));
console.log(isEmpty(null));
————————————————
版权声明:本文为CSDN博主「程序员牛哥」的原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接及本声明。
原文链接:https://blog.csdn.net/pengfeicfan/article/details/115587211
void其实是javascript中的一个函数,接受一个参数,返回值永远是undefined。可以说,使用void目的就是为了得到javascript中的undefined
console.log(void "hello") // undefined
console.log(void ("hello")) // undefined
console.log(void (0)) // undefined
console.log(void 0) // undefine
//


void(0)和undefined

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

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

console.log("undefined".length)
console.log("void 0".length)

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

undefined === void 0 \\ true

isNaN的问题

Number.isNaN() - JavaScript | MDN

猜测下面的值

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

交换值

如果用位运算,则

let a = 1;
let b = 2;
a ^= b;
b ^= a;
a ^= b;
console.log(a); // 2
console.log(b); // 1

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

let a = 1;
let b = 2;
let c = a;
a = b;
b = c;
console.log(a); // 2
console.log(b); // 1

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

let a = 1;
let b = 2;
[a, b] = [b, a];
console.log(a); // 2
console.log(b); // 1


  • 解构一般用来如本例的交换值,或者从对象取值,如
// 从对象中取值
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

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

let arr = [1];
let value = 'a';
if (arr.length > 1) {
value = arr[1];
}
console.log(value); // a

而用解构,则仅需

let arr = [1];
let [, value = 'a'] = arr;
console.log(value); // a

清空数组的操作

let arr = [1,2,3];
// 第一种写法
arr = [];
// 第二种写法
arr.length = 0;

两种写法有什么区别呢?

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

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问题

let a =[1,2,3,4];
for(let i=0;i<a.length;i++){
console.log(a[i]);
}
let a =[1,2,3,4];
const len = a.length;
for(let i=0;i<len;i++){
console.log(a[i]);
}
let a =[1,2,3,4];
for(let i=0,len = a.length;i<len;i++){
console.log(a[i]);
}

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

内存堆栈的问题

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

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


相关文章
|
2天前
|
人工智能 JSON API
全网刷屏的 Jev 模型正式开放!一手实战测评 + 保姆级教程
全网爆火的 Jev 模型是什么?有什么用?怎么使用?怎么接入 AI 编程工具?效果真的好么?傻子可懂的 Jev 保姆级实战教程 + 项目实战测评来啦
4660 5
|
14天前
|
人工智能
千问办公官网入口:阿里AI办公QwenWork产品页和免费网页端链接
千问办公官网含两大入口:一是网页端(qwenwork.cn),即开即用,支持浏览器直接访问;二是阿里云产品页 https://t.aliyun.com/U/JNKJuO 提供免费/付费版详情、功能介绍及使用指南。
|
14天前
|
人工智能 自然语言处理 安全
阿里云千问办公 QwenWork详细介绍:产品核心能力、典型场景、价格及常见问题解答
千问办公是阿里云推出的一站式AI办公平台,主打"不止于对话,更注重交付",依托通义千问旗舰大模型,用户一句话即可完成数据分析、PPT生成、视频剪辑等复杂任务,直接输出可用成果。产品深度打通钉钉生态与企业OA,覆盖桌面端、网页端,提供企业标准版198元/人/月等多档订阅方案,新用户注册即赠2000积分,适配工程师、HR、财务等多职业办公场景,成为能动手干活的"全能AI同事"。
|
13天前
|
IDE 开发工具
Qoder 上线 Sonus 模型,Computer Use 能力全面增强
Qoder国际版上线全新内置大模型Sonus(/ˈsoʊnəs/),全球领先,专精超长任务执行与电脑操作(Computer Use)。配合Qoder桌面端0.2.3版本,可自主完成编程、金融建模、科研及表格制作等复杂工作。现全面支持Qoder全系产品,效率提升3.2倍。
1674 8
Qoder 上线 Sonus 模型,Computer Use 能力全面增强
|
15天前
|
缓存 人工智能 自然语言处理
阿里云qwen3.8-flash大模型介绍:模型能力、模型价格、免费额度与最新活动
本文是阿里云百炼平台Qwen3.8-Flash大模型的选型接入指南,作为兼顾性能与响应速度的高性价比多模态模型,它支持百万级上下文窗口、全场景多模态输入与完整智能体能力矩阵,适配编程辅助、智能体协作等核心场景。文中同步梳理了最新下调的阶梯定价、夜间4折等优惠活动,搭配OpenAI兼容流式调用示例,帮助开发者低成本快速落地高并发AI应用。
阿里云qwen3.8-flash大模型介绍:模型能力、模型价格、免费额度与最新活动
|
9天前
|
缓存 IDE Java
【保姆级】Android Studio下载、安装和汉化教程(2026最新)
Android Studio 是 Google 官方推出的免费 Android 应用开发集成环境,基于 IntelliJ IDEA,内置模拟器、调试器、性能分析及 Compose 界面工具,功能全面,文档丰富,是安卓开发首选工具。(239字)
|
15天前
|
人工智能 API 内存技术
刚刚 DeepSeek V4.1 Flash 开启内测,1 分钟教你用上!
刚刚 DeepSeek 内测群发布了 DeepSeek V4.1 Flash 中间版本内测的消息,这次的模型采用了新的结构,原生支持多模态、能力更强、速度更快、且成本更低。
2005 15