复制代码 代码如下:
/* 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 < properties.length; 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 < 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

华山资源网 Design By www.eoogi.com
广告合作:本站广告合作请联系QQ:858582 申请时备注:广告合作(否则不回)
免责声明:本站资源来自互联网收集,仅供用于学习和交流,请遵循相关法律法规,本站一切资源不代表本站立场,如有侵权、后门、不妥请联系本站删除!
华山资源网 Design By www.eoogi.com

稳了!魔兽国服回归的3条重磅消息!官宣时间再确认!

昨天有一位朋友在大神群里分享,自己亚服账号被封号之后居然弹出了国服的封号信息对话框。

这里面让他访问的是一个国服的战网网址,com.cn和后面的zh都非常明白地表明这就是国服战网。

而他在复制这个网址并且进行登录之后,确实是网易的网址,也就是我们熟悉的停服之后国服发布的暴雪游戏产品运营到期开放退款的说明。这是一件比较奇怪的事情,因为以前都没有出现这样的情况,现在突然提示跳转到国服战网的网址,是不是说明了简体中文客户端已经开始进行更新了呢?