JavaScript的范围

JavaScript的范围:BOM + DOM + ECMAScript

BOM

BOM即Browser Object Mode,浏览器对象模型。

BOM提供了独立于内容而与浏览器窗口进行交互的对象。BOM由一系列相关的对象构成,并且每个对象都提供了很多方法与属性。因为BOM主要用于管理窗口与窗口之间的通信,因此其核心对象是window。BOM缺乏标准,JavaScript语法的标准化组织是ECMA,DOM的标准化组织是W3C

DOM

DOM即Document Object Model,文档对象模型。

当网页被加载时,浏览器会创建页面的文档对象模型,即DOM。DOM(文档对象模型)被构造为对象的树。DOM由一系列相关的对象构成,引申为Document对象。DOM的标准化组织是W3C

ECMAScript

ECMAScript指代JavaScript的核心语法。JavaScript 由 Brendan Eich 发明。
JavaScript于1995 年出现在 Netscape 中于 1997 年被 ECMA(一个标准协会)采纳。

ECMAScript(规范)语法核心

1
2
3
4
5
变量
函数
数据类型(基本数据类型 + 对象类型)
结构(循环|条件|判断)
面向对象等内容

基本类型和复杂类型

基本类型(简单数据类型)
  • string
  • number
  • boolean
  • undefined
  • null
复杂类型(复合数据类型)
  • Object
  • Array
  • Date
  • RegExp
  • Function
  • String
  • Number
  • Boolean
  • Math

操作符说明

一元操作符

定义:只能够操作一个值的操作符叫做一元操作符。

① 递增和递减操作符

[01] 前置型,递增和递减操作在包含他们的语句被求值之前就执行。
[02] 后置型,递增和递减操作在包含他们的语句被求值之后才执行。

1
2
3
4
5
6
7
8
9
var num1  = 2;
var num2 = 20;
var num3 = --num1 + num2; //21
var num4 = num1 + num2; //21
----
var num1 = 2;
var num2 = 20;
var num3 = num1-- + num2; //22
var num4 = num1 + num2; //21

② 一元加和减操作符

一元加操作符对结果不会有任何的影响。 一元减操作符主要用于表示负数。

位操作符

01 按位非(NOT)

使用~表示,执行按位非的结果就是返回数值的反码。 操作数的负值减去1

1
2
3
var num1 = 25;
var num2 = -num1 - 1; //-26
consol.log(~num1) //-26

02 按位与(AND)

使用&符号表示,操作两个操作数。 只要有〇就为〇

03 按位或(OR)

使用|符号表示,操作两个操作数。 只要有1就为1

04 按位异或(XOR)

使用^符号表示,操作两个操作数。 相同则为0,不同则为1

05 左移|右移(|有符号|无符号)

布尔操作符

布尔操作符一共有三个,分别是:非、与、或

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
01 逻辑非 
符号:!
说明:取反,可应用于任何值,!!相当于没有操作。

02 逻辑与
符号:&&
说明:两个值都为真则结果为真。属于短路操作,若第一个操作数能决定结果,则不会再对第二个操作数求值。

03 逻辑或
符号:||
说明:两个值中有一个为真则结果为真。属于短路操作,若第一个操作数为真,则不会再对第二个操作数求值了。
技巧:可以利用逻辑或短路操作的特点来避免为变量赋nullundefined值。

var myObject = refObject || backupObject;
//如果refObject的值不是null,那么它的值将被赋值给myObject
//如果是null,那么就将backupObject的值赋值给myObject。

乘性操作符

乘 * 除 / 模 %

加性操作符

加 + 减 -

说明:上述五种操作符在操作数为非数值的时候内部会执行自动的类型转换。

关系操作符

1
2
3
4
5
大于 > 
小于 <
小于等于 <=
大于等于 >=
说明:返回布尔类型的值,要么为false,要么为true

相等操作符

01 相等和不相等[先转换再比较],符号是 ==!=

1
2
3
4
5
6
7
比较的规则:
[01] 如果操作数中有布尔值,则先转换为数值再比较。
[02] 如果是字符串和数值比较,则先将字符串转换为数值再比较。
[03] 如果是对象和其他类型的值比较,则先调用对象的valueOf方法,然后用得到的基本类型值去比较。
[04] null和undefined是相等的。
[05] NaN和NaN不相等。
[06] 若两个操作符都是对象,则比较他们是不是同一个对象,如果指向的是同一个对象则返回true,否则返回false。

02 全等和不全等[仅比较不转换],符号是===!==

1
2
3
比较的规则:
[01] null和undefined是不全等的,因为它们是不同类型的值。
[02] 类型相同,且值相等,则返回true,否则返回false。

条件操作符

符号:表达式1 ? 字面量1 :字面量2
说明:如果表达式1的结果为true,则使用字面量1,否则使用字面量2。

赋值操作符

符号:=、+=、-=、*=、<<=等等
说明:使用赋值操作符对性能而言,没有任何的提升,只是简化了赋值操作而已。

值类型和引用类型

值类型

1
2
3
4
5
数值
字符串
布尔类型
undefined
null

引用类型

1
2
3
4
对象(Object类型)
数组(Array)
函数 (Function)
···

值类型保存为简单的数据值,赋值只是简单的数据值的复制
引用类型保存为对象,其本质是指向内存位置的引用(地址),赋值是对地址的复制

代码示例

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
//备注:值类型
var num1 = 10;
var num2 = num1; //把num1的值复制一份给num2,num1和num2的值相等,除此之外没有任何其他关系

console.log(num1,num2); //10,10
console.log(num1 == num2); //true

num2 = 20; //修改num2的值为20,不会对num1产生任何的影响
console.log(num1,num2); //10,20
console.log(num1 == num2); //false

//备注:引用类型
var arr1 = [1,2,3];
var arr2 = arr1;
console.log(arr1,arr2); //[1,2,3],[1,2,3]
console.log(arr1 == arr2); //true

var arr3 = [1,2,3];
console.log(arr3); //[1,2,3]
console.log(arr1 == arr3,arr2 == arr3); //false,false

/**
* 代码说明:
* arr1和arr2在比较的时候,值相等(都是[1,2,3]),且引用相等(都指向堆中同一块数据),因此arr1和arr2相等
* arr3和arr1以及arr2比较的时候,值相等([1,2,3]),但是引用不相等(arr3指向的是堆中另外一块数据),因此不等
* 总结:引用类型在比较相等的时候,只有值和引用都相等才相等
* */

值类型和引用类型的赋值

赋值操作(=):把当前变量存储的值复制一份给接收的变量

值类型的赋值把当前变量存储的值(具体的数据)复制一份给接收的变量
引用类型赋值把当前变量存储的值(具体数据的引用即地址)复制一份给接收的变量

1
2
3
4
5
6
7
8
9
//引用类型使用注意
console.log(arr1,arr2); //[1,2,3],[1,2,3];
console.log(arr1 == arr2); //true
arr1.push(4);
console.log(arr1,arr2); //[1,2,3,4],[1,2,3,4]

/**
* 代码说明:因为arr1和arr2内部的引用指向的是同一块数据,所以修改了arr1会对arr2也产生影响
* */

值类型和引用类型作为函数参数处理

形参 占位用的参数,用来接收数据的参数而已
实参 实际传递的参数
函数的调用 在函数调用的时候,函数默认会把实参的值赋值给形参
值类型参数 在函数内部对形参变量进行修改不会影响到实参的值
引用类型参数 在函数内部对形参变量进行修改会影响到实参的值,因为他们的引用指向同一个对象

值类型和引用类型示意图

基本类型的赋值

1
2
var str1 = "Hi 文顶顶!";
var str2 = str1;


引用类型的结构和赋值

1
2
3
4
5
6
7
8
9
var car = {
color:"红色",
number:"B99"
};
var p1 = {
name:"文顶顶",
age:18,
car:car
};


1
2
3
4
5
var obj1 = {
name:"文顶顶",
age:18
};
var obj2 = obj1;

对象的动态特性:在js中可以动态的对对象属性进行增加、修改和删除等操作。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
//01 创建对象
var obj = {
name:"刘德华",
age:60
};

//02 动态的为对象添加属性
obj.height = "180cm";
console.log(obj.height);

//03 动态的为对象添加方法
obj.maiMeng = function () {
console.log("华仔会卖萌噢");
};

obj.maiMeng();

//04 修改属性的值:如果设置的属性以前不存在,那么就是添加,如果设置的属性已经存在了,那么就是修改
obj.name = "王宝强";
console.log(obj.name)

//05 删除属性
delete obj.name;
console.log(obj.name); //undefined

访问对象的两种方式

点语法
[ ]语法,注意对象的属性必须是字符串

in 和 delete关键字

in关键字的作用

❐ 判断属性是否存在于对象中,注意所有的key都是字符串
❐ 在for in循环中 遍历对象的 键

1
2
3
4
5
6
7
8
9
10
11
12
13
14
var obj = {
name:"张三",
age:18
};

for(k in obj)
{
console.log(k,obj[k]);
}

//检测obj对象中是否存在name这个属性
console.log("name" in obj);

//注意:in关键字操作数组的时候检测的是索引值并非数组元素

delete关键字的作用

❐ 删除对象的属性
❐ 删除未使用var声明的变量
❐ 返回值为boolean类型,true则 表示是否删除成功

1
2
3
使用注意:
01 删除的属性如果不存在,返回true
02 删除的如果是原型中的属性,返回true 但是删除不成功

break和continue

循环和分支结构

1
2
3
4
5
6
7
8
9
//循环结构
for
while
do...while
for..in

//分支结构
if...else..
swith..case

break和continue对比
break终止循环,循环中后面的代码不再执行
continue结束当前循环,循环后面的代码不再执行,继续下一次循环

调试工具的使用

开启调试窗口 windows 平台: f12
调试窗口介绍

1
2
3
4
5
指针: 选择页面中的元素
手机: 使用移动端界面调试
Elements: 查看页面 DOM 树
Console: 控制台(注意, 控制台与该页面是一个整体, 在控制台中的任何操作, 会影响到页面)
Source: 代码调试

调试工具的使用

逐过程运行, 一次运行一个函数
单步运行(逐步运行), 一次运行一句, 如果是函数, 进入函数体内运行
继续运行. 从当前状态运行下去, 直到出现断点, 如果没有断点则运行结束

设置断点技巧

1
2
3
4
逐步与逐过程混合
断点加继续运行
条件断点(右键添加 add contitional breakpoint)
利用 watch 监视窗口可以查看对象成员

异常处理

异常情况
01 运行环境的多样性导致的异常(浏览器)
02 语法错误,代码错误
03 异常的特征:一旦代码出现异常,后面的代码就不会再执行

异常捕获

1
2
3
4
5
6
try{
//这里写可能出现异常的代码
}catch(e){
//这里的e就是捕获的异常对象
//可以在这里写,出现异常后的处理代码
}

异常捕获语句执行的过程:

1
2
3
4
01 代码正常运行, 如果在try中出现了错误, try 里面出现错误的语句后面的代码都不再执行, 直接跳转到 catch 中
02 在catch中处理错误信息
03 继续执行后面的代码
04 如果 try 中没有出现错误, 那么不走 catch 直接执行后面的代码

捕获异常的特点:通过try-catch语句进行异常捕获之后,代码将会继续执行,而不会中断。

注意:语法错误异常用try-catch语句无法捕获,因为在预解析阶段,语法错误会直接检测出来,而不会等到运行的时候才报错。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
//01 try ... catch结构的使用
//a(); 若直接调用则爆出:Uncaught ReferenceError: a is not defined错误
//在开发中,我们对于可能会报错或者是发生异常的代码用try结构进行处理

try{
a(); //如果发生异常,那么至少不会到正程序中断
}
catch(e)
{
//如果try语句中发生了异常,那么会执行此处的代码块
//参数e.为具体的异常信息,可以打印进行查看
console.log(e);
}

function functionTest() {
console.log("functionTest");
};
functionTest();

//结论:
//使用try...catch结构,如果发生了异常,那么不会影响后面代码的执行
//我们可以在发生异常信息之后做出具体的处理

手动抛出异常

案例:自己写的一个函数,需要一个参数,如果用户不传参数,此时想直接给用户抛出异常,就需要了解如何抛出异常。抛出异常使用throw关键字,下面给出对应的示例:

手动抛出异常信息-字符串

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
try{
//a(); //如果发生异常,那么至少不会到正程序中断

//不使用系统默认的异常信息,尝试手动抛出
throw "对不起,您调用了尚未定义的方法";
}
catch(e)
{
//如果try语句中发生了异常,那么会执行此处的代码块
//参数e.为具体的异常信息,可以打印进行查看
console.log(e);
}

function functionTest() {
console.log("functionTest");
};
functionTest();

手动抛出异常信息-对象

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
try{
//a(); //如果发生异常,那么至少不会到正程序中断

//不使用系统默认的异常信息,尝试手动抛出
throw {
errMsg:"具体的错误信息提示",
errCode:"指定错误类型的代号,如1001等"
};
}
catch(e)
{
//如果try语句中发生了异常,那么会执行此处的代码块
//参数e.为具体的异常信息,可以打印进行查看
console.log(e);

//在try语句中抛出的错误信息是什么,那么得到的异常信息就是什么
//如果抛出的是字符串,那么得到的就是字符串
//如果抛出的是对象,那么此处得到的就是对象
console.log(e.errMsg);
console.log(e.errCode);
}

function functionTest() {
console.log("functionTest");
};
functionTest();

异常捕获语句的完整模式

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
异常捕获语句的完整模式为try-catch-finally

try{
//在执行的时候可能发生异常的代码
b();
}
catch (e)
{
//如果try代码块中的代码在执行中发生了异常,那么就会执行该代码块的代码
//通过打印e对象可以查看具体的异常信息
console.log(e); //打印异常信息
}
finally {
//不论try语句中的代码是否会发生异常,都一定会执行此处的代码块
//一般在前端开发中很少使用,常用语后台开发的资源释放工作
console.log("无论如何总要执行的代码");
}

说明 finally中的代码,不管是否发生异常,都会执行。一般用在后端语言中,用来释放资源,JavaScript中很少会用到。

DOM操作复习

获取元素操作

1
2
3
getElementById
getElementsByTagName
getElementsByClassName

元素节点操作

1
2
3
4
5
6
7
appendChild
insertBefore
removeChild
replaceChild
cloneNode
createElement
createTextNode(创建文本节点)

属性节点操作

1
2
3
getAttribute
setAttribute
removeAttribute

常用DOM属性

1
2
3
4
className
innerHTML
innerText/textContent value
children

代码示例

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
//0 获取页面中指定的标签,并设置其样式
var divID = document.getElementById("divId");

divID.style.backgroundColor = "pink";
divID.style.height = "40px";
divID.style.width = "200px";

//01 创建新的标签
var div = document.createElement("div");

//02 设置标签的样式
div.style.backgroundColor = "red";
div.style.height = "100px";
div.style.width = "300px";
div.style.fontSize = "20";

//03 设置标签的内容
div.innerText = "这是一个自己创建的标签";

//04 把标签插入到页面中
document.body.appendChild(div);

函数和对象的创建

定义函数的几种方式
① 函数声明
② 函数表达式
③ 使用Function类型的构造器创建

代码示例

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
//01 函数声明
function functionName() {
console.log('以函数声明的方式来定义函数');
}

functionName();

//02 函数表达式
var func = function () {
console.log('函数表达式的方式来定义函数');
};
func();

//03 使用Function构造器来创建
var funcName = new Function();
funcName();
//上面的代码等价于
/*
function funcName() {

}
*/

面层过程和面向对象编程

面向对象编程和面向过程编程是一种编程思想,和具体的语言关系不大。

面向过程编程和面向对象编程的主要区别

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
面向过程编程:
关注点在于解决问题需要的每一个详细的步骤
示例:
自己洗衣服的过程
① 收集需要洗的脏衣服
② 准备洗衣粉、洗衣液等
③ 把衣服放到一个盆里
④ 接水
⑤ 把洗衣粉放到盆里
⑥ 摩擦,摩擦,不断的摩擦
⑦ 把洗好的衣服用清水冲洗干净
⑧ 尽量把把洗好的衣服的水分拧干
⑨ 晾晒

面向对象编程:
关注点在于解决问题需要的对象身上
示例:
使用洗衣机洗衣服的过程
① 收集需要洗的脏衣服
② 找到合适的洗衣机
③ 设定洗衣服和烘干的程序

总结:面向过程和面向对象他们的区别就类似于自己洗衣服和使用洗衣机洗衣服|自己做饭吃和去餐馆吃饭

面向对象编程的相关概念

对象

什么是对象? 所有的一切都是对象,在开发中有一项重要的工作就是对象的划分
一般来说,我们所指的对象是某个具体的事物,而非泛泛的类别

对象的特征(静态描述信息)

所谓特征就是一些特定的描述信息
譬如 → 学生(性别、年龄、班级、专业、籍贯、家庭住址)
譬如 → 汽车(颜色、车牌、品牌、价格等)

对象的行为(动态特性)

譬如 → 人(吃饭、睡觉、玩游戏、奔跑、运动等)
譬如 → 狗(吃、睡、咬人、叫、流口水)

js中的对象

键-值对(key-value)的集合。

现实生活中的对象和js对象的对应关系

静态的描述信息 - js对象中的属性(属性就是定义在对象内部的变量)
动态的行为特征 - js对象中的方法(方法就是定义在对象内部的函数)

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
var zhangsan = {
name:"张三",
sex:"男",
age:18,
address:"天上人间1号公馆",

eat:function () {
console.log('能吃');
},
sleep:function () {
console.log("能睡");
},
say:function () {
console.log("能说话");
},
run:function () {
console.log("能运动");
},
song:function () {
console.log("能唱歌");
}
};

//打印对象的属性并调用相关的方法
console.log(zhangsan.name,zhangsan.age,zhangsan.address);
zhangsan.say();
zhangsan.sleep();