js变量 变量 在函数中,变量的主要作用是暂存业务处理过程中用到的一些值。JS 中的变量是使用 var 关键字来定义的,无论什么类型的变量都使用它来定义,因此 JS 是一种弱类型语言。但是,它的变量是区分大小写 的,也就是说red 、 Red、reD是三个不同的变量 。 JS中的变量早期要求必须是用_、“$”、英文字母和数字组成,而且第一个字符不可以是数字。对于现在的引擎来说,只要在词法解析的时候不引起误会就可以了,即使使用中文也是可以的。 以下是以下关键词: !Pasted image 20240414160948.png
操作符 js运算符 !Pasted image 20240414161414.png 操作符...的作用:
将参数转化为数组 function mailTo(...names){};
将数组转化为参数 Math.max(...[1,3,5]); !Pasted image 20240414161852.png
NaN NaN 是JavaScript中的一个特殊数值,代表“不是一个数字”(Not-a-Number)。它用于表示某些无法表示的数值结果,例如除以零、对负数开平方根等。以下是关于 NaN 的一些详细介绍:
产生NaN的情形
数学运算 :
除以零:0 / 0、Infinity / Infinity、Infinity / -Infinity等。
对负数开平方根:Math.sqrt(-1)。
无穷大减去无穷大:Infinity - Infinity。
类型转换 :
将非数字字符串转换为数字:Number("hello")、parseInt("hello")等。
不合理的运算 :
对一个非数字进行数学运算:"hello" * 5。
NaN的特性
不等于任何值 :NaN不等于任何值,包括它自己。例如,NaN === NaN的结果是false。这是因为NaN代表一个不确定的值,无法与任何具体值进行比较。
使用isNaN()函数检测 :可以使用isNaN()函数来检测一个值是否为NaN。例如,isNaN(NaN)返回true。不过,isNaN()函数有时会返回不准确的结果,因为它会先将参数转换为数字,然后再判断是否为NaN。例如,isNaN("hello")也会返回true,因为"hello"会被转换为NaN。
使用Number.isNaN()函数检测 :ES6引入了Number.isNaN()函数,用于更准确地检测一个值是否为NaN。例如,Number.isNaN(NaN)返回true,而Number.isNaN("hello")返回false。
传播性 :在涉及NaN的运算中,结果通常也是NaN。例如,NaN + 5、NaN * 10等运算的结果都是NaN。
示例 1 2 3 4 5 6 7 8 9 10 11 console .log (0 / 0 ); console .log (Math .sqrt (-1 )); console .log (Number ("hello" )); console .log ("hello" * 5 ); console .log (NaN === NaN ); console .log (isNaN (NaN )); console .log (isNaN ("hello" )); console .log (Number .isNaN (NaN )); console .log (Number .isNaN ("hello" )); console .log (NaN + 5 ); console .log (NaN * 10 );
NaN 在JavaScript中是一个重要的特殊值,了解其产生原因、特性以及检测方法,有助于避免在数值运算和类型转换中出现错误。
isNaN 在 JavaScript 中,isNaN 是一个用于检测值是否为 NaN(Not-a-Number) 的全局函数。由于 NaN 的特殊性(例如 NaN !== NaN),直接判断一个值是否是 NaN 需要借助工具函数。以下是 isNaN 的详细说明及注意事项:
一、isNaN 的基本行为
语法 :isNaN(value)
作用 :检测 value 是否是 NaN,或在转换为数值后是否为 NaN。
返回值 :布尔值(true 或 false)。
关键规则:
隐式类型转换 :isNaN 会先将参数转换为数值,再判断是否是 NaN。
NaN 的特殊性 :NaN 是唯一一个不等于自身的值(NaN !== NaN),因此需要 isNaN 辅助判断。
二、isNaN 的示例分析 1. 直接检测 NaN 1 2 isNaN (NaN ); isNaN (Number .NaN );
2. 数值类型 1 2 3 isNaN (123 ); isNaN (0 / 0 ); isNaN (Infinity );
3. 字符串 1 2 3 4 isNaN ("123" ); isNaN ("abc" ); isNaN ("" ); isNaN (" " );
4. 其他类型 1 2 3 4 5 6 isNaN (true ); isNaN (false ); isNaN (null ); isNaN (undefined ); isNaN ({}); isNaN ([1 , 2 ]);
三、isNaN 的陷阱 由于 isNaN 的隐式类型转换,某些情况下可能产生反直觉的结果:
示例: 1 2 3 4 5 6 isNaN ("123abc" ); isNaN (" 123 " ); isNaN (new Date ()); isNaN ([]); isNaN ([123 ]); isNaN ([NaN ]);
四、isNaN vs Number.isNaN
场景
isNaN 结果
Number.isNaN 结果
原因
isNaN(NaN)
true
true
直接检测 NaN
isNaN("abc")
true
false
字符串不是 NaN
isNaN(123)
false
false
数值有效
isNaN(undefined)
true
false
undefined 本身不是 NaN
isNaN("123")
false
false
字符串可转为数值,但非 NaN
示例: ES6 引入了更严格的 Number.isNaN,不会进行隐式类型转换 ,直接判断是否为 NaN:
1 2 3 Number .isNaN (NaN ); Number .isNaN ("abc" ); Number .isNaN (0 / 0 );
五、如何正确判断 NaN?
优先使用 Number.isNaN :避免隐式转换的副作用。
手动检查 :利用 NaN 的特性(NaN !== NaN):1 2 3 4 function isTrueNaN (value ) { return value !== value; } isTrueNaN (NaN );
六、总结
方法
特点
适用场景
isNaN
隐式类型转换后判断
需要兼容旧代码的宽泛检测
Number.isNaN
严格判断是否为 NaN
精确检测 NaN(推荐)
value !== value
直接利用 NaN 的特性
兼容性更好的替代方案
最佳实践
避免全局 isNaN :在 ES6+ 中优先使用 Number.isNaN。
显式类型转换 :若需要检测字符串是否为数值,应先显式转换:1 2 3 4 const str = "123" ;if (Number .isNaN (Number (str))) { console .log ("字符串无法转为数值" ); }
通过理解 isNaN 的隐式转换逻辑和 Number.isNaN 的严格性,可以更安全地处理 JavaScript 中的 NaN 检测。
变量提升 在 JavaScript 中,变量提升(Hoisting)是一个重要的概念,它指的是变量和函数声明会被提升到其所在作用域的顶部。这意味着你可以在声明变量或函数之前就使用它们,因为 JavaScript 引擎在执行代码之前会先处理这些声明。不过,需要注意的是,只有声明会被提升,而赋值操作不会被提升。
变量提升 声明提升 当使用 var 关键字声明变量时,变量的声明会被提升到函数作用域(如果在函数内)或全局作用域(如果在全局作用域内)的顶部。但是,变量的初始化(赋值)不会被提升。
1 2 3 console .log (x); var x = 5 ;console .log (x);
在这个例子中,变量 x 的声明被提升到了全局作用域的顶部,所以第一行 console.log(x) 不会抛出 ReferenceError。但是,由于赋值操作没有被提升,所以在声明和赋值之前访问 x 会得到 undefined。
函数声明提升 函数声明也会被提升,这意味着你可以在函数声明之前调用该函数。
1 2 3 4 console .log (sayHello ()); function sayHello ( ) { return "Hello" ; }
在这个例子中,函数 sayHello 的声明被提升到了全局作用域的顶部,所以可以在声明之前调用它。
函数表达式提升 函数表达式的行为与变量声明类似。函数表达式的声明会被提升,但赋值操作不会被提升。
1 2 3 4 console .log (sayHello ()); var sayHello = function ( ) { return "Hello" ; };
在这个例子中,变量 sayHello 的声明被提升,但赋值操作没有被提升。因此,在声明和赋值之前尝试调用 sayHello 会抛出 TypeError,因为此时 sayHello 是 undefined。
let 和 const 的提升与 var 不同,let 和 const 声明的变量也会被提升,但它们会被置于一个“暂时性死区”(Temporal Dead Zone, TDZ),这意味着在块的开始到变量声明之前,这些变量是不可访问的。
1 2 3 console .log (x); let x = 5 ;console .log (x);
在这个例子中,尽管 let 声明的变量 x 被提升了,但在声明之前访问 x 会抛出 ReferenceError,因为 x 处于暂时性死区。
总结
变量提升 :var 声明的变量会被提升到其所在作用域的顶部,但赋值操作不会被提升。
函数声明提升 :函数声明会被提升,可以在声明之前调用。
函数表达式提升 :函数表达式的声明会被提升,但赋值操作不会被提升。
let 和 const 提升 :let 和 const 声明的变量会被提升,但会处于暂时性死区,直到它们被声明。 理解变量提升有助于避免一些常见的错误,特别是在使用 var 声明变量时。使用 let 和 const 可以减少变量提升带来的问题,因为它们的提升行为更加严格。
实例 1 2 3 4 5 6 7 8 var foo = {n :1 };(function (foo ){ console .log (foo.n ); foo.n = 3 ; var foo = {n :2 }; console .log (foo.n ); })(foo); console .log (foo.n );
等价于:
1 2 3 4 5 6 7 8 9 10 11 12 13 var foo = { n : 1 }; (function (foo ) { var foo; console .log (foo.n ); foo.n = 3 ; foo = { n : 2 }; console .log (foo.n ); })(foo); console .log (foo.n );
let和`constlet 和 const 都是 ES6(ECMAScript 2015)引入的新关键字,用于声明变量,它们在很多方面都优于传统的 var 关键字。虽然它们在块级作用域、暂时性死区等方面有相似之处,但也存在一些关键区别。以下是 let 和 const 的主要区别:
1. 可变性
let :声明的变量可以重新赋值。
const :声明的变量必须初始化,并且一旦赋值后就不能再被重新赋值。
示例 1 2 3 4 5 6 let x = 5 ;x = 10 ; console .log (x); const y = 5 ;y = 10 ; console .log (y);
2. 初始化要求
let :声明的变量可以不立即初始化,但可以在后续的代码中赋值。
const :声明的变量必须在声明时立即初始化。
示例 1 2 3 4 let z; z = 15 ; console .log (z); const w;
3. 适用场景
let :适用于需要在块级作用域内重新赋值的变量,比如循环计数器、临时变量等。
const :适用于不需要重新赋值的常量,比如配置项、常量值、函数和对象引用等。即使使用 const 声明的对象,对象的属性仍然可以被修改,只是对象引用本身不能被重新赋值。
示例 1 2 3 4 5 6 7 8 9 10 11 12 13 14 for (let i = 0 ; i < 5 ; i++) { console .log (i); } console .log (i); const person = { name : 'Kimi' , age : 25 }; person.age = 26 ; console .log (person); person = { name : 'Moonshot' , age : 30 };
4. 作用域
let 和 const 都具有块级作用域,这意味着它们只在声明它们的块({ ... })内有效。这与 var 的函数级作用域或全局作用域不同。
示例 1 2 3 4 5 6 if (true ) { let a = 1 ; const b = 2 ; } console .log (a); console .log (b);
5. 暂时性死区(Temporal Dead Zone, TDZ)
let 和 const 都会提升到块的顶部,但它们在声明之前处于暂时性死区,这意味着在声明之前访问它们会抛出 ReferenceError。
var 也会提升,但提升后的值是 undefined,而不是进入暂时性死区。
示例 1 2 3 4 console .log (a); let a = 5 ;console .log (b); const b = 10 ;
总结
let :适用于需要在块级作用域内重新赋值的变量。
const :适用于不需要重新赋值的常量,有助于代码的可读性和维护性。 在实际开发中,推荐尽可能使用 const 声明变量,除非确实需要重新赋值,再使用 let。这样可以减少变量被意外修改的风险,提高代码的健壮性。
实例
1 2 3 4 5 6 7 var a = 1 ;function test ( ){ console .log (a); class a {} } test ();