ES5中因为没有class关键字,所以创建类的方式是通过构造函数来定义的。我将一步步的用代码演示如何慢慢用原生的语法实现JS的类的定义和继承。希望大家喜欢。
废话不多说,我们来看原生JavaScript定义类的方法。
1. 最简单的类
// 类的构造函数
function Person() {
this.name = "夏诺风"; // 属性 name
this.age = 18; // 属性 age
}
// 调用类则使用new关键字
var person = new Person();
console.log(person.name); // 输出 夏诺风
2. 构造函数和原型链里面增加属性和方法
function Person() {
this.name = "夏诺风"; // 属性 name
this.age = 18; // 属性 age
// 增加类方法
this.run = function() {
console.log(this.name + '正在跑步');
}
}
// 原型链上的属性会被多个实例所共享,构造函数中的属性则不会
Person.prototype.sex = "男"; // 原型链增加属性
Person.prototype.walk = function() { // 原型链上增加方法
console.log(this.name + '正在走路');
};
// 调用类则使用new关键字
var person = new Person();
console.log(person.name); // 输出 "夏诺风"
person.run(); // 调用方法 输出 "夏诺风正在跑步"
// 我们也可以调用原型链的方法
person.walk(); // 调用原型链上的方法 输出 "夏诺风正在走路"
以上两个例子就是ES5中怎么定义类的属性和方法的例子,你可以在构造函数中定义也可以在原型链上定义,都是没有问题的。
3. 类里面的静态方法
function Person() {
this.name = "夏诺风"; // 属性 name
this.age = 18; // 属性 age
// 增加类方法
this.run = function() { // 实例方法必须通过new以后才能被调用
console.log(this.name + '正在跑步');
}
}
// 静态方法
Person.getInfo = function() {
console.log('我是静态方法');
}
// 原型链上的属性会被多个实例所共享,构造函数中的属性则不会
Person.prototype.sex = "男"; // 原型链增加属性
Person.prototype.walk = function() { // 原型链上增加方法
console.log(this.name + '正在走路');
};
// 静态方法的调用是不需要new的,而是直接“构造方法名称.方法名”
Person.getInfo();
ES5里面的继承
1. 对象冒充实现继承
function Person() {
this.name = "夏诺风"; // 属性 name
this.age = 18; // 属性 age
// 增加类方法
this.run = function() { // 实例方法必须通过new以后才能被调用
console.log(this.name + '正在跑步');
}
}
// 原型链上的属性会被多个实例所共享,构造函数中的属性则不会
Person.prototype.sex = "男"; // 原型链增加属性
Person.prototype.walk = function() { // 原型链上增加方法
console.log(this.name + '正在走路');
};
// SuperMan类继承Person 在ES5中继承最常用的方法就是原型链+对象冒充的组合继承模式
function SuperMan() {
Person.call(this); // 对象冒充实现继承
}
var superman = new SuperMan();
// 对象冒充可以继承构造函数中的属性和方法,但是没有办法结成原型链上的属性和方法。
superman.run(); // 输出 “夏诺风正在跑步”
superman.walk(); // 报错,对象冒充实现的继承没有办法继承原型链上的属性和方法。
2. 原型链实现继承
function Person() {
this.name = "夏诺风"; // 属性 name
this.age = 18; // 属性 age
// 增加类方法
this.run = function() { // 实例方法必须通过new以后才能被调用
console.log(this.name + '正在跑步');
}
}
// 原型链上的属性会被多个实例所共享,构造函数中的属性则不会
Person.prototype.sex = "男"; // 原型链增加属性
Person.prototype.walk = function() { // 原型链上增加方法
console.log(this.name + '正在走路');
};
// SuperMan类继承Person 在ES5中继承最常用的方法就是原型链+对象冒充的组合继承模式
function SuperMan() {}
SuperMan.prototype = new Person(); // 原型链实现继承
var superman = new SuperMan();
// 原型链实现继承,既可以继承构造函数中的属性和方法,也可以继承原型链上的函数和方法。
superman.run(); // 输出 “夏诺风正在跑步”
superman.walk(); // 输出 “夏诺风正在走路”
3. 原型链继承的问题?没有办法给父类传参
function Person(name, age) {
this.name = name; // 属性 name
this.age = age; // 属性 age
// 增加类方法
this.run = function () { // 实例方法必须通过new以后才能被调用
console.log(this.name + '正在跑步');
}
}
// 原型链上的属性会被多个实例所共享,构造函数中的属性则不会
Person.prototype.sex = "男"; // 原型链增加属性
Person.prototype.walk = function () { // 原型链上增加方法
console.log(this.name + '正在走路');
};
function SuperMan(name, age) {}
SuperMan.prototype = new Person();
var superman = new SuperMan("超级夏诺风", 19); // 原型链继承的时候,我们没有办法给父类传参数
superman.run(); // 输出 “undefined正在跑步”
4. 原型链 + 对象冒充继承的组合继承模式
function Person(name, age) {
this.name = name; // 属性 name
this.age = age; // 属性 age
// 增加类方法
this.run = function () { // 实例方法必须通过new以后才能被调用
console.log(this.name + '正在跑步');
}
}
// 原型链上的属性会被多个实例所共享,构造函数中的属性则不会
Person.prototype.sex = "男"; // 原型链增加属性
Person.prototype.walk = function () { // 原型链上增加方法
console.log(this.name + '正在走路');
};
function SuperMan(name, age) {
Person.call(this, name, age); // 对象冒充继承 实例化子类可以给父类传参
}
SuperMan.prototype = new Person();
var superman = new SuperMan("超级夏诺风", 19); // 原型链继承的时候,我们没有办法给父类传参数
superman.run(); // 输出 “超级夏诺风正在跑步”
5. 原型链 + 对象冒充继承的组合继承模式的另外一种方法
function Person(name, age) {
this.name = name; // 属性 name
this.age = age; // 属性 age
// 增加类方法
this.run = function () { // 实例方法必须通过new以后才能被调用
console.log(this.name + '正在跑步');
}
}
// 原型链上的属性会被多个实例所共享,构造函数中的属性则不会
Person.prototype.sex = "男"; // 原型链增加属性
Person.prototype.walk = function () { // 原型链上增加方法
console.log(this.name + '正在走路');
};
function SuperMan(name, age) {
Person.call(this, name, age); // 对象冒充继承 实例化子类可以给父类传参
}
SuperMan.prototype = Person.prototype; // 因为上面已经继承了父类的构造函数中的属性和方法,剩下我们只需要继承原型链就好了
var superman = new SuperMan("超级夏诺风", 19); // 原型链继承的时候,我们没有办法给父类传参数
superman.run(); // 输出 “超级夏诺风正在跑步”
基本涵盖了ES5中的类创建和类继承的实现方式,初次总结希望大家喜欢,有不足之处也希望大家指出。