JavaScript程序设计之ECMAScript

1. 简介

解析型编程语言(脚本)

运行环境 – 浏览器

ECMAScript – 语言核心标准

DOM文档对象模型 – W3C标准,操作文档对象的API

BOM浏览器对象模型 – 操作浏览器对象的API

引入 – 内嵌代码,外联文件,靠近</body>标签

2. 调试器

浏览器 – F12

调试器

3. 基本语法

3.1 变量标示符

变量标示符

3.2 关键字和保留字

关键字和保留字

3.3 大小写敏感

大小写敏感

3.4 严格模式

严格模式

  1. 隐式声明或定义变量不可行,要带var关键字
  2. 对象属性不能够重名
  3. arguments属性不可用
  4. with语句不可用

3.5 注释

多行注释,以”/“开头,以”/“结尾,不可嵌套

单行注释,以”//“开头

4. 类型系统

4.1 基本类型

4.1.1 对象类型系统

对象类型系统

4.1.2 标准类型

标准类型

4.1.3 原始类型和引用类型

原始类型和引用类型

原始类型和引用类型的赋值

4.1.4 undefined
说明

值:undefined

已声明未赋值的变量

1
2
var a;
console.log(a);

获取对象不存在的属性

1
2
3
var obj = {a:1};
var num = obj.b;
console.log(num);

无返回值的函数的执行结果

1
2
3
var fun = (function() {
console.log('hello');
})()

函数的参数没有传入

1
2
3
var fun = (function(x) {
return x;
})()

void(expression)

类型转换
Boolean Number String
undefined false NaN “undefined”
4.1.5 Null
说明

值:null

表示对象不存在

1
var a = document.getElementById('a');
类型转换
Boolean Number String
null false 0 “null”
4.1.6 Boolean
说明

值:true,false

字面量或变量定义

1
2
true;
var a = false;

条件语句导致系统执行的隐式类型转换

1
2
3
4
5
if (document.getElementById('a')) {
console.log('ok');
} else {
console.log('error');
}
类型转换
Number String
true 1 “true”
false 0 “false”
4.1.7 String
说明

值:由单引号或双引号包裹的字符序列

1
2
3
""
'hello'
var str = 'name="hello"'
类型转换
Number Boolean
“” 0 false
“1a” 1 true
4.1.8 Number
说明

值:整型直接量,八进制直接量(0-),十六进制直接量(0x-),浮点型直接量

1
2
3
4
10;
1.4;
1.2e5;
var count = 0x10;
类型转换
String Boolean
0 “0” false
1 “1” true
Infinity “Infinity” true
NaN “NaN” false
4.1.9 Object
说明

值:一组属性的集合

1
var obj = {a:1,b='hello'}
类型转换
Number Boolean String
{} NaN true “[object object]”

4.2 类型识别

typeof

可以识别标准类型(Null除外)

不可以识别具体对象类型(Function除外)

1
2
3
4
5
6
7
8
9
typeof 'jerre';
typeof 12;
typeof true;
typeof undefined;
typeof null; // "object"
typeof {a: 1};
typeof function () {}; // "function"
typeof []; // "object"
typeof /\d/; // "object"
instanceof

识别内置对象类型

识别自定义对象类型

不能识别原始类型

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
[] instanceof Array;
/\d/ instanceof RegExp;
function Point(x,y) {
this.x = x;
this.y = y;
}
function Circle(x,y,r) {
Point.call(this,x,y);
this.r = r;
}
Circle.prototype = new Point();
Circle.prototype.constructor = Circle;
var circle = new Circle(1,1,2);
circle instanceof Circle; // true
circle instanceof Point; // true
1 instanceof Number; // false
'a' instanceof String; // false
Object.prototype.toString

可以识别标准类型以及内置对象类型

不能识别自定义类型

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
function getType(obj) {
// 分割输出结果中从"object "之后到最后的字符序列,并且小写
return Object.prototype.toString.call(obj).slice(8,-1).toLowerCase();
}
getType(1);
getType('a');
getType(true);
getType(undefined); // 'undefined'
getType(null); // 'null'
getType({});
getType([]); // array
getType(new Date); // date
getType(/\d/); // regexp
getType(function () {});
function Person(num) {
this.num = num;
}
getType(new Person(1)); // object
constructor

可以识别标准类型(undefined和null除外,没有构造器)

可以识别内置对象类型

可以识别自定义类型

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
'a'.constructor === String;
(1).constructor === Number;
true.constructor === Boolean;
({}).constructor === Object;
[].constructor === Array;
function Person(num) {
this.num = num;
}
new Person(1).constructor === Person; // true
// 获取对象构造函数名称
function getConstructorName(obj) {
return obj && obj.constructor && obj.constructor.toString().match(/function\s*([^(]*)])/)[1];
}
getConstructorName([]) === 'Array'; // true

5. 内置对象

5.1 简介

标准内置对象

构造器对象

  1. 说明
  2. 实例化对象方法
  3. 属性方法
  4. 原型对象属性方法
  5. 实例对象属性方法

普通对象

  1. 说明
  2. 属性方法

5.2 Object

Object

Object.create

Object.create

Object.prototype.toString

Object.prototype.toString

Object.prototype.hasOwnProperty

Object.prototype.hasOwnProperty

5.3 Boolean

Boolean

布尔
数字 0,NaN false
字符串 “” false
undefined false
null false
对象 true

5.4 String

String

String.prototype.indexOf

String.prototype.indexOf

String.prototype.replace

String.prototype.replace

String.prototype.split

String.prototype.split

5.5 Number

Number

Number.prototype.toFixed

String.prototype.toFixed

5.6 Array

Array

Array.prototype.splice

Array.prototype.splice

Array.prototype.forEach

Array.prototype.forEach

5.7 Function

Function

自定义对象构造器

自定义对象构造器

Function.prototype.apply

Function.prototype.apply

Function.prototype.bind

Function.prototype.bind

子类构造器

子类构造器

函数调用
  1. ()
  2. apply,call
函数参数
  1. 形参个数不一定等于实参个数
  2. 值传递
  3. 通过参数类型检查事项函数重载
arguments
  1. length:实参个数
  2. 0…arguments.length-1:实参属性名称(key-value中的key)
  3. callee:函数本身
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
// 比较不定数量的数字大小并且返回大数
function max(a,b) {
if (max.length === arguments.length) {
return a > b ? a : b;
} else {
var _max = arguments[0];
for (var i=0; i<arguments.length; i++) {
if (_max < arguments[i]) {
_max = arguments[i];
}
}
return _max;
}
}
值传递

值传递

函数重载

函数重载是指在同一作用域内,可以有一组具有相同函数名,不同参数列表的函数,这组函数被称为重载函数。

Javascript中参数列表对函数的功能是没有影响。参数列表只是为了我们更方便地使用函数而设置的,真正调用函数时,起作用的永远是一个存放参数的数组(可以通过arguments对象访问的数组)。

在定义同名函数的时候,后定义的函数只不过是覆盖了先定义函数的引用变量。

requirejs实现的函数重载

1
2
3
4
5
6
7
8
9
10
// 定义了一个math模块
// math.js
define(function (){
var add = function (x,y){
return x+y;
};
return {
add: add
};
});

在其他地方加载方法

1
2
3
4
// main.js
require(['math'], function (math){
alert(math.add(1,1));
});

5.8 RegExp

RegExp

RegExp.prototype.test

RegExp.prototype.test

5.9 Date

Date

5.10 Math

Math

Math.floor

Math.floor

5.11 JSON

JSON

JSON.stringify

JSON.stringify

JSON.parse

JSON.parse

5.8 全局对象

全局对象

NaN

NaN

parseInt

parseInt

eval

eval

encodedURIComponent

encodedURIComponent

6. 表达式与运算符

表达式

expression

运算符

operator

关系运算 ===

关系运算 ===

####关系运算 ==

关系运算 ==

逻辑运算 !

逻辑运算 !

逻辑运算 &&

逻辑运算 !

逻辑运算 ||

逻辑运算 !

运算符优先级

运算符优先级

7. 语句

语句

for in

for/in

with

with

8. 变量作用域

变量作用域

  1. 生命周期
  2. 作用范围
  3. 静态作用域(词法作用域),由程序定义的位置决定

静态作用域

  1. 动态作用域,程序运行时刻决定

动态作用域

Javascript变量作用域

  1. 使用静态作用域
  2. 没有块级作用域
  3. ES5使用词法环境管理静态作用域

词法环境

  1. 组成

    环境记录(形参、变量、函数等)
    对外部词法环境引用(outer)

  2. 一段代码开始执行前,先初始化词法环境

    形参
    变量定义 var x = undefined
    函数定义
    函数定义

  3. 构造过程

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    > var x = 10;
    > function foo(y) {
    > var z = 30;
    > function bar(q) {
    > return x + y + z + q;
    > }
    > return bar;
    > }
    > var bar = foo(20);
    > bar(40);
    >

    >

    构造过程1
    构造过程2
    构造过程3

  4. 问题

    形参、函数定义、变量定义名称冲突

    arguments

    函数表达式

  5. with

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    > var foo = 'abc';
    > with({
    > foo: 'bar'
    > }) {
    > function f() {
    > alert(foo); // 'bar'
    > };
    > (function () {
    > alert(foo); // 'bar'
    > })();
    > f();
    > }
    >

    >

    有with构造过程

  1. try … catch

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    > try {
    > var e = 10;
    > throw new Error();
    > } catch(e) {
    > function f() {
    > alert(e);
    > };
    > (function () {
    > alert(e);
    > })();
    > f();
    > }
    >

    >

    有try ... catch构造过程

  2. 带名称的函数表达式

    1
    2
    3
    4
    5
    > (function A() {
    > A = 1;
    > alert(A); // <function>
    > })();
    >

    >

    带名称的函数表达式构造过程

9. 闭包

1
2
3
4
5
6
7
8
9
function add() {
var i = 0;
return function() {
alert(i++);
}
}
var f = add();
f();
f();

闭包

闭包概念

保存变量现场

封装