如何在JavaScript中实现简单的继承?
下面的例子将创建一个雇员类Employee,它从Person继承了原型prototype中的所有属性。
function Employee(name, sex, employeeID) { this.name = name; this.sex = sex; this.employeeID = employeeID; } // 将Employee的原型指向Person的一个实例 // 因为Person的实例可以调用Person原型中的方法, 所以Employee的实例也可以调用Person原型中的所有属性。 Employee.prototype = new Person(); Employee.prototype.getEmployeeID = function() { return this.employeeID; }; var zhang = new Employee("ZhangSan", "man", "1234"); console.log(zhang.getName()); // "ZhangSan
上面关于继承的实现很粗糙,并且存在很多问题:
正因为JavaScript本身没有完整的类和继承的实现,并且我们也看到通过手工实现的方式存在很多问题, 因此对于这个富有挑战性的任务网上已经有很多实现了:
这篇文章将会给出一个可行的实例代码具体分析这些实现,最终达到对JavaScript中如何实现类和继承,希望对你理解JavaScript有一定的帮助。
( function() { jClass = function() { }; // 当前是否处于创建类的阶段 var initializing = false; jClass.extend = function( prop ) { var baseClass = null; // 如果调用当前函数的对象(这里是函数)不是Class,则是父类 if ( this !== jClass ) { baseClass = this; } // 本次调用所创建的类(构造函数) var jConstructor = function() { // 如果当前处于实例化类的阶段,则调用init原型函数 if ( !initializing ) { // 如果父类存在,则实例对象的baseprototype指向父类的原型 // 这就提供了在实例对象中调用父类方法的途径 if ( baseClass ) { this._superprototype = baseClass.prototype; } this.init.apply( this, arguments ); } } // 如果此类需要从其它类扩展 if ( baseClass ) { initializing = true; jConstructor.prototype = new baseClass(); jConstructor.prototype.constructor = jConstructor; initializing = false; } // 新创建的类自动附加extend函数 jConstructor.extend = arguments.callee; // 覆盖父类的同名函数 for ( var name in prop ) { if ( prop.hasOwnProperty( name ) ) { // 如果此类继承自父类baseClass,并且父类原型中存在同名函数name if ( baseClass && typeof ( prop[name] ) === "function" && typeof ( jConstructor.prototype[name] ) === "function" && /\b_super\b/.test( prop[name] ) ) { // 重定义函数name - // 首先在函数上下文设置this._super指向父类原型中的同名函数 // 然后调用函数prop[name],返回函数结果 // 注意:这里的自执行函数创建了一个上下文,这个上下文返回另一个函数, // 此函数中可以应用此上下文中的变量,这就是闭包(Closure)。 // 这是JavaScript框架开发中常用的技巧。 jConstructor.prototype[name] = ( function( name, fn ) { return function() { this._super = baseClass.prototype[name]; return fn.apply( this, arguments ); }; } )( name, prop[name] ); } else { jConstructor.prototype[name] = prop[name]; } } } return jConstructor; }; } )(); // Demo var Person = jClass.extend( { init: function( name ) { this.name = name; }, getName: function( prefix ) { return prefix + this.name; } } ); var Employee = Person.extend( { init: function( name, employeeID ) { // 调用父类的方法 this._super( name ); this.employeeID = employeeID; }, getEmployeeIDName: function() { // 注意:我们还可以通过这种方式调用父类中的其他函数 var name = this._superprototype.getName.call( this, "Employee name: " ); return name + ", Employee ID: " + this.employeeID; }, getName: function() { // 调用父类的方法 return this._super( "Employee name: " ); } } ); var zhang = new Employee( "ZhangSan", "1234" ); console.log( zhang.getName( ) ); // "Employee name: ZhangSan" console.log( zhang.getEmployeeIDName() ); // "Employee name: ZhangSan, Employee ID: 1234"
JavaScript继承的实现,布布扣,bubuko.com
原文:http://blog.csdn.net/zyb_icanplay7/article/details/30084719