使用方式:
/**
* 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;
分享到:
相关推荐
4. ES6 Class:JavaScript从ES6开始引入了类的语法糖,使得类的定义更接近传统面向对象语言。 5. 静态方法:在类上定义的方法,不属于任何实例,而是属于类本身。 这个猜拳游戏项目提供了丰富的学习材料,无论你是...
在探讨面向对象的JavaScript之前,我们首先需要了解面向对象编程(Object-Oriented Programming, OOP)的基本特性:封装性、抽象性、继承性和多态性。 ##### 8.1.1 封装性 **定义:** 封装性是面向对象编程的一个...
在没有类的情况下,JavaScript使用原型式继承模拟面向对象概念。`Object.create`函数可以创建一个新的对象,该对象的原型是传入的第一个参数。 5. **构造函数、实例和`this`关键字** `this`在JavaScript中表示...
### JavaScript经典面向对象设计 #### 标题与描述解析 标题“JavaScript经典面向对象设计”指出了本书的主要内容是关于如何使用面向对象编程(OOP)原则和技术来编写高质量、可扩展且可重用的JavaScript应用程序及...
MY-CLASS类库提供了类似于类的语法糖,使得JavaScript的面向对象编程更加接近于传统的类继承模式,这对于习惯于其他面向对象语言的开发者来说更容易理解。通过这样的封装,可以更好地管理和组织代码,减少重复,同时...
**JS面向对象汇总PDF**是针对JavaScript编程语言中面向对象编程概念的一个综合性的学习资料,主要探讨了JavaScript如何实现面向对象编程(OOP)的设计原则和模式。在JavaScript中,面向对象编程是一种重要的编程范式...
在JavaScript中,虽然原生支持函数作为一等公民,可以模拟面向对象的特性,但`adm-jclass` 提供了更高级别的抽象,使得类的定义和使用更为直观和简洁。通过这个库,开发者可以创建具有私有属性和方法、构造函数、...
8. **类(Class)**:虽然2008年的JavaScript版本还不支持ES6的类语法,但书可能讲解了如何模拟类的行为,例如使用构造函数和原型。 9. **类型系统(Type System)**:JavaScript是一种动态类型语言,书中会解释...
JavaScript 通过构造函数和原型来模拟面向对象编程中的类和实例,而通过原型链可以实现对象之间的继承关系。 总之,JavaScript 面向对象编程虽然没有传统意义上的类和继承,但是通过构造函数和原型对象,以及原型链...
在这个“JavaScript面向对象基础”的资料中,我们将会探讨JavaScript中的类、对象、封装、继承以及多态等关键概念。 1. **对象与对象字面量** 在JavaScript中,对象是由键值对组成的无序集合,可以使用对象字面量...
在JavaScript中,尽管ES6之前其语法并不直接支持类(class)的概念,但...随着ES6的引入,JavaScript现在有了更接近传统类语法的`class`关键字,但上述的模拟方法仍然是理解JavaScript面向对象编程基础的重要部分。
ES6引入了`class`语法糖,使得JavaScript的面向对象编程更接近传统的类式语言。虽然在底层仍然基于原型,但`class`提供了更简洁的定义构造函数、方法和继承的方式。例如,`class Student extends Person { ...
面向对象编程的核心概念包括类、对象、封装、继承和多态。 1. 类与对象 在面向对象编程中,类可以看作是一个模板或者蓝图,用于创建具有相同属性和方法的对象。JavaScript中的类是从ES6开始引入的,但在此之前,...
以下是两种经典的JavaScript面向对象继承方法的详细解释: 1. **基于原型的继承**: 这种方法是JavaScript最基础的继承方式,通过`prototype`属性实现。在提供的代码示例中,首先定义了一个`Pet`对象,它有一个...
JavaScript并非传统的面向对象语言,它不支持类(class)的概念,而是采用基于原型(prototype)的继承机制。这意味着对象可以直接从其他对象继承属性和方法,而不是从类实例化。JavaScript的类型系统包括五种基本...
在JavaScript中,类和继承是面向对象编程的重要概念。JavaScript是一种动态类型的语言,它没有像Java或C++那样的传统类,而是使用函数作为构造器来模拟类的行为,并通过原型链实现继承。本文将深入探讨JavaScript中...