什么是类?什么是对象?

类是一个抽象的概念,是对某一类事物的抽象。 我们举个例子,人类可以看作一个类,这个类的共性有:第一、站立行走,第二、有一个很发达的大脑,上面这两点都是静态的,描述的是客观的属性(attributes)。人类还需要吃饭、需要睡觉,上面这两点都是动态的行为,即方法(methods)。类可以包含函数,函数在类中就是动态的行为,即方法。

对象就是类的实例化。人类是一个类,而每一个人就是人类的实例化,即每一个人就是一个对象,对象具有类的属性及方法(每个人都站立行走、有一个发达的大脑,并且需要吃饭睡觉)。

JavaScript中类的声明

1. 普通声明,基于已有对象扩充其属性和方法

1
2
3
4
5
6
7
var obj = new Object();
obj.name = '张三';
obj.age = '18';
obj.run = function(){
console.log(this.name + '开始奔跑');
}
obj.run(); // 张三开始奔跑

这种方式的弊端:这种对象的可复用性不强,如果需要使用多个对象,还需要重新扩展其属性和方法。

2. 键值对声明

1
2
3
4
5
6
7
8
9
var obj = {
name : '张三',
age : 18,
run : function () {
console.log(this.name + '开始奔跑');
}
};

obj.run(); // 张三开始奔跑

可以看得到,键值对中的键就是对象的属性,值就是对应属性的值

3. 构造函数方式

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
function Person() {
this.name = '张三';
this.age = 18;

this.run = function () {
console.log(this.name + '开始奔跑');
}

console.log(this.name + '的年龄为' + this.age);
}


//实例化对象:
var person = new Person(); // 张三的年龄为18
person.run(); // 张三开始奔跑

4. 原型(“prototype”)方式

1
2
3
4
5
6
7
8
9
10
11
12
function Person() {

}

Person.prototype.name = '张三';
Person.prototype.age = 18;
Person.prototype.run = function () {
console.log(this.name + '开始奔跑');
}

var person = new Person();
person.run(); // 张三的年龄为18

使用原型存在的缺点:

  1. 不能传参数;
  2. 有可能会导致程序错误。如果使用原型方式来定义对象,那么生成的所有对象会共享原型中的属性,这样一个对象改变了该属性也会反映到其他对象当中。单纯使用原型方式定义对象无法在构造函数中为属性赋初值,只能在对象生成后再去改变属性值。

继承

创建一个或多个类的专门版本类方式称为继承(Javascript只支持单继承)。 创建的专门版本的类通常叫做子类,另外的类通常叫做父类。 在Javascript中,继承通过赋予子类一个父类的实例并专门化子类来实现。

让我们来看一下例子。
我们定义了 Student类作为 Person类的子类. 之后我们重定义了sayHello() 方法并添加了 squat() 方法

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
28
29
30
31
32
33
34
35
36
37
38
39
40
41
function Person(name) {
this.name = name;
this.sayHello = function () {
console.log('我的名字叫' + name);
}

this.run = function () {
console.log(name + '开始奔跑');
}
}

// 定义学生类
function Student(name,age) {
// 调用父类构造器, 确保(使用Function#call)"this" 在调用过程中设置正确
Person.call(this,name);
//初始化学生年龄
this.age = age;

/**
* 更换Person类的sayHello方法
*/
this.sayHello = function () {
console.log('我的名字叫' + name + ',今年' + age + '岁')
}
this.squat = function () {
console.log('蹲下来')
}

}
// 建立一个由Person.prototype继承而来的Student.prototype对象
Student.prototype = Object.create(Person.prototype);
// 设置"constructor" 属性指向Student
Student.prototype.constructor = Student;

var student = new Student('张三',18);
student.sayHello(); // 我的名字叫张三,今年18岁
student.run(); // 张三开始奔跑
student.squat(); //蹲下来

console.log(student instanceof Person); // true
console.log(student instanceof Student); // true