你不知道的js

整数

1 == 1.0  // true
1 === 1.0 // true

JavaScript 内部,所有数字都是以64位浮点数形式储存,即使整数也是如此。所以,1与1.0是相同的,是同一个数。

正0和负0

+0 === -0    // true
-0 === 0     // true
+0 === 0     // true

+0 和 -0的符号表示位不同,正负0的比较只有用ES6中的Object.is判断才返回false

	Object.is(+0,-0)   // false
	Object.is(+0,0)   // true
	Object.is(-0,0)   // false

无穷数

 2 ** 1024 // Infinity
 1/-0 // -Infinity

根据IEE64标准,64位浮点数的指数部分的长度是11个二进制位,意味着指数部分的最大值是2047(2的11次方减1)。也就是说,64位浮点数的指数部分的值最大为2047,分出一半表示负数,则 JavaScript 能够表示的数值范围为21024到2-1023(开区间),超出这个范围的数无法表示。

如果一个数大于等于2的1024次方,那么就会发生“正向溢出”,即 JavaScript 无法表示这么大的数,这时就会返回Infinity

整数最大/最小值

// 超过范围的计算
9007199254740992 + 1 // 9007199254740992
9007199254740992 + 2 // 9007199254740994

Number.MAX_SAFE_INTEGER === 9007199254740991 // true
Number.MAX_SAFE_INTEGER === 2**53-1  //true

js中整数最大值的安全范围是Number.MIN_SAFE_INTEGER到Number.MAX_SAFE_INTEGER即-(2的53次方-1) 到 (2的53次方-1)

原始类型

  Number
  String
  Null
  Undefined
  Symbol
  BigInt 
  Symbol

原始类型不可以修改,可以重新赋值

var num = 1;
function changeNumber(n){
	num++;
}
console.log(num); // 1

引用类型可以被修改

var obj = {n:1};
function changeObjProperty(o,p){
	o[p] = undefined;
}
changeObjProperty(obj,'n');
console.log(obj);  // {n: undefined}

比较

[] == ![] // true
NaN !== NaN // true
[] == '' // true 

1 == true // true
2 == true // false
"2" == true // flase

null > 0 // false
null < 0 // false
null == 0 // false
null >= 0 // true

对于被广泛使用的比较运算符(==)来说,会在进行比较之前,将两个操作数转换成相同的类型。对于关系运算符(比如 <=)来说,会先将操作数转为原始值,使它们类型相同,再进行比较运算。

比较的特点:

  • 对于两个拥有相同字符顺序,相同长度,并且每个字符的位置都匹配的字符串,应该使用严格比较运算符。

  • 对于两个数值相同的数字应该使用严格比较运算符,NaN和任何值不相等,包括其自身,正数零等于负数零。

  • 对于两个同为true或同为false的布尔操作数,应使用严格比较运算符。
    不要使用严格比较运算符或比较运算符来比较两个不相等的对象。

  • 当比较一个表达式和一个对象时,仅当两个操作数引用相同的对象(指针指向相同对象)。

  • 对于Null 和 Undefined 类型而言,应使用严格比较运算符比较其自身,使用比较运算符进行互相比较。

  • 对象和字符串比较,对象转为字符串两者再比较

==,===和Object.is

三个都是判断相等的有什么不同呢,看下面表格

变量x变量y=====Object.is
undefinedundefinedtruetruetrue
nullnulltruetruetrue
truetruetruetruetrue
falsefalsetruetruetrue
“foo”“foo”truetruetrue
00truetruetrue
+0-0truetruefalse
0falsetruefalsefalse
“”falsetruefalsefalse
“”0truefalsefalse
“0”0truefalsefalse
“17”17truefalsefalse
[1,2]“1,2”truefalsefalse
new String(“foo”)“foo”truefalsefalse
nullundefinedtruefalsefalse
nullfalsefalsefalsefalse
undefinedfalsefalsefalsefalse
{ foo: “bar” }{ foo: “bar” }falsefalsefalse
new String(“foo”)new String(“foo”)falsefalsefalse
0nullfalsefalsefalse
0NaNfalsefalsefalse
“foo”NaNfalsefalsefalse
NaNNaNfalsefalsetrue

加法

let obj = {};

{} + 1 // 1,这里的 {} 被当成了代码块 相当于 + 1
{ 1 + 1 } + 1 // 1

obj + 1 // [object Object]1
{} + {} // Chrome 上显示 "[object Object][object Object]",Firefox 显示 NaN

[] + {} // [object Object]
[] + a // [object Object]
+ [] // 等价于 + "" => 0
{} + [] // 0  {} 被当做代码块 相当于 + [] 
a + [] // [object Object]

[2,3] + [1,2] // '2,31,2'
[2] + 1 // '21'
[2] + (-1) // "2-1"

js在+运算的时候, 会先推断两个操作数是不是Number类型。 如果都是Number类型,则直接相加得出结果。 如果其中有一个操作数为String类型,则将另一个操作数隐式的转换为String,然后进行字符串拼接得出结果。

[]和{}转字符串的不同

String({}) // "[object Object]"
String([]) // ""

减法

// 减法或其他操作,无法进行字符串连接,因此在错误的字符串格式下返回 NaN
[2] - 1 // 1
[2,3] - 1 // NaN
{} - 1 // -1
### 《你知道JS》与《JS语言精粹》的内容区别 #### 内容侧重点 《你知道JS》更注重于JavaScript底层机制的解析,深入探讨了诸如作用域、闭包、原型链、类型转换以及异步编程等高级主题。它仅从语言设计层面解释这些特性的工作原理,还通过大量示例帮助读者理解如何在实际开发中规避陷阱并写出更健壮的代码。此书的目标是让开发者能够真正“掌握”JavaScript这门语言的核心思想[^1]。 相比之下,《JS语言精粹》则聚焦于提炼JavaScript中最精华的部分,并以简洁明快的方式呈现给读者。书中精选了一些关键概念如函数、对象模型、正则表达式和模块模式等,旨在引导开发者学习那些被证明为高效且实用的语言特性和最佳实践。由于其篇幅有限,该书没有对每个主题进行非常详尽地展开[^1]。 #### 难度层次与适用人群 《你知道JS》适合已经有一定基础并对JavaScript有较深兴趣的技术人员阅读。无论是希望深入理解语言本质的中级开发者还是追求极致性能优化的高级工程师都能从中受益匪浅。这本书鼓励读者挑战传统认知边界,去探索那些平时可能被忽略但至关重要的细节问题。 而《JS语言精粹》虽然也涉及到了一些复杂的知识点(比如闭包),但它整体上更适合初学者或希望快速提升编码技巧的人群使用。通过阅读本书可以迅速建立起对于JavaScript核心概念的基本认识框架,为进一步深入学习打下坚实的基础。 #### 更新程度与时代适应性 随着ECMAScript标准断演进,《你知道JS》系列也在持续更新中,涵盖了ES6/ES7等新版本引入的重要功能如箭头函数、let/const声明、类语法糖等。因此,在紧跟现代JavaScript发展趋势方面具有明显优势。 反观《JS语言精粹》,尽管它曾一度成为众多前端程序员案头必备的经典之作,但由于出版时间较早且后续修订较少,部分内容确实显得有些陈旧过时。例如关于变量作用域管理、模块化实现方式等方面未能充分反映近年来社区所采用的新方法论和技术栈变化。 ```javascript // 示例:利用闭包创建私有状态 function Counter() { let count = 0; return { increment: () => ++count, decrement: () => --count, getCount: () => count }; } const counter = Counter(); counter.increment(); console.log(counter.getCount()); // 输出 1 ```
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值