`

JS Class继承类:模拟面向对象继承

阅读更多

使用方式:

 

/**
 * Person = Class.extend({
 * 		init: function(){}
 * });
 * 
 * Student = Person.extend({
 * 		init: function(){}
 * });
 */

 源代码:

/**废弃该方式,采用base.js         (function() {
	var k = false, 
	t = /xyz/.test(function() {}) ? /\b_super\b/ : /.*/;
	this.Class = function() {
	};
	Class.extend = function(q) {
		function w() {
			!k && this.init && this.init.apply(this, arguments)
		}
		var K = this.prototype;
		k = true;
		var O = new this;
		k = false;
		for ( var C in q)
			O[C] = typeof q[C] == "function" 
				&& typeof K[C] == "function"
				&& t.test(q[C]) 
				? function(fa, qa) {
					return function() {
						var p = this._super;
						this._super = K[fa];
						var u = qa.apply(this, arguments);
						this._super = p;
						return u
					}
				}(C, q[C]) : q[C];
		w.prototype = O;
		w.constructor = w;
		w.extend = arguments.callee;
		return w;
	};
})();*/
Base.js
/*
	Base.js, version 1.1a
	Copyright 2006-2009, Dean Edwards
	License: http://www.opensource.org/licenses/mit-license.php
*/

var Base = function() {
	// dummy
};

Base.extend = function(_instance, _static) { // subclass
	var extend = Base.prototype.extend;
	
	// build the prototype
	Base._prototyping = true;
	var proto = new this;
	extend.call(proto, _instance);
	proto.base = function() {
		// call this method from any other method to invoke that method's ancestor
	};
	delete Base._prototyping;
	
	// create the wrapper for the constructor function
	//var constructor = proto.constructor.valueOf(); //-dean
	var constructor = proto.constructor;
	var klass = proto.constructor = function() {
		if (!Base._prototyping) {
			if (this._constructing || this.constructor == klass) { // instantiation
				this._constructing = true;
				constructor.apply(this, arguments);
				delete this._constructing;
			} else if (arguments[0] != null) { // casting
				return (arguments[0].extend || extend).call(arguments[0], proto);
			}
		}
	};
	
	// build the class interface
	klass.ancestor = this;
	klass.extend = this.extend;
	klass.forEach = this.forEach;
	klass.implement = this.implement;
	klass.prototype = proto;
	klass.toString = this.toString;
	klass.valueOf = function(type) {
		//return (type == "object") ? klass : constructor; //-dean
		return (type == "object") ? klass : constructor.valueOf();
	};
	extend.call(klass, _static);
	// class initialisation
	if (typeof klass.init == "function") klass.init();
	return klass;
};

Base.prototype = {	
	extend: function(source, value) {
		if (arguments.length > 1) { // extending with a name/value pair
			var ancestor = this[source];
			// overriding a method?
			// the valueOf() comparison is to avoid circular references
			if (ancestor && (typeof value == "function") && 
				(!ancestor.valueOf || ancestor.valueOf() != value.valueOf()) &&
				/\bbase\b/.test(value)) {
				// get the underlying method
				var method = value.valueOf();
				// override
				value = function() {
					var previous = this.base || Base.prototype.base;
					this.base = ancestor;
					var returnValue = method.apply(this, arguments);
					this.base = previous;
					return returnValue;
				};
				// point to the underlying method
				value.valueOf = function(type) {
					return (type == "object") ? value : method;
				};
				value.toString = Base.toString;
			}
			this[source] = value;
		} else if (source) { // extending with an object literal
			var extend = Base.prototype.extend;
			// if this object has a customised extend method then use it
			if (!Base._prototyping && typeof this != "function") {
				extend = this.extend || extend;
			}
			var proto = {toSource: null};
			// do the "toString" and other methods manually
			var hidden = ["constructor", "toString", "valueOf"];
			// if we are prototyping then include the constructor
			var i = Base._prototyping ? 0 : 1;
			while (key = hidden[i++]) {
				if (source[key] != proto[key]) {
					extend.call(this, key, source[key]);

				}
			}
			// copy each of the source object's properties to this object
			for (var key in source) {
				if (!proto[key]) extend.call(this, key, source[key]);
			}
		}
		return this;
	}
};

// initialise
Base = Base.extend({
	constructor: function() {
		this.extend(arguments[0]);
	}
}, {
	ancestor: Object,
	version: "1.1",
	
	forEach: function(object, block, context) {
		for (var key in object) {
			if (this.prototype[key] === undefined) {
				block.call(context, object[key], key, object);
			}
		}
	},
		
	implement: function() {
		for (var i = 0; i < arguments.length; i++) {
			if (typeof arguments[i] == "function") {
				// if it's a function, call it
				arguments[i](this.prototype);
			} else {
				// add the interface using the extend method
				this.prototype.extend(arguments[i]);
			}
		}
		return this;
	},
	
	toString: function() {
		return String(this.valueOf());
	}
});

Class = Base;

分享到:
评论

相关推荐

    猜拳游戏:java面向对象,kotlin面向对象,js面向对象,3个方法开发.zip

    4. ES6 Class:JavaScript从ES6开始引入了类的语法糖,使得类的定义更接近传统面向对象语言。 5. 静态方法:在类上定义的方法,不属于任何实例,而是属于类本身。 这个猜拳游戏项目提供了丰富的学习材料,无论你是...

    Javascript 面向对象的JavaScript进阶

    在探讨面向对象的JavaScript之前,我们首先需要了解面向对象编程(Object-Oriented Programming, OOP)的基本特性:封装性、抽象性、继承性和多态性。 ##### 8.1.1 封装性 **定义:** 封装性是面向对象编程的一个...

    JavaScript面向对象编程指南

    在没有类的情况下,JavaScript使用原型式继承模拟面向对象概念。`Object.create`函数可以创建一个新的对象,该对象的原型是传入的第一个参数。 5. **构造函数、实例和`this`关键字** `this`在JavaScript中表示...

    javascript 经典面向对象设计

    ### JavaScript经典面向对象设计 #### 标题与描述解析 标题“JavaScript经典面向对象设计”指出了本书的主要内容是关于如何使用面向对象编程(OOP)原则和技术来编写高质量、可扩展且可重用的JavaScript应用程序及...

    javascript面向对象包装类Class封装类库剖析.docx

    MY-CLASS类库提供了类似于类的语法糖,使得JavaScript的面向对象编程更加接近于传统的类继承模式,这对于习惯于其他面向对象语言的开发者来说更容易理解。通过这样的封装,可以更好地管理和组织代码,减少重复,同时...

    JS面向对象汇总PDF

    **JS面向对象汇总PDF**是针对JavaScript编程语言中面向对象编程概念的一个综合性的学习资料,主要探讨了JavaScript如何实现面向对象编程(OOP)的设计原则和模式。在JavaScript中,面向对象编程是一种重要的编程范式...

    adm-jclass: 一个面向对象编程的js库

    在JavaScript中,虽然原生支持函数作为一等公民,可以模拟面向对象的特性,但`adm-jclass` 提供了更高级别的抽象,使得类的定义和使用更为直观和简洁。通过这个库,开发者可以创建具有私有属性和方法、构造函数、...

    2008年图书:面向对象的JavaScript

    8. **类(Class)**:虽然2008年的JavaScript版本还不支持ES6的类语法,但书可能讲解了如何模拟类的行为,例如使用构造函数和原型。 9. **类型系统(Type System)**:JavaScript是一种动态类型语言,书中会解释...

    js面向对象笔记

    JavaScript 通过构造函数和原型来模拟面向对象编程中的类和实例,而通过原型链可以实现对象之间的继承关系。 总之,JavaScript 面向对象编程虽然没有传统意义上的类和继承,但是通过构造函数和原型对象,以及原型链...

    Javascript面向对象基础.rar

    在这个“JavaScript面向对象基础”的资料中,我们将会探讨JavaScript中的类、对象、封装、继承以及多态等关键概念。 1. **对象与对象字面量** 在JavaScript中,对象是由键值对组成的无序集合,可以使用对象字面量...

    在JavaScript中模拟类(class)及类的继承关系_.docx

    在JavaScript中,尽管ES6之前其语法并不直接支持类(class)的概念,但...随着ES6的引入,JavaScript现在有了更接近传统类语法的`class`关键字,但上述的模拟方法仍然是理解JavaScript面向对象编程基础的重要部分。

    Javascript面向对象基础

    ES6引入了`class`语法糖,使得JavaScript的面向对象编程更接近传统的类式语言。虽然在底层仍然基于原型,但`class`提供了更简洁的定义构造函数、方法和继承的方式。例如,`class Student extends Person { ...

    JavaScript面向对象编程

    面向对象编程的核心概念包括类、对象、封装、继承和多态。 1. 类与对象 在面向对象编程中,类可以看作是一个模板或者蓝图,用于创建具有相同属性和方法的对象。JavaScript中的类是从ES6开始引入的,但在此之前,...

    javaScript面向对象继承方法经典实现.docx

    以下是两种经典的JavaScript面向对象继承方法的详细解释: 1. **基于原型的继承**: 这种方法是JavaScript最基础的继承方式,通过`prototype`属性实现。在提供的代码示例中,首先定义了一个`Pet`对象,它有一个...

    javascript面向对象教程

    JavaScript并非传统的面向对象语言,它不支持类(class)的概念,而是采用基于原型(prototype)的继承机制。这意味着对象可以直接从其他对象继承属性和方法,而不是从类实例化。JavaScript的类型系统包括五种基本...

    javascript中类和继承(代码示例+prototype.js)

    在JavaScript中,类和继承是面向对象编程的重要概念。JavaScript是一种动态类型的语言,它没有像Java或C++那样的传统类,而是使用函数作为构造器来模拟类的行为,并通过原型链实现继承。本文将深入探讨JavaScript中...

Global site tag (gtag.js) - Google Analytics