Prototype Class对象学习_prototype
/* Based on Alex Arnell's inheritance implementation. */
var Class = (function() {
//临时存储parent的prototype
function subclass() {};
//创建类的方法
function create() {
var parent = null, properties = $A(arguments);
//检查新建一个类时,是否指定了一个父对象
//如果指定了父类,赋值给parent
if (Object.isFunction(properties[0]))
parent = properties.shift();
//真正用作返回的类,在创建实例时,将调用initialize方法进行初始化
function klass() {
this.initialize.apply(this, arguments);
}
//给klass添加addMethods方法,在调用create方法之后
//仍可以调用addMethods方法进行类级别的方法扩充
Object.extend(klass, Class.Methods);
//给返回的类添加两个属性,superclass:父类,subclasses:子类的集合
klass.superclass = parent;
klass.subclasses = [];
//如果创建类时指定了父对象,则把klass的原型指向父对象的实例,实现原型链继承
if (parent) {
subclass.prototype = parent.prototype;
klass.prototype = new subclass;
//为父类添加子类,维护父类的子类集合
parent.subclasses.push(klass);
}
//向新类添加方法
for (var i = 0; i klass.addMethods(properties[i]);
//如果没有指定初始化方法,则默认把一个空方法赋给初始化方法
if (!klass.prototype.initialize)
klass.prototype.initialize = Prototype.emptyFunction;
/*
* 修正新类的构造函数,使得构造函数指向自己,这里特意说一下(如果注释掉下面这行):
* var Person=Class.create();
* var p1=new Person();
* alert(p1.constructor==Person) //true
* var Man=Class.create(Person)
* var m1=new Man();
* alert(m1.constrcutor==Man) //false
* alert(m1.constrcutor==Person) //true
* alert(m1.construcctor==p1.constrcutor) //true
*
* 看出问题来了吧?Man的构造函数竟然指向了Person的构造函数
* 问题的根源在klass.prototype = new subclass;这句话
* 具体原因我就不解释了,要详细理解的请查看《JavaScript语言精髓与编程实践》155~160页
*/
klass.prototype.constructor = klass;
return klass;
}
//把创建类时的方法添加到新类,或者在创建完类之后在添加类级别的方法
function addMethods(source) {
//取得新类的父类
var ancestor = this.superclass && this.superclass.prototype;
var properties = Object.keys(source);
//貌似下面的判断总是为真,不知道为什么这么写,知道的告诉我?
if (!Object.keys({ toString: true }).length) {
//如果新类重写了toString和valueOf方法则添加之
if (source.toString != Object.prototype.toString)
properties.push("toString");
if (source.valueOf != Object.prototype.valueOf)
properties.push("valueOf");
}
//遍历所有的新类声明中的方法
for (var i = 0, length = properties.length; i //property是函数名称,value是函数体
var property = properties[i], value = source[property];
//判断这个方法是否需要调用父类的同名方法
if (ancestor && Object.isFunction(value) &&
value.argumentNames().first() == "$super") {
var method = value;
//这里很重要!
//替换$super参数,使得这个参数指向父类的同名方法
//这里应用了Function的wrap方法,wrap方法的解释请参考【Prototype 学习——Function对象】
//method是新定义的方法,所以他的第一个参数为$super,然后从'='到'.'之间返回的是父类的同名方法
//最后调用wrap方法把$super参数替换成父类的同名方法,这样在子类调用$super()时,将调用父类的同名方法
//这里构造的非常棒!值得思考
value = (function(m) {
return function() { return ancestor[m].apply(this, arguments); };
})(property).wrap(method);
//将新产生的value(即经过修改过的子类方法)的valueOf和toString指向原子类的同名方法
//这里是在修正调用wrap方法之后的遗留问题
value.valueOf = method.valueOf.bind(method);
value.toString = method.toString.bind(method);
}
//把方法添加到新类中
this.prototype[property] = value;
}
return this;
}
//返回Class的可调用方法
return {
create: create,
Methods: {
addMethods: addMethods
}
};
})();
这个类就提供了2个方法:create和addMethods,上面的源码注释中已经说明的很清楚了,下面就看些例子,具体说明一下用法:
//声明Person类,并定义初始化方法
var Person = Class.create({
initialize: function(name) {
this.name = name;
},
say: function(message) {
return this.name + ': ' + message;
}
});
// when subclassing, specify the class you want to inherit from
var Pirate = Class.create(Person, {
// redefine the speak method
//注意这里的$super用法,在对照源码中的解释仔细看一下
say: function($super, message) {
return $super(message) + ', yarr!';
}
});
var john = new Pirate('Long John');
john.say('ahoy matey');
// -> "Long John: ahoy matey, yarr!"
var john = new Pirate('Long John');
john.sleep();
// -> ERROR: sleep is not a method
// every person should be able to sleep, not just pirates!
//这里是addMethods的用法,可以在类级别扩充方法
Person.addMethods({
sleep: function() {
return this.say('ZzZ');
}
});
john.sleep();
//这里是superclass和subclasses两个属性的用法
Person.superclass
// -> null
Person.subclasses.length
// -> 1
Person.subclasses.first() == Pirate
// -> true
Pirate.superclass == Person
// -> true
三个例子几本覆盖了Class类的方法,详细例子请参考:http://prototypejs.org/learn/class-inheritance

热AI工具

Undresser.AI Undress
人工智能驱动的应用程序,用于创建逼真的裸体照片

AI Clothes Remover
用于从照片中去除衣服的在线人工智能工具。

Undress AI Tool
免费脱衣服图片

Clothoff.io
AI脱衣机

AI Hentai Generator
免费生成ai无尽的。

热门文章

热工具

记事本++7.3.1
好用且免费的代码编辑器

SublimeText3汉化版
中文版,非常好用

禅工作室 13.0.1
功能强大的PHP集成开发环境

Dreamweaver CS6
视觉化网页开发工具

SublimeText3 Mac版
神级代码编辑软件(SublimeText3)

JavaScript字符串替换方法详解及常见问题解答 本文将探讨两种在JavaScript中替换字符串字符的方法:在JavaScript代码内部替换和在网页HTML内部替换。 在JavaScript代码内部替换字符串 最直接的方法是使用replace()方法: str = str.replace("find","replace"); 该方法仅替换第一个匹配项。要替换所有匹配项,需使用正则表达式并添加全局标志g: str = str.replace(/fi

因此,在这里,您准备好了解所有称为Ajax的东西。但是,到底是什么? AJAX一词是指用于创建动态,交互式Web内容的一系列宽松的技术。 Ajax一词,最初由Jesse J创造

10款趣味横生的jQuery游戏插件,让您的网站更具吸引力,提升用户粘性!虽然Flash仍然是开发休闲网页游戏的最佳软件,但jQuery也能创造出令人惊喜的效果,虽然无法与纯动作Flash游戏媲美,但在某些情况下,您也能在浏览器中获得意想不到的乐趣。 jQuery井字棋游戏 游戏编程的“Hello world”,现在有了jQuery版本。 源码 jQuery疯狂填词游戏 这是一个填空游戏,由于不知道单词的上下文,可能会产生一些古怪的结果。 源码 jQuery扫雷游戏

本教程演示了如何使用jQuery创建迷人的视差背景效果。 我们将构建一个带有分层图像的标题横幅,从而创造出令人惊叹的视觉深度。 更新的插件可与JQuery 1.6.4及更高版本一起使用。 下载

本文讨论了在浏览器中优化JavaScript性能的策略,重点是减少执行时间并最大程度地减少对页面负载速度的影响。

Matter.js是一个用JavaScript编写的2D刚体物理引擎。此库可以帮助您轻松地在浏览器中模拟2D物理。它提供了许多功能,例如创建刚体并为其分配质量、面积或密度等物理属性的能力。您还可以模拟不同类型的碰撞和力,例如重力摩擦力。 Matter.js支持所有主流浏览器。此外,它也适用于移动设备,因为它可以检测触摸并具有响应能力。所有这些功能都使其值得您投入时间学习如何使用该引擎,因为这样您就可以轻松创建基于物理的2D游戏或模拟。在本教程中,我将介绍此库的基础知识,包括其安装和用法,并提供一

本文演示了如何使用jQuery和ajax自动每5秒自动刷新DIV的内容。 该示例从RSS提要中获取并显示了最新的博客文章以及最后的刷新时间戳。 加载图像是选择
