这篇笔记的内容对应的是《JavaScript高级程序设计(第三版)》中的第三章。

1.语法

1-1 区分大小写

ECMAScript 中的一切都是区分大小写的。

  • testTest 首字母不同,那么它们就不相同
  • typeoftypeOf 中间有个字母大小写不同,那么它们也不相同

1-2 标识符

认识标识符

  1. 标识符的作用:用于变量、函数名、属性名、函数的参数
  2. 标识符的规则:
1. 第一个字符必须是字母、下划线(_)或美元符($)
2. 其他字符可以是字母、数字、下划线或美元符

注:
1. ECMAScript 标识符一般采用驼峰方式定义,即第一个字母小写,剩下每个有意义的单词首字母大写(不是强制规定)
2. 不能使用关键字、保留字、true、false 和 null 作为标识符(强制规定)

思考:可不可以使用 undefined 作为标识符?

使用 var 来定义变量的时候不可以:

var undefined = 123;
console.log(undefined); // undefined

使用 const 或 let 定义变量的时候可以:

let undefined = 123;
console.log(undefined); // 123

结论:尽量不要使用 undefined 作为标识符

1-3 注释

注释的方式有两种:

  1. 单行注释
  2. 多行注释
// 单行注释
/**
 * 多行注释
 */

1-4 严格模式

ECMAScript5 中引入了严格模式的概念。

  1. 严格模式的作用:为 JavaScript 定义一种不同的解析与执行模型
  2. 严格模式的启用:在文件中定义一个编译指令 "use strict";

严格模式可以在文件中使用,也可以在函数中使用。如果要在整个文件中使用严格模式,就要在文件顶部添加编译指令;如果要让函数在严格模式下执行,要在函数体中增加编译指令。

"use strict";

// js文件中的其他代码
function func(){
  "use strict";
  // 函数体
}

1-5 语句

语句一般以分号结尾。

var num = 123;

结尾分号不是必须的,如果没有分号,以解析器确定语句的结尾。

var num = 123

语句结尾手动增加分号的好处:

  1. 提高代码的性能(解析器不需要推测在哪里需要插入分号)
  2. 避免一些不必要的错误(如代码压缩时出错)

推荐语句的结尾使用分号

2.关键字和保留字

关键字在 ECMA-262 中具有特定的用途,一般用于:

  1. 用于控制语句的开始或结束
  2. 用于执行特定的操作等

ECMA-262 中的关键字如下:

break do instanceof typeof case
else new var catch finally
return void continue for switch
while debugger function this with
default if throw delete in
try

ECMA-262 中的保留字没有任何意义,但是以后有可能被用作关键字:

abstract boolean byte char class
const debugger double enum export
extends final float goto implements
import int interface long native
package private protected public short
static super synchronized throws transient
volatile let yield

关键字和保留字不能用作标识符

3.变量

ECMAScript 中定义变量的方式,var 操作符后面跟上变量名,如 var num;

ECMAScript 每个变量仅仅是一个用来保存值的占位符而已,ECMAScript 中的变量可以保存任意类型的值:

var num = 123; // 定义一个变量,初始值为数字
num = '123'; // 更改变量的值,这个时候数值类型为字符串

不建议修改变量所保存的值的类型

如果变量在声明的时候,没有指定初始值,会保存一个特殊的值 undefined

var num;
console.log(num); // undefined

一条语句可以定义多个变量,但是要使用逗号操作符分割:

var num = 123, 
    str = 'test', 
    flag = true;

注意:严格模式下,不能定义名字为 eval 或 arguments 的变量,否则会报错。

'use strict';

var arguments = 123;
console.log(arguments);

会报出下面的错误:

SyntaxError: Unexpected eval or arguments in strict mode

分析:定义变量并结合作用域

在函数内部通过 var 定义的变量,在函数外部不能访问。

function func() {
  var name = 'wang'; // 这是一个局部变量,当函数执行结束的时候,该变量会被销毁
}
func();
console.log(name); // ReferenceError: name is not defined

如果在函数内部定义变量的时候不使用 var 关键字,那么就会默认定义的是一个全局变量。

function func() {
  name = 'wang';
}
func();
console.log(name); // 'wang'

上面的代码和下面的代码等价,因为发生了变量声明提升:

var name;
function func() {
  name = 'wang';
}
func();
console.log(name); // 'wang'

4.数据类型

ECMAScript 中有 5 种简单的数据类型和 1 种复杂的数据类型。

  • 简单数据类型:Undefined Null Boolean Number String
  • 复杂数据类型:Object

4-1 typeof 操作符

typeof 是一个操作符,不是一个函数,虽然在判断数据类型的时候可以写成 typeof(123),但是括号不是必须的。

typeof 123
typeof(123)

使用 typeof 操作符,返回值是下面值中的一个:

  • undefined : 值未定义
var arg1;
var arg2 = undefined;
var arg3 = void 0;
  • boolean : 值是布尔值
var arg1 = true;
var arg2 = false;
  • string : 值是字符串
var arg1 = '';
var arg2 = 'false';
  • number : 值是数值
var arg1 = 123;
  • object : 值是对象或 null
var arg1 = new Object();
var arg2 = null;
  • function : 值是函数
function func() {}
console.log(typeof func); // function

注意:typeof 操作符后面的内容可以是变量,也可以是字面量。

var str = 'test';
console.log(typeof str); // 变量
console.log(typeof 'test'); // 字面量

4-2 Undefined 类型

Undefined 类型中只有一个值:undefined。Undefined 类型存在的作用就是比较。无论什么情况下,都没有必要把一个变量的值,显示指定为 undefined

变量在声明的时候没有初始化,那么默认该变量的值就是 undefined

var arg;
console.log(arg === undefined); // true

尚未声明的变量,只能执行一项操作,就是检测该变量的数据类型。

console.log(typeof name); // undefined

由于声明为初始化和未声明的变量,通过 typeof 操作符得到的结果相同,因此在变量初始的时候,一般给其赋初始值,这样,在使用 typeof 操作符的时候,就能判断该变量是不是未声明的变量。

4-3 Null 类型

Null 类型中只有一个值:nullnull 表示的是空对象指针,因此,使用 typeof 操作符得到的结果是 object

var arg = null;
console.log(arg); // null

如果定义的变量,将来用来保存对象,那么就在定义的时候,初始化为 null

var obj = null; // 保存对象的引用

undefined 派生自 null,因此,在相等测试中返回 true

console.log(null == undefined); // true

4-4 Boolean 类型

Boolean 类型中有两个值:truefalse

Boolean 可以将其他数据类型转成 Boolean 类型,转换规则如下:

数据类型 true false
Boolean true false
String 任意非空字符串 ""(空字符串)
Number 任意非零数字 0和NaN
Object 任意对象 null
Undefined 不适用 undefined

使用方式:

Boolean('string') // true

在流程控制语句中,会自动执行 Boolean 进行转换:

var str = 'test';
if(str){ // 相当胡 if(Boolean(str)){
  console.log(123)
}

4-5 Number 类型

Number 类型使用 IEEE754 来表示整数和浮点数。

认识不同的进制:

  1. 十进制:0-9表示,逢10进1
  2. 八进制:0-7表示,逢8进1
  3. 十六进制:0-9和A-F表示,逢16进1
var num1 = 12; // 十进制
var num2 = 014; // 八进制,以0开头
var num3 = 0x12; // 十六进制,以0x开头

无效的八进制会自动解析成十进制:

var num = 029; // 由于八进制中没有9,会自动解析成十进制的29

在严格模式下定义八进制的数字会报错:

'use strict';
var num = 017; // SyntaxError: Octal literals are not allowed in strict mode.

浮点数的组成:存在小数点,小数点后面存在数字。

var num1 = 0.1; // 浮点数
var num2 = .2; // 虽然小数点之前可以没有数字,但是不推荐这种写法

浮点数占用的内存是整数的两倍,因此,ECMAScript 会把小数点后面没有数字或数字为0的浮点数转成整数来节约内存。

var num1 = 1.;  // 解析成 1
var num2 = 1.0; // 解析成 1

可以用科学计数法表示很大的值或者很小的值:

var num1 = 3.123e10; // 可以使用e,也可以使用E
var num2 = 3.123e-10; // 表示小数

ECMAScript 能够表示的最大值 Number.MAX_VALUE 和最小值 Number.MIN_VALUE。可以通过 isFinite() 方法判断数值是否在 ECMAScript 能够表示的数值范围之内。

console.log(isFinite(123)); // true

超出这个可表示的范围的值,就是正无穷(Number.POSITIVE_INFINITY)和负无穷(Number.NEGATIVE_INFINITY)了。无穷大(Infinity)是不能参与运算的值,因此,如果有一个值的结果是无穷大,那么计算得到的值仍是无穷大。

console.log(Number.POSITIVE_INFINITY + 1) // Infinity

NaN 是一个比较特殊的值,这个数值用来表示,本来应该返回数字的值,而最终的结果没有返回数值。

2/0 // NaN

NaN 和任何数值进行运算,得到的结果都是 NaN。

NaN + 1 // NaN

需要注意的是 NaN 和任何值都不相等,包括和自己本身。

console.log(NaN == NaN);  // false
console.log(NaN === NaN); // false

可以使用 isNaN 函数来判断一个数是否不是数字,规则:如果参数能转成数字,返回 false;如果参数不能转成数字,返回 true。

isNaN(NaN) // true
isNaN(true) // false

4-6 数值转换

把非数值转成数值,有三个函数可以使用:

  • Number() : 将任意数值类型转成数字
  • parseInt() : 将字符串转成整数
  • parseFloat() : 将字符串转成浮点数

Number() 方法

1.布尔类型:

Number(true)  // 1
Number(false) // 0

2.数值类型: 原样输出

Number(12)   // 12
Number(12.3) // 12.3

3.Null类类型:

Number(null) // 0

4.字符串:

Number('123')    // 123,数字会转成对应的十进制的值
Number('+123')   // 123
Number('-123')   // -123
Number('123.12') // 123.12
Number('')       // 0,空字符串结果为0
Number('0xf')    // 十六进制对应的十进制
// 其余字符串转成 NaN

使用一元加操作符,得到的结果和 Number 函数的结果相同

+'' // 0

parseInt() 方法

该方法在转换成数值类型的时候,会有下面的操作:

  1. 首先检查字符串开头的字符是否是 '+' '-' 空格 数字,如果不是,则转成 NaN
  2. 如果是,则检查到第一个不为数字的字符为止,中间的内容转成数字
parseInt('123')      // 123
parseInt('  12.012') // 12
parseInt('a12')      // NaN

该方法可以指定第二个参数,表示第一个参数是哪种进制的数值字符串:

parseInt('12', 8) // 10,12是八进制值,转成十进制就是10

parseFloat() 方法

该方法在转换成数值类型的时候,会有下面的操作:

  1. 首先检查字符串开头的字符是否是 '+' '-' 空格 数字 小数点,如果不是,则转成 NaN
  2. 如果是,则检查到第一个不为数字或小数点的字符为止,中间的内容转成数字
  3. 注意:如果字符串以小数点开头,那么到第二个小数点的位置为止,中间的值作为浮点数
parseFloat('.12')  // 0.12
parseFloat('.12.') // 0.12
parseFloat('+.12') // 0.12
parseFloat('a.12') // NaN

这个方法没有第二个参数。

4-7 String 类型

String 类型用于表示由零个或多个16位 Unicode 字符组成的字符序列,即字符串。字符串可以由引号(单引号或双引号都可以)括起来表示。

'这是一个由单引号括起来的字符串'
"这是一个由双引号括起来的字符串"

转义字符:

字面量 含义
\n 换行
\t 制表符
\b 空格
\r 回车
\\ 斜杠
\' 单引号
\" 双引号
\xnn 以十六进制代码nn表示一个字符,如\x41表示'A'
\unnnn 以十六进制代码表示一个 Unicode 字符

字符串的特点:

字符串一旦创建,值就不能改变。如果要改变,需要重新开辟内存,创建字符串,然后更新变量的指向。

转成字符串:

除了 null 和 undefined,每个数据类型都有 toString,因此,可以使用 toString 方法转成字符串。

123..toString()  // '123',第一个点会被解析成小数点,第二个才是调用方法的操作符
(123).toString() // '123'

toString 的第二个参数用来指定转成数字的基数。

12..toString(2) // 转成二进制

如果对 null 和 undefined 使用 toString 方法会报错:

undefined.toString() // TypeError: Cannot read property 'toString' of undefined
null.toString()      // TypeError: Cannot read property 'toString' of null

一种更加强大的转换成字符串的方法 String,可以接收 null 或 undefined,作为参数;同时也可以接收其他数据类型作为参数。

console.log(String(null));      // null
console.log(String(undefined)); // undefined

一种更简单的转成字符串的方式是,将数值类型与空字符串相加:

123 + ''  // '123'
null + '' // 'null'

4-8 Object 类型

创建 Object 实例的方式,可以通过构造函数的形式创建:

var obj = new Object();

如果构造函数中没有传递参数,那么可以省略括号:

var obj = new Object; // 这种方式不推荐

每个 Object 实例都有下面的属性和方法:

  • Constructor : 构造函数,用于创建对象的函数
  • hasOwnProperty(propertyName) : 检查实例中是否包含某个属性,不是实例原型上的属性
  • isPrototypeOf(object) : 检查传入的对象是否是另一个对象的原型
  • propertyIsEnumerable(propertyName) : 属性能否使用 for-in 语句进行遍历
  • toLocalString : 转成与本地运行环境相匹配的字符串
  • toString : 返回对象的字符串表示
  • valueOf : 返回对象的字符串、数值或布尔值的表示

这些内容作为记忆,在后续的章节会有对这些内容的详细解释。


沫俱宏
763 声望33 粉丝

自己的肯定最重要,做任何决定,一定要从内心出发