深入理解Javascript(二)面向对象、事件循环机制
3. 面向对象高级
3.1 对象创建模式
new运算符
当函数用new运算符调用,会被当做构造函数调用;new会有如下操作:
- 创建一个普通的空对象{}
- 让这个空对象的__proto__指向构造函数的prototype
- 将this指向新创建的这个对象
- 如果构造函数返回值是非原始值,这个值将作为新对象的值返回;如果没返回值或返回值是原始值,新对象将作为返回值。(正常情况下,不会写返回值)
- Object构造函数方式:先创建Object空对象,再动态添加属性/方法 适用于:起始不确定对象内部数据 缺点:语句多
1
2
3
4
5
6
7
8
9var p =new Object();
p.name = "Tom";
p.age = 18;
p.setName = function(name){
this.name = name;
};
p.setAge = function(age){
this.age = age;
}; - 对象字面量形式:使用{}创建对象,同时指定属性/方法 适用于:起始确定对象内部数据 缺点:创建多个相似对象,代码重复
1
2
3
4
5
6
7
8
9
10var p = {
name:"Tom",
age:18,
setName:function(name){
this.name = name;
},
setAge:function(age){
this.age = age;
}
}; - 工厂模式:定义一个工厂函数,内部以字面量形式创建对象,并返回这个对象。 工厂函数:返回一个对象的函数 适用场景:需要创建多个Object对象 缺点:对象没有具体类型,都是Object
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16function creatPerson(name,age){
var obj = {
name:name,
age:age,
setName:function(name){
this.name = name;
},
setAge:function(age){
this.age = age;
}
};
return obj;
}
var p1 = creatPerson("Tom",18);
var p2 = creatPerson("Bob",15); - 自定义构造函数:定义一个构造函数,通过new创建对象 适用于:需要创建多个类型确定的对象 缺点:每个对象都有相同的数据, 浪费内存(下例中的setName和setAge重复放入p1 p2)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21function Person(name,age){
this.name = name;
this.age = age;
this.setName = function(name){
this.name = name;
};
this.setAge = function(age){
this.age = age;
};
}
var p1 = new Person("Tom",18);
var p2 = new Person("Bob",25);
function Student(name,money){
……
}
var s1 = new Student("Danny",12)
//由此,我们就区分了Person与Student两种不同类型
console.log(p1 instanceof Person);
console.log(s1 instanceof Student); - 构造函数+原型:自定义构造函数, 属性在函数中初始化, 方法添加到原型上
1
2
3
4
5
6
7
8
9
10function Person(name,age){
this.name = name;
this.age = age;
}
Person.prototype.setName = function(name){
this.name = name;
};
Person.prototype.setAge = function(age){
this.age = age;
};
3.2 继承模式
1 | function Father(name,age){ //this指向Father实例 |
3.3 面向对象的特点
- 封装:对象是存储不同属性的容器,并且负责数据的安全 如何确保数据安全:
- 私有化属性,在属性名前加#,私有属性只能在对象内部访问;
- 提供setter和getter方法,暴露属性。灵活控制读写权限,同时还可以进行数据验证。
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18class Person{
#name
#age
#gender
construstor(name,age,gender){
this.#name = name
this.#age = age
this.#gender = gender
}
set name(name){
this.#name = name
}
get name(){
return this.#name
}
} - 继承:extends关键字 super引用父类的属性、方法
- 多态:JS并不会检查参数的类型,意味着任何类型的参数都可以传入
4. 线程机制与事件机制
4.1 进程与线程
进程(Process) 是计算机中的程序关于某数据集合上的一次运行活动,是系统进行资源分配和调度的基本单位,是操作系统结构的基础。 在当代面向线程设计的计算机结构中,进程是线程的容器。程序是指令、数据及其组织形式的描述,进程是程序的实体。是计算机中的程序关于某数据集合上的一次运行活动,是系统进行资源分配和调度的基本单位,是操作系统结构的基础。程序是指令、数据及其组织形式的描述,进程是程序的实体。
总结:
进程:指在系统中正在运行的一个应用程序;程序一旦运行就是进程;进程——资源分配的最小单位。
线程:系统分配处理器时间资源的基本单元,或者说进程之内独立执行的一个单元执行流。线程——程序执行的最小单位
4.2 JS执行队列
HTML5提出了web worker标准,允许JS脚本创建多个线程。于是,JS出现了同步和异步。
JS的异步是通过回调函数实现的。常见的异步任务:
普通事件,如click、resize等
加载资源,如load、error等
定时器,如setInterval、setTimeout等
同步任务在主线程执行栈中,异步任务在任务队列中。
执行机制:
- 先执行执行栈中的同步任务
- 遇到异步任务,将异步任务提交给对应的异步线程处理
- 当事件发生,将其推入任务队列
- 执行栈中的任务执行完毕,在按次序读取任务队列中中的异步任务,被读取的异步任务进入执行栈,开始执行
- 重复step4
本博客所有文章除特别声明外,均采用 CC BY-NC-SA 4.0 许可协议。转载请注明来自 Zhenduo's Blog!