🗝 JavaScript 变量与数据类型
# JavaScript 变量
# 字面量
一些固定的值,不可以改变。很少使用,例如:
1 2 3 4 true false null NaN "string"
# 变量
用来保存任意的字面量。一般通过变量使用字面量,描述字面量。
声明变量的方法: var
。
在新版标准的 JavaScript 中,不再建议使用 var
。
使用 let
关键字声明变量,例如 let message
。
一次声明多个变量:
let user = 'John', age = 25, message = 'Hello';
1
2
3
变量的修改:
let message; message = 'Hello!'; message = 'World!'; alert(message);
1
2
3
4
5变量的拷贝:
let hello = 'Hello world!'; let message; // 将字符串 'Hello world' 从变量 hello 拷贝到 message message = hello; // 现在两个变量保存着相同的数据 alert(hello); // Hello world! alert(message); // Hello world!
1
2
3
4
5
6
7
8
9但是一个变量只能被
let
声明一次,之后在不使用let
的情况下对其引用,下面是错误的例子:let message = "This"; // 重复 'let' 会导致 error let message = "That"; // SyntaxError: 'message' has already been declared
1
2
3
4通常需要在使用一个变量前定义它。但是在早期,我们可以不使用最好每次要使用变量之前都提前声明,以免造成不必要的出错。let
进行变量声明,而可以简单地通过赋值来创建一个变量。现在如果我们不在脚本中使用use strict
声明启用严格模式,这仍然可以正常工作,这是为了保持对旧脚本的兼容。
# 标识符
JavaScript 中可以自主命名的内容。比如:变量名、函数名、属性名。
标识符应该遵守规范:
- 标识符中可以含有字母、数字、
_
、$
; - 标识符不能以数字开头;
- 标识符不能是 JavaScript 中的关键字和保留字;(保留字请可参看上一节笔记)
- 标识符如果包含多个单词一般采用驼峰命名法;
# 常量
声明一个常数(不变)变量,可以使用 const
关键字,例如: const myBirthday = '18.04.1982';
。使用 const
声明的变量称为「常量」。它们不能被修改,如果你尝试修改就会发现报错。
如果是需要将常量用作别名,以便记住那些在执行之前就已知的难以记住的值。使用大写字母和下划线来命名这些常量。例如:
const COLOR_RED = "#F00"; const COLOR_GREEN = "#0F0"; const COLOR_BLUE = "#00F"; const COLOR_ORANGE = "#FF7F00"; // ……当我们需要选择一个颜色 let color = COLOR_ORANGE; alert(color); // #FF7F00
1
2
3
4
5
6
7
8大写命名的常量仅用作「硬编码(hard-coded)」值的别名。
而常规命名的常量,可能是在执行期间被「计算」出来,但初始赋值之后就不会改变,例如:
const pageLoadTime = /* 网页加载所需的时间 */;
1pageLoadTime
的值在页面加载之前是未知的,所以采用常规命名。但是它仍然是个常量,因为赋值之后不会改变。
# 命名规范
一个变量名应该有一个清晰、明显的含义,对其存储的数据进行描述。
可以遵循的一个规则:
- 使用易读的命名,比如
userName
或者shoppingCart
。 - 远离缩写和短名称!
- 变量名在能够准确描述变量的同时要足够简洁。不好的例子就是
data
和value
,这样的名称等于什么都没说。如果能够非常明显地从上下文知道数据和值所表达的含义,这样使用它们也是可以的。 - 脑海中的术语要和团队保持一致。如果网站的访客称为「用户」,则我们采用相关的变量命名,比如
currentUser
或者newUser
,而不要使用currentVisitor
或者一个newManInTown
。
# JavaScript 数据类型
JavaScript 中的值都具有特定的类型。我们可以将任何类型的值存入变量。例如,一个变量可以在前一刻是个字符串,下一刻就存储一个数字。
JavaScript 是动态类型的编程语言,意思是虽然编程语言中有不同的数据类型,但是你定义的变量并不会在定义后,被限制为某一数据类型。
# 基本数据类型
JavaScript 中有 5 个基本数据类型以及对象 object
类型:
🌟 ES6 新增 symbol
和 bigInt
数据类型;所以共计为 8 种基本的数据类型(7 种原始类型和 1 种引用类型)。
# String
字符串
JavaScript 中的字符串是引号中的任意文本。可以使用单引号或双引号。最近的 JavaScript 版本中添加使用反引号 ``
,它们允许我们通过将变量和表达式包装在 ${…}
中,来将它们嵌入到字符串中。。
let str = "Hello";
let str2 = 'Single quotes are ok too';
let phrase = `can embed another ${str}`;
2
3
反引号相关:
${…}
内的表达式会被计算,计算结果会成为字符串的一部分。可以在${…}
内放置任何东西:诸如名为name
的变量,或者诸如1 + 2
的算数表达式,或者其他一些更复杂的。- 这仅仅在反引号内有效,其他引号不允许这种嵌入。
在 JavaScript 中没有这种类型。只有一种 string
类型,一个字符串可以包含零个(为空)、一个或多个字符。例如:
let str = ''
# Number
数值
所有的整数和浮点数都是 Number
类型;
// 最大表示的数值
Number.MAX_VALUE= 1.7976931348623157e+308
// 特殊的数值
a = Infinity // 正无穷
a = -Infinity // 负无穷
NaN // 非法数值
0b... // 表示二进制数值
0... // 表示八进制数值
0x... // 表示十六进制数值
2
3
4
5
6
7
8
9
10
数字可以有很多操作,比如,乘法 *
、除法 /
、加法 +
、减法 -
等等。下一节运算符有介绍。
在 JavaScript 中做数学运算是安全的,可以进行任何的数学运算包括除以 0,将非数字字符串视为数字,等等。脚本永远不会因为一个致命的错误(“死亡”)而停止。最坏的情况下,会得到 NaN
的结果。
特殊的数值:
Infinity
代表无穷大 (opens new window) ∞。是一个比任何数字都大的特殊值。可以通过除以 0 来得到它。或者在代码中直接使用
Infinity
。NaN
代表一个计算错误。它是一个不正确的或者一个未定义的数学操作所得到的结果。NaN
是粘性的,任何对NaN
的进一步数学运算都会返回NaN
。所以,如果在数学表达式中有一个NaN
,会被传播到最终结果(只有一个例外:NaN ** 0
结果为1
)。
# BigInt
类型
在 JavaScript 中, Number
类型无法表示大于 (2^53-1)
(即 9007199254740991
),或小于 -(2^53-1)
的整数。这是其内部表示形式导致的技术限制。
BigInt
类型是最近被添加到 JavaScript 语言中的,用于表示任意长度的整数。用于需要很大的数字,例如用于加密或微秒精度的时间戳。
可以通过将
n
附加到整数字段的末尾来创建BigInt
值,例如:// 尾部的 "n" 表示这是一个 BigInt 类型 const bigInt = 1234567890123456789012345678901234567890n;
1
2
# Boolean
布尔值
用于逻辑的判断,只有两个值: true
或。 false
。
# Undefined
未定义
声明一个变量但没有赋值,此时变量的值为 undefined
. 特殊值 undefined
和 null
一样自成类型。从技术上讲,可以显式地将 undefined
赋值给变量:
let age = 100;
// 将值修改为 undefined
age = undefined; // 不建议
2
3
4
通常,使用 null
将一个「空」或者「未知」的值写入变量中,而 undefined
则保留作为未进行初始化的事物的默认初始值,所以不显示赋值也会自动为 undefined
。
# Null
空值
特殊的 null
值不属于上述任何一种类型。表示空的对象。使用 typeof
会返回 object
;
JavaScript 中的 null
不是一个「对不存在的 object
的引用」或者 「null 指针」。JavaScript 中的 null
仅仅是一个代表「无」、「空」或「值未知」的特殊值。
例如:
let age = null;
# 引用(对象)类型
object
类型是一个特殊的类型。其他所有的数据类型都被称为「原始类型」,因为它们的值只包含一个单独的内容(字符串、数字或者其他)。相反, object
则用于储存数据集合和更复杂的实体。
Object
:任意对象。
Function
:函数对象,是特殊的可以执行的对象。
Array
:数组对象(内部数据有序)
# 数据类型的判断
typeof
返回一个字符串(开头小写),表示未经计算的操作数的类型。当我们想要分别处理不同类型值的时候,或者想快速进行数据类型检验时,非常有用。- 可以判断:
undefined
, 数值,字符串,布尔值,function
- ⭐️ 不能判断:
null
与object
,object
与array
(明确区分)
- 可以判断:
typeof undefined // "undefined"
typeof 0 // "number"
typeof 10n // "bigint"
typeof true // "boolean"
typeof "foo" // "string"
typeof Symbol("id") // "symbol"
typeof Math // "object" (1)
typeof null // "object" (2)
typeof alert // "function" (3)
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
- 关于
null
: 这是官方承认的typeof
的错误,这个问题来自于 JavaScript 语言的早期阶段,并为了兼容性而保留了下来。null
绝对不是一个object
。null
有自己的类型,它是一个特殊值。typeof
的行为在这里是错误的。
var a
console.log(a, typeof a, typeof a === 'undefined', a === undefined)
// undefined 'undefined' true true
2
3
instanceof()
: 专门判断对象的具体类型。
var b1 = {
b2 : [1, 'abc', console.log],
b3: function () {
console.log('b3')
return function(){
return 'testFunction'
}
}
}
console.log(b1 instanceof Object, b1 instanceof Array) // true false
console.log(b1.b2 instanceof Array, b1.b2 instanceof Object) // true true
console.log(b1.b3 instanceof Function, b1.b3 instanceof Object) // true true
console.log(typeof b1.b3 === 'function') // true
console.log(typeof b1.b2[2] === 'function') // true
b1.b2[2](4) // 函数用加括号可以调用(表达式)
console.log(b1.b3()()) // b3 // testFunction
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
===
全等:可以判断undefined
/null
var a
a = null
console.log(typeof a, a===null) // object true
2
3
# 数据类型的转换
# 转换为字符串 String
- 调用被转换数据的
toString()
方法(强制类型转换);
var a = 123;
a = a.toString();
console.log(typeof(a)); // string
2
3
注:不适用于 null
和 undefined
;
- 调用
String()
方法(强制类型转换):
var a = 123;
a = String(a);
2
注:对于 null
值,直接转换为字符串 "null"
,对于 undefined
直接转换为字符串 "undefined"
;
- 添加空字符串:为任意的数据类型 +
“”
(隐式类型转换):
var a = true;
a = a + "";
console.log(typeof(a)); // string
2
3
# 转换为数字类型 Number
- 调用转换函数
Number()
(强制类型转换):
var s = "123";
s = Number(s);
2
转换的情况:
- 字符串 => 数字
如果字符串是一个合法的数字,则直接转换为对应的数字
如果字符串是一个非法的数字,则转换为NaN
如果是一个空串或纯空格的字符串,则转换为0
- 布尔值 => 数字
true
转换为1
false
转换为0
- 空值 => 数字
null
转换为0
- 未定义 => 数字
undefined
转换为NaN
2️⃣ 调用转换方法
parseInt()
或parseFloat()
(强制类型转换):对于非完全数字的字符回将有效的数值为转换为相应的
Number
:var a = "3.14159 px"; b = parseInt(a); console.log(b); // 3 c = parseFloat(a); console.log(c); // 3.14159
1
2
3
4
5
63️⃣ 使用一元
+
(隐式类型转换):原理与使用
Number()
相同。var a = "123"; a =+a;
1
2
# 转换为布尔值 Boolean
:
- 使用
Boolean()
函数 (强制类型转换):
var s = 'false';
s = Boolean(s);
console.log(s); // true
2
3
转换的情况:
字符串 => 布尔:
除了空串其余全是true
;数值 => 布尔:
除了0
和NaN
其余的全是true
;
null、undefined
=> 布尔:
都是false
对象 => 布尔:
都是true
- 隐式类型转换:
为任意的数据类型做两次非运算,即可将其转换为布尔值;
var a = "hello";
a = !!a; // true
2
- 符号串的对比
Javascript 字符串在进行大于 (小于) 比较时,会根据第一个不同的字符的 ASCII 值码进行比较,当数字与字符串进行比较大小时,会强制的将数字转换成字符串然后再进行比较:
console.log('13'>'3'); // 输出:false
console.log(5>'6'); // 输出: false
console.log('d'>'ABDC') // 输出: true
console.log(19>'ssf') // 输出 false
console.log('A'>'abcdef') // 输出 false
2
3
4
5
手动转换为 ASCII 码,用正负数表示大小:
sorter={(a:string,b:string)=> a.charCodeAt()-b.charCodeAt()}
# 相关问题
undefined
和null
的区别:
undefined
代表声明了变量但是没有赋值;
null
代表声明并且赋值了变量,值为 null
;
将变量赋值为
null
的情况:- 初始赋值,表明要赋值为对象,用作占位符。
- 结束前,使对象成为垃圾对象。(使用垃圾回收器回收)
var a = null; // 初始化,null作占位符 a = ['test',123]; // 确定为对象时,赋值 // ... a = null; // 最后回收对象
1
2
3
4严格区分变量类型和数据类型:
- 数据的类型:基本类型与对象类型
- 变量的类型(变量内存值的类型)
- 基本类型:保存就是基本类型的数据
- 引用类型:保存的是地址值(对象类型)
基本数据类型的数据,变量是直接保存的它的值。
变量与变量之间是互相独立的,修改一个变量不会影响其他的变量。引用数据类型的数据,变量是保存的对象的引用(内存地址)。
如果多个变量指向的是同一个对象,此时修改一个变量的属性,会影响其他的变量。比较两个变量时,对于基本数据类型,比较的就是值,对于引用数据类型,比较的是地址,地址相同才相同;
# JavaScript 数组
数组对象的作用是:使用单独的变量名来存储一系列的有序的值。
- 数组可以用一个变量名存储所有的值,并且可以用变量名访问任何一个值。
- 数组中的每个元素都有自己的的标识,以便它可以很容易地被访问到。
# 创建数组
常规方法: new
var myCars = new Array();
myCars[0] = "Saab"
myCars[1] = "Volvo"
myCars[2] = "BMW"
2
3
4
简洁方法:
var Cars = new Array("Saab", "Volvo", "BMW")
字面:
var myCars = ["Saab","Volvo","BMW"]
# 访问数组
访问数组可以通过指定数组名或者索引,访问某个特定的值。
获取值:
var carName = myCars[0]
1修改值:
myCars[0] = "TOYOTA"
1
# 特殊的数组
在 JavaScript 中,所有的变量都是对象,数组中可以有不同的变量类型,即数组可以包含对象元素、函数、数组:
myArray[0]=Date.now
myArray[1]=myFunction
myArray[2]=myCars
2
3
# 数组方法与属性
📃 相关参考:数组 - 学习 Web 开发 | MDN (mozilla.org) (opens new window) | JavaScript Array 对象 | 菜鸟教程 (runoob.com) (opens new window)