标签:javascript
下面这段代码是javascrip inherit 的一段继承的代码我倒持了一早上才搞明白其中的道理,最主要是里面有一些平时我们不怎么使用的函数和方法。比较迷惑人。现在我就针对这些代码做一些自己的注解:(当然他也有一些英文注解,但是不够清楚明白,我们也可以后期改造这个方法,让他更适合我们自己的使用)
/* Simple JavaScript Inheritance
* By John Resig http://ejohn.org/
* MIT Licensed.
*/
// Inspired by base2 and Prototype
(function(){
//方法在继承的时候会类似java等具有继承特性的语言一样,初始化上级父类中的方法和属性。
//initializing 这个属性主要是用来作为是否初始化过的一个变量。
var initializing = false;
//这个是需要特殊对待的一段代码,这段代码在后面进行覆盖父类属性中用到了判断是否是函数,且是否存在上级父类方法的判断条件。如果对这个有什么疑问查看我转载的另一篇关于该代码的博文。
fnTest = /xyz/.test(function(){xyz;}) ? /\b_super\b/ : /.*/;
// The base Class implementation (does nothing)
//基类的实现,这个地方只是声明一下Class基类而已,啥事也不干。
this.Class = function(){};
// Create a new Class that inherits from this class
//这是声明Class基类的继承方法,同时带着的参数需要特殊说明:prop就是后面我们调用extend方法的时候传进去的参数。
Class.extend = function(prop) {
//_super 是特别有用的属性。是用来存储父类属性的数组。使得后面继承的类可以用this._super.xxx调用父类属性。
var _super = this.prototype;
// Instantiate a base class (but only create the instance,
// don‘t run the init constructor)
initializing = true;
//首先创建一个自己的对象,这样就会把对象的所有属性拷贝在了prototype中,在第一次调用Class.extend时,new this()生成的是没有特殊属性的父类对象。
var prototype = new this();
initializing = false;
// Copy the properties over onto the new prototype
//这里想必大家在看英文注释已经搞明白是怎么回事了,对,就是拷贝属性。在这里面就只做了这么一件事情。但是这里面有覆盖的逻辑在里面。还有创建父类子类调用关系链。
for (var name in prop) {//循环所有属性
// Check if we‘re overwriting an existing function
//检查父类的方法,如果父类存在相同名字的方法则覆盖父类的方法。在javascript里面方法参数是可以多传或者少传,有点像java里面的动态参数。所以不存在方法多态(重载),相同名字就直接重写了。
prototype[name] = typeof prop[name] == "function" &&
typeof _super[name] == "function" && fnTest.test(prop[name]) ?
(function(name, fn){
return function() {
//暂时保存自己调用父类的引用
var tmp = this._super;
// Add a new ._super() method that is the same method
// but on the super-class
//创建自己的super的引用
this._super = _super[name];
// The method only need to be bound temporarily, so we
// remove it when we‘re done executing
//这里涉及到了一个很陌生的方法是apply,和这个方法很类似的方法有一个call方法,也就是fn的方法重新绑定一下参数,this指的是本段funciton本身。arguments指的是传入的参数。也就是无论fn中传入什么参数,这里返回的ret就会绑定参数。
var ret = fn.apply(this, arguments);
//再把父类的引用设置回来
this._super = tmp;
//返回方法调用本身
return ret;
};
})(name, prop[name]) :
prop[name];//如果父类不存在则放回方法本身
}
//这是构造方法
// The dummy class constructor
function Class() {
// All construction is actually done in the init method
if ( !initializing && this.init )
this.init.apply(this, arguments);
}
//将重新生成的属性赋给Class,这个Class不是基类Class而是生成的对象自己。也就是可以
// Populate our constructed prototype object
Class.prototype = prototype;
//构造函数引用
// Enforce the constructor to be what we expect
Class.prototype.constructor = Class;
//callee这个方法会把本段extend方法赋给Class的extend方法,这样新生成的类也可以实现继承
// And make this class extendable
Class.extend = arguments.callee;
return Class;
};
})();
标签:javascript
原文地址:http://snaile.blog.51cto.com/8061810/1605274