Skip to content

JavaScript 基础语法

1. 变量

  • JavaScript 的变量名区分大小写Aa是两个不同的变量。
  • 如果只是声明变量而没有赋值,则该变量的值是undefinedundefined是一个特殊的值,表示“无定义”。
  • JavaScript 是一种动态类型语言,也就是说,变量的类型没有限制,变量可以随时更改类型。
  • 如果使用var重新声明一个已经存在的变量,是无效的。(如果第二次声明的时候还进行了赋值,则会覆盖掉前面的值。)
  • 变量提升:JavaScript 引擎的工作方式是,先解析代码,获取所有被声明的变量,然后再一行一行地运行。这造成的结果,就是所有的变量的声明语句,都会被提升到代码的头部,这就叫做变量提升(hoisting)。

2. 注释

  • JavaScript 提供两种注释的写法:一种是单行注释,用//起头;另一种是多行注释,放在/**/之间。
  • 此外,由于历史上 JavaScript 可以兼容 HTML 代码的注释,所以<!---->也被视为合法的单行注释。(需要注意的是,-->只有在行首,才会被当成单行注释,否则会当作正常的运算。)

3. 数据类型

  • 数值(number):整数和小数(比如 1 和 3.14)。
  • 字符串(string):文本(比如 Hello World)。
  • 布尔值(boolean):表示真伪的两个特殊值,即true(真)和false(假)。
  • undefined:表示“未定义”或不存在,即由于目前没有定义,所以此处暂时没有任何值。
  • null:表示空值,即此处的值为空。
  • 对象(object):各种值组成的集合。
    • 狭义的对象(object)
    • 数组(array)
    • 函数(function)

3.1 typeof 运算符

JavaScript 有三种方法,可以确定一个值到底是什么类型。

  • typeof运算符
  • instanceof运算符
  • Object.prototype.toString方法

typeof 运算符可以返回一个值的数据类型。
数值、字符串、布尔值分别返回 number、string、boolean。

javascript
typeof 123 // "number"
typeof '123' // "string"
typeof false // "boolean"

function f() {}
typeof f
// "function"

typeof undefined
// "undefined"

typeof window // "object"
typeof {} // "object"
typeof [] // "object"

typeof null // "object"
  • 空数组([])的类型也是 object
  • instanceof 运算符可以区分数组和对象。
  • null 的类型是 object,这是由于历史原因造成的。

3.2 null 和 undefined

  • nullundefined都可以表示“没有”,含义非常相似。将一个变量赋值为undefinednull,老实说,语法效果几乎没区别。
  • if 语句中,它们都会被自动转为 false,相等运算符(==)甚至直接报告两者相等。
  • 区别是这样的:null是一个表示“空”的对象,转为数值时为 0;undefined是一个表示“此处无定义”的原始值,转为数值时为NaN
  • 判断:使用 === 进行判断。
javascript
// 变量声明了,但没有赋值
var i;
i // undefined

// 调用函数时,应该提供的参数没有提供,该参数等于 undefined
function f(x) {
  return x;
}
f() // undefined

// 对象没有赋值的属性
var  o = new Object();
o.p // undefined

// 函数没有返回值时,默认返回 undefined
function f() {}
f() // undefined

3.3 布尔值

如果 JavaScript 预期某个位置应该是布尔值,会将该位置上现有的值自动转为布尔值。转换规则是除了下面六个值被转为false,其它值都视为true

js
undefined
null
false
0
NaN
""          // 空字符串
''          // 空字符串
  • 注意,空数组([])和空对象({})对应的布尔值,都是 true
  • 判断:使用 === 进行判断;if (x === true) {}

3.4 整数和浮点数

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

javascript
1 === 1.0 // true

0.1 + 0.2 === 0.3
// false

0.3 / 0.1
// 2.9999999999999996

(0.3 - 0.2) === (0.2 - 0.1)
// false

3.5 数值精度

根据国际标准 IEEE 754,JavaScript 浮点数的64个二进制位,从最左边开始,是这样组成的。

  • 第1位:符号位,0表示正数,1表示负数
  • 第2位到第12位(共11位):指数部分
  • 第13位到第64位(共52位):小数部分(即有效数字)

符号位决定了一个数的正负,指数部分决定了数值的大小,小数部分决定了数值的精度。
精度最多只能到53个二进制位,这意味着,绝对值小于2的53次方的整数,即-253到253,都可以精确表示。

3.6 数值范围

  • 如果一个数大于等于2的1024次方,那么就会发生“正向溢出”,即 JavaScript 无法表示这么大的数,这时就会返回Infinity
  • 如果一个数小于等于2的-1075次方(指数部分最小值-1023,再加上小数部分的52位),那么就会发生为“负向溢出”,即 JavaScript 无法表示这么小的数,这时会直接返回0。

3.7 NaN

javascript
5 - 'x' // NaN
0 / 0 // NaN
typeof NaN // 'number'
NaN === NaN // false

NaN是 JavaScript 的特殊值,表示“非数字”(Not a Number),主要出现在将字符串解析成数字出错的场合。

  • 0 除以 0 也会得到 NaN
  • 它的数据类型依然属于 Number
  • NaN 不等于任何值,包括它本身
  • NaN 在布尔运算时被当作false
  • NaN 与任何数(包括它自己)的运算,得到的都是 NaN

3.8 Infinity

Infinity有正负之分,Infinity表示正的无穷,-Infinity表示负的无穷。

javascript
// 场景一
Math.pow(2, 1024)
// Infinity

// 场景二
0 / 0 // NaN
1 / 0 // Infinity

Infinity === -Infinity // false

1 / -0 // -Infinity
-1 / -0 // Infinity

Infinity > 1000 // true
-Infinity < -1000 // true

Infinity > NaN // false
-Infinity > NaN // false

Infinity < NaN // false
-Infinity < NaN // false
  • Infinity 大于一切数值(除了 NaN),-Infinity 小于一切数值(除了 NaN)。
  • Infinity 与 NaN 比较,总是返回 false

3.9 与数值相关的全局方法

  • parseInt() 用于将字符串转为整数。还可以用于进制转换。
  • parseFloat() 用于将一个字符串转为浮点数。
  • isNaN() 用来判断一个值是否为 NaN。
  • isFinite() 返回一个布尔值,表示某个值是否为正常的数值。

3.10 字符串

字符串可以包含在单引号、双引号或反引号中。

  • 由于 HTML 语言的属性值使用双引号,所以很多项目约定 JavaScript 语言的字符串只使用单引号
  • 连接运算符(+)可以连接多个单行字符串,将长字符串拆成多行书写,输出的时候也是单行
  • 字符串可以被视为字符数组,因此可以使用数组的方括号运算符,用来返回某个位置的字符(位置编号从0开始)
  • length 属性返回字符串的长度,该属性也是无法改变的。比如:s.length
  • es6 新增模板字符串,在反引号 `` 内书写,需要拼接的内容用$()包裹

3.11 Base64 转码

JavaScript 原生提供两个 Base64 相关的方法。

  • btoa():任意值转为 Base64 编码
  • atob():Base64 编码转为原来的值

要将非 ASCII 码字符转为 Base64 编码,必须中间插入一个转码环节,再使用这两个方法。

javascript
function b64Encode(str) {
  return btoa(encodeURIComponent(str));
}

function b64Decode(str) {
  return decodeURIComponent(atob(str));
}

b64Encode('你好') // "JUU0JUJEJUEwJUU1JUE1JUJE"
b64Decode('JUU0JUJEJUEwJUU1JUE1JUJE') // "你好"

3.12 数组

  • 索引/下标从 0 开始
  • 数组的深拷贝建议使用 JSON.stringifyJSON.parse
    js
    const arr2 = JSON.parse(JSON.stringify(arr1));
  • 数组的遍历:点击查看详情
    1. forEach 方法
    2. for 语句
    3. for...of 语句

3.13 对象

对象(object)是 JavaScript 语言的核心概念,也是最重要的数据类型。 简单说,对象就是一组“键值对”(key-value)的集合,是一种无序的复合数据集合。

  • 对象的所有键名都是字符串(ES6 又引入了 Symbol 值也可以作为键名),所以加不加引号都可以。
  • 如果键名是数值,会被自动转为字符串。
  • 对象的每一个键名又称为“属性”(property),它的“键值”可以是任何数据类型。可以是函数
  • 读取对象的属性,有两种方法,一种是使用点运算符,还有一种是使用方括号运算符。
  • 点运算符和方括号运算符,不仅可以用来读取值,还可以用来赋值。
  • 查看一个对象本身的所有属性,可以使用Object.keys方法。Object.keys(obj);
  • 属性的删除:delete 命令 delete obj.p // true
    • 注意,删除一个不存在的属性,delete 不报错,而且返回 true。
  • 属性是否存在:in 运算符 if ('toString' in obj) {}
    • in运算符的一个问题是,它不能识别哪些属性是对象自身的,哪些属性是继承的。
    • 可以使用对象的hasOwnProperty方法判断一下,是否为对象自身的属性。
  • 属性的遍历:for...in 循环 for (var p in obj) {}

4. 运算

4.1 算术运算符

加 + 减 - 乘 * 除 / 取余 % 自增 ++ 自减 --

4.2 赋值运算符

= += -= *= /= %=

4.3 比较运算符

  • 等于 == 不等于 != 大于 > 小于 < 大于等于 >= 小于等于 <=
  • 绝对等于 === 值和类型均相等
  • 不绝对等于 !== 值和类型有一个不相等,或两个都不相等

4.4 逻辑运算符

与 && 或 || 非 !

5. 条件语句

JavaScript 提供if结构和switch结构,完成条件判断,即只有满足预设的条件,才会执行相应的语句。

5.1 if 语句

javascript
if (m === 3) {
  m += 1;
}

if (m === 0) {
  // ...
} else if (m === 1) {
  // ...
} else if (m === 2) {
  // ...
} else {
  // ...
}

5.2 switch 语句

javascript
switch (fruit) {
  case "banana":
    // ...
    break;
  case "apple":
    // ...
    break;
  default:
    // ...
}
  • 每个case 代码块内部的break语句不能少,否则会接下去执行下一个 case 代码块,而不是跳出 switch 结构。
  • switch 语句后面的表达式,与 case 语句后面的表示式比较运行结果时,采用的是严格相等运算符(===),而不是相等运算符(==),这意味着比较时不会发生类型转换。

5.3 三元运算符 ?:

javascript
// (条件) ? 表达式1 : 表达式2
var even = (n % 2 === 0) ? true : false;

6. 循环语句

https://developer.mozilla.org/zh-CN/docs/Web/JavaScript/Guide/Loops_and_iteration

循环语句用于重复执行某个操作,它有多种形式。

6.1 while 循环

javascript
while (条件) {
  语句;
}

var i = 0;
while (i < 100) {
  console.log('i 当前为:' + i);
  i = i + 1;
}
  • while 语句的循环条件是一个表达式,必须放在圆括号中。

6.2 for 循环

javascript
for (初始化表达式; 条件; 递增表达式) {
  语句
}

var x = 3;
for (var i = 0; i < x; i++) {
  console.log(i);
}
  • for 语句的三个部分(initialize、test、increment),可以省略任何一个,也可以全部省略。

6.3 do...while 循环

javascript
do {
  语句
} while (条件);

var x = 3;
var i = 0;
do {
  console.log(i);
  i++;
} while(i < x);
  • 不管条件是否为真,do...while 循环至少运行一次,这是这种结构最大的特点。
  • 另外,while 语句后面的分号注意不要省略。

6.4 break 语句和 continue 语句

  • break语句用于跳出代码块或循环。
  • continue语句用于立即终止本轮循环,返回循环结构的头部,开始下一轮循环。

6.5 for...in 语句

  • for...in 语句循环一个指定的变量来循环一个对象所有可枚举的属性。
js
let arr = ['a', 'b', 'c']
let obj = {'k1': 'v1', 'k2': 'v2', 'k3': 'v3'}

for (let i in arr) {
  console.log(i)        // 数组遍历的是下标:0 1 2
}

for (let i in obj) {
  console.log(i)        // 对象遍历的是它的 key:k1 k2 k3
}
  • 最好不用 for...in 语句来遍历数组,因为它会遍历除了数字索引外,还有可能遍历你自定义的属性名字。

6.6 for...of 语句

  • for...of 语句用于遍历可迭代对象(不包含 object 类型)的值。
js
let arr = ['a', 'b', 'c']
let obj = {'k1': 'v1', 'k2': 'v2', 'k3': 'v3'}

for (let i of arr) {
  console.log(i)        // a b c
}

for (let i of obj) {
  console.log(i)        // 报错:TypeError: obj is not iterable
}

7. 函数

js
function test()
{
    // 执行代码
}