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