一、类, 类的实例
1: 类: 具有相同类型的一类实例的逻辑描述;
2: 类的实例: 被构造函数出来的具有这个类的实例特征的一个表;
3: 类的成员函数: 完成对应的逻辑,通过this来操作不通的实例;
// 类的构造函数 function Person(name, age) { this.name = name; this.age = age; } // 类的方法: --> 类的成员函数 // 通过this,来操作 类的实例来完成特定的逻辑; Person.prototype.get_age = function() { return this.age; } Person.prototype.get_name = function() { return this.name; } // end var xiaoming = new Person("xiaoming", 12); // new Person等价于自己构造了一个my_person对象 var my_person = { name: "xxxxx", age: 12, __proto__: { get_name: Person.prototype.get_name, get_age: Person.prototype.get_age, } }; var xiaohong = new Person("xiaohong", 13); var xiaotian = new Person("xiaotian", 13); console.log(xiaotian); console.log(xiaohong); console.log(xiaoming); xiaotian.get_name(); xiaoming.get_name(); xiaotian.get_name(); // xiaotian, xiaoming, xiaohong 者三个实例都有相同的结构: // 1:每个人实例 都有 name, age, // 2: 每个实例都有一个 (函数)方法get_name, get_age; // 他们者三个实例,属于同一个类型; // 他们三个实例,都是Person类 // 把Person看作是一个类, xiaotian, xiaoming,xiaohong可以看作是 // 类的 3个实例; // Enemy.js // 类 function Enemy(name, level) { this.name = name; this.level = level; } Enemy.prototype.attack_player = function() { console.log("attack_player", this); } // Enemy.prototype这个表我们又把他叫做 类原型; // 类结束 module.exports = Enemy; var Enemy = require("./Enemy") var e1 = new Enemy("e1", 1); e1.attack_player(); var e2 = new Enemy("e2", 2); e2.attack_player();
二、原型引用
1:每个函数对象都有prototype属性;
3: clone一个函数对象的prototype;
(1)定义一个空函数;
(2)空函数的prototype = 函数对象的prototype;
(3) 新构造函数.prototype = new 空函数();
// 写法2 var a = function() {} // 为什么用空函数,是因为继承时不需要父类的属性 a.prototype = Enemy.prototype; BossEnemy.prototype = new a(); // {__proto_: Enemy原型} // 获取到原型以后,那么我就继承了 Enemy 的原型方法; BossEnemy.prototype.boss_attack = function() { console.log("boss_attack"); }
三、js实现继承
1: 子类clone 基类构造函数的prototype;
2: 子类和基类如果有同名的方法,会现在当前这个类的函数;
3: 子类的实例显示的调用基类的函数
基类.prototype.函数名字.call(实例, 参数1,参数2);
4: 编写一个Class()方法来定义一个类,让它继承基类;
// 继承机制: 猫的代码---> 波斯猫的代码 // 敌人--> 特殊的敌人 --> 原来敌人的基础上--> 继承原来的代码, --> 添加; // step1: 创建一个BossEnemy的构造函数; function BossEnemy(name, level) { // 调用基类的构造函数 Enemy.call(this, name, level) // 扩展自己的成员; this.blood = 100; } // step2: 把Enemy里面所有的原型方法,都复制过来; // BossEnemy.prototype = Enemy.prototype; // 不可以直接这样; // 写法1 /*BossEnemy.prototype = {}; for(var i in Enemy.prototype) { BossEnemy.prototype[i] = Enemy.prototype[i]; }*/ // end // 写法2 var a = function() {} // 为什么用空函数,是因为继承时不需要父类的属性 a.prototype = Enemy.prototype; BossEnemy.prototype = new a(); // {__proto_: Enemy原型} // 获取到原型以后,那么我就继承了 Enemy 的原型方法; BossEnemy.prototype.boss_attack = function() { console.log("boss_attack"); } var boss = new BossEnemy("通天教主", 10); boss.boss_attack(); boss.attack_player(); BossEnemy.prototype.attack_player = function() { Enemy.prototype.attack_player.call(this); console.log("BossEnemy get name"); return this.name; } boss.attack_player(); // javascript 没有类,继承语法的, new, this, 模拟 // 有些地方些了一个继承函数; // 这个Class函数,能帮我们得到新的类 function Class(class_desic) { var new_class = function(name, level) { if (class_desic.extend) { // 有基类 class_desic.extend.call(this, name, level); } if (class_desic.init) { class_desic.init.call(this); } } if (class_desic.extend) { var a = function() {}; a.prototype = class_desic.extend.prototype; new_class.prototype = new a(); } else { new_class.prototype = {}; } for(var i in class_desic) { if (i == "extend") { continue; } new_class.prototype[i] = class_desic[i]; } return new_class; } var BossEnemy2 = Class({ // 定义写死的关键字 extend 是继承自那个基类 extend: Enemy, // 对象的名字 init: function(){ }, boss_attack: function() { }, add_blood: function() { console.log("add_blood", this); }, }); var b2 = new BossEnemy2("boss2", 1111); console.log(b2); b2.add_blood();