当前位置: 澳门新濠3559 > 服务器运维 > 正文

//创建类的方法,但是这对像JavaScript这样的弱类

时间:2019-12-26 07:51来源:服务器运维
函数 [javascript] function Person(name) {           this.name = name;       }       Person.method("getName", function () { return this.name; });       function User(name, password) {           this.name =

函数

[javascript]
function Person(name) { 
         this.name = name; 
     } 
     Person.method("getName", function () { return this.name; }); 
     function User(name, password) { 
         this.name = name; 
         this.password = password; 
     } 
     User.inherits(Person); 
     User.method("getPassword", function () { return this.password; }); 
     User.method("getName", function () { return "My name is :" + this.uber("getName"); }); 
 
     var p = new Person("123"); 
     alert(p.getName()); 
     var u = new User("abc", "456"); 
     alert(u.getPassword()); 
     alert(u.getName()); 
   function Person(name) {
            this.name = name;
        }
        Person.method("getName", function () { return this.name; });
        function User(name, password) {
            this.name = name;
            this.password = password;
        }
        User.inherits(Person);
        User.method("getPassword", function () { return this.password; });
        User.method("getName", function () { return "My name is :" + this.uber("getName"); });

//创建类的方法
function create() {
var parent = null, properties = $A(arguments);
    //检查新建一个类时,是否指定了一个父对象
    //如果指定了父类,赋值给parent
if (Object.isFunction(properties[0]))
parent = properties.shift();

构造器

        var User = Person.extend({
            constructor: function (name, password) {
                this.base(name);
                this.password = password;
            },
            getPassWord: function () { return this.password; }
        });

var john = new Pirate('Long John');
john.say('ahoy matey');
// -> "Long John: ahoy matey, yarr!"

Java

Base.prototype = { 
 extend: function(source, value) {
  if (arguments.length > 1) { // extending with a name/value pair
   var ancestor = this[source];
   if (ancestor && (typeof value == "function") && // overriding a method?
    // the valueOf() comparison is to avoid circular references
    (!ancestor.valueOf || ancestor.valueOf() != value.valueOf()) &&
    /bbaseb/.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]);

//这里是superclass和subclasses两个属性的用法

强类型

        var p = new Person("123");
        alert(p.getName());
//创建类的方法,但是这对像JavaScript这样的弱类型语言是无关的。        var u = new User("456", "abc");
        alert(u.getName());
        alert(u.getPassWord());
作者:dz45693  

// 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!';
}
});

函数

在阅读精通JavaScript(图灵计算机科学丛书)里面有讲解javascript继承的一些东东。

//遍历所有的新类声明中的方法
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);

要展示这一点,我们要介绍一个小小的“甜点”可以主我们像一个常规的类语言一样写代码。我们然后会展示一些在类语言中没有的有用的模式。最后,我们会就会解释这些“甜点”。类继承 首先,我们建立一个Parenizor类,它有成员 value的get和set方法,还有一个会将value包装在括号内的toString方法。 复制代码 代码如下: function Parenizor { this.setValue; } Parenizor.method('setValue', function { this.value = value; return this; }); Parenizor.method('getValue', function () { return this.value; }); Parenizor.method('toString', function () { return ' + ')'; }); 这个语法可能没什么用,但它很容易看出其中类的形式。method方法接受一个方法名和一个函数,并把它们放入类中作为公共方法。 现在我们可以写成 复制代码 代码如下: myParenizor = new Parenizor; myString = myParenizor.toString(); 正如期望的那样,myString是 ""。 现在我们要建立另一个继承自Parenizor的类,它基本上是一样的除了toString方法将会产生"-0-"如果value是零或者空。 复制代码 代码如下: function ZParenizor { this.setValue; } ZParenizor.inherits; ZParenizor.method("e;toString"e;, function () { if { return this.uber; } return "-0-"; }); inherits方法类似于Java的extends 。uber方法类似于Java的super。它令一个方法调用父类的方法。 我们可以写成这样 复制代码 代码如下: myZParenizor = new ZParenizor; myString = myZParenizor.toString(); 这次, myString是 "-0-". JavaScript 并没有类,但我们可以编程达到这个目的。 多继承 通过操作一个函数的prototype对象,我们可以实现多继承。混合多继承难以实现而且可能会遭到名称冲突的危险。我们可以在JavaScript中实现混合多继承,但这个例子我们将使用一个较规范的形式称为瑞士继承SwissI nheritance. 假设有一个NumberValue类有一个setValue方法用来检查 value是不是在一个指定范围内的一个数,并在适当的时候抛出异常。我们只要它的setValue和 setRange方法给我们的ZParenizor。我们当然不想要它的toString方法。这样,我们写到: 复制代码 代码如下: ZParenizor.swiss(NumberValue, 'setValue', 'setRange'); 这个将仅仅添加需要的方法。 寄生继承 这是另一个书写 ZParenizor类的方法。并不从 Parenizor继承,而是写了一个调用了Parenizor构造器的构造器,并对结果修改最后返回这个结果。这个构造器添加的是特权方法而非公共方法。 复制代码 代码如下: function ZParenizor2 { var self = new Parenizor; self.toString = function () { if { return this.uber; } return "-0-" }; return self; } 类继承是一种“是……”的关系,而寄生继承是一个关于“原是……而现在是……”的关系。构造器在对象的构造中扮演了大量的角色。注意uber 对特权方法仍有效。 类扩展 JavaScript的动态性让我们可以对一个已有的类添加或替换方法。我们可以在任何时候调用方法。我们可以随时地扩展一个类。继承不是这个方式。所以我们把这种情况称为“类扩展”来避免和Java的extends──也叫扩展,但不是一回事──相混淆。 对象扩展 在静态面向对象语言中,如果你想要一个对象和另一个对象有所区别,你必须新建立一个类。但在JavaScript中,你可以向单独的对象添加方法而不用新建类。这会有巨大的能量因为你就可以书写尽量少的类,类也可以写得更简单。想想JavaScript的对象就像哈希表一样。你可以在任何时候添加新的值。如果这个值是一个函数,那他就会成为一个方法。 这样在上面的例子中,我完全不需要 ZParenizor类。我只要简单修改一下我的实例就行了。 复制代码 代码如下: myParenizor = new Parenizor; myParenizor.toString = function () { if { return this.uber; } return "-0-"; }; myString = myParenizor.toString(); 我们给 myParenizor实例添加了一个 toString方法而没有使用任何继承。我们可以演化单独的实例因为这个语言是无类型的。 小甜点 要让上面的例子运行起来,我写了四个“甜点”方法。首先,method方法,可以把一个实例方法添加到一个类中。 复制代码 代码如下: Function.prototype.method = function { this.prototype[name] = func; return this; }; 这个将会添加一个公共方法到 Function.prototype中,这样通过类扩展所有的函数都可以用它了。它要一个名称和一个函数作为参数。 它返回 this。当我写一个没有返回值的方法时,我通常都会让它返回this。这样可以形成链式语句。 下面是 inherits方法,它会指出一个类是继承自另一个类的。它必须在两个类都定义完了之后才能定义,但要在方法继承之前调用。 复制代码 代码如下: Function.method('inherits', function { var d = 0, p = (this.prototype = new parent; this.method('uber', function uber { var f, r, t = d, v = parent.prototype; if { v = v.constructor.prototype; t -= 1; } f = v[name]; } else { f = p[name]; if { f = v[name]; } } d += 1; r = f.apply(this, Array.prototype.slice.apply; d -= 1; return r; }); return this; }); 再来,我们扩展 Function类。我们加入一个 parent类的实例并将它做为新的prototype。我们也必须修正constructor字段,同时我们加入uber方法。 uber方法将会在自己的prototype中查找某个方法。这个是寄生继承或类扩展的一种情况。如果我们是类继承,那么我们要找到parent的prototype中的函数。return语句调用了函数的apply方法来调用该函数,同时显示地设置this并传递参数。参数可以从arguments数组中获得。不幸的是,arguments数组并不是一个真正的数组,所以我们又要用到apply来调用数组中的slice方法。 最后,swiss方法 复制代码 代码如下: Function.method('swiss', function { for (var i = 1; i < arguments.length; i += 1) { var name = arguments[i]; this.prototype[name] = parent.prototype[name]; } return this; }); The swiss方法对每个参数进行循环。每个名称,它都将parent的原型中的成员复制下来到新的类的prototype中。 总结 JavaScript可以像类语言那样使用,但它也有一种十分独特的表现层次。我们已经看过了类继承、瑞士继承、寄生继承、类扩展和对象扩展。这一等系列代码复用的模式都能来自这个一直被认为是很小、很简单的JavaScript语言。 类对象属于“硬的”。给一个“硬的”对象添加成员的唯一的方法是建立一个新的类。在JavaScript中,对象是“软的”。要给一个“软”对象添加成员只要简单的赋值就行了。 因为JavaScript中的类是这样地灵活,你可能会还想到更复杂的类继承。但深度继承并不合适。浅继承则较有效而且更易表达。

// 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());
 }
});

代码如下: /* Based on Alex Arnell's inheritance implementation. */ var Class = (function() { //临时存储parent的prototype function subclass() {}; //创建类的方...

JavaScript

    }
   }
   // 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;
 }
};

    /*
     * 修正新类的构造函数,使得构造函数指向自己,这里特意说一下(如果注释掉下面这行):
     * 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;
}

动态

[javascript]
/*
    Base.js, version 1.1a
    Copyright 2006-2010, Dean Edwards
    License:
*/ 
 
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]; 
            if (ancestor && (typeof value == "function") && // overriding a method?  
                // the valueOf() comparison is to avoid circular references  
                (!ancestor.valueOf || ancestor.valueOf() != value.valueOf()) && 
                /bbaseb/.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()); 
    } 
}); 
/*
 Base.js, version 1.1a
 Copyright 2006-2010, Dean Edwards
 License:
*/

//把创建类时的方法添加到新类,或者在创建完类之后在添加类级别的方法
function addMethods(source) {
    //取得新类的父类
var ancestor = this.superclass && this.superclass.prototype;
var properties = Object.keys(source);

静态

其一是讲解DouglasCrockford的js

这个类就提供了2个方法:create和addMethods,上面的源码注释中已经说明的很清楚了,下面就看些例子,具体说明一下用法:

但首先,为什么我们如此关心继承呢?主要有两个原因。第一个是类型有利。我们希望语言系统可以自动进行类似类型引用的转换cast。小类型安全可以从一个要求程序显示地转换对象引用的类型系统中获得。这是强类型语言最关键的要点,但是这对像JavaScript这样的弱类型语言是无关的,JavaScript中的类引用无须强制转换。

其一是讲解DouglasCrockford的js 代码如下: [javascript] //简单的辅...

return this;
}

JavaScript一种没有类的,面向对象的语言,它使用原型继承来代替类继承。这个可能对受过传统的面向对象语言训练的程序员来说有点迷惑。JavaScript的原型继承比类继承有更强大的表现力,现在就让我们来看看。

[javascript]
//简单的辅助函数,让你可以将新函数绑定到对象prototype上  
      Function.prototype.method = function (name, func) { 
          this.prototype[name] = func; 
          return this; 
      } 
      //一个相当复杂的函数,允许你方便地从其他对象继承函数,  
      //同时仍然可以调用属于父对象的那些方法  
      Function.method('inherits', function (parent) { 
          var d = {}; //记录我们目前所在父层次的级数  
          var p = (this.prototype = new parent()); //继承父对象的方法  
          //创建一个新的名位uber的特权函数  
          //调用它时会执行所有在继承时被重写的函数  
          this.method("uber", function uber(name) { 
              if (!(name in d)) { 
                  d[name] = 0; //继承级数默认为0  
              } 
              var f, /*要执行的函数*/r, /*函数返回值*/t = d[name], v = parent.prototype; /*父对象的prototype*/ 
              if (t) { 
                  //如果我们已经在某个uber函数内 上溯到必要的级数已找到原始的prototype  
                  while (t) { 
                      v = v.constructor.prototype; 
                      t -= 1; 
                  } 
                  f = v[name]; //从prototype中获得函数  
              } 
              else { 
                  //uber第一次调用 从prototype获得要执行的函数  
                  f = p[name]; 
                  if (f == this[name]) { 
                      //如果函数属于当前prototype 则改为调用父对象的prototype  
                      f = v[name]; 
                  } 
              } 
              d[name] += 1; //记录我们在继承堆栈中所在位置  
              //使用除第一个以外所有的arguments 调用函数 第一个参数是执行的匿名函数名   
              r = f.apply(this, Array.prototype.slice.apply(arguments, [1])); 
              d[name] -= 1; //恢复继承堆栈  
              return r; 
          }); 
          return this; 
      }); 
      //只继承父对象特定的函数。而非使用new parent()的继承的所有函数  
      Function.method("swiss", function (parent) { 
          for (var i = 1; i < arguments.length; i++) { 
              var name = arguments[i]; 
              this.prototype[name] = parent[name]; 
          } 
          return this; 
      }); 
      /* Function.prototype.method 它提供了一个简单的方法,把函数于构造函数原型关联起来。
      之所以有效,是因为所有的构造函数本身都是函数,所以能获得method这个新方法
      Function.prototype.inherits这一函数可以用于提供简单的对象继承,它的代码主要围绕任意对象方法中调用
      this.uber(methodname)为中心,并在让这个uber方法执行它要覆盖的父对象的方法。
      Function.prototype.swiss这是.method函数的增强版,可以用于单一父对象获取多个函数。如果有多个父对象上
      就能获得可用的多对象继承
      */ 
  //简单的辅助函数,让你可以将新函数绑定到对象prototype上
        Function.prototype.method = function (name, func) {
            this.prototype[name] = func;
            return this;
        }  www.2cto.com
        //一个相当复杂的函数,允许你方便地从其他对象继承函数,
        //同时仍然可以调用属于父对象的那些方法
        Function.method('inherits', function (parent) {
            var d = {}; //记录我们目前所在父层次的级数
            var p = (this.prototype = new parent()); //继承父对象的方法
            //创建一个新的名位uber的特权函数
            //调用它时会执行所有在继承时被重写的函数
            this.method("uber", function uber(name) {
                if (!(name in d)) {
                    d[name] = 0; //继承级数默认为0
                }
                var f, /*要执行的函数*/r, /*函数返回值*/t = d[name], v = parent.prototype; /*父对象的prototype*/
                if (t) {
                    //如果我们已经在某个uber函数内 上溯到必要的级数已找到原始的prototype
                    while (t) {
                        v = v.constructor.prototype;
                        t -= 1;
                    }
                    f = v[name]; //从prototype中获得函数
                }
                else {
                    //uber第一次调用 从prototype获得要执行的函数
                    f = p[name];
                    if (f == this[name]) {
                        //如果函数属于当前prototype 则改为调用父对象的prototype
                        f = v[name];
                    }
                }
                d[name] += 1; //记录我们在继承堆栈中所在位置
                //使用除第一个以外所有的arguments 调用函数 第一个参数是执行的匿名函数名
                r = f.apply(this, Array.prototype.slice.apply(arguments, [1]));
                d[name] -= 1; //恢复继承堆栈
                return r;
            });
            return this;
        });
        //只继承父对象特定的函数。而非使用new parent()的继承的所有函数
        Function.method("swiss", function (parent) {
            for (var i = 1; i < arguments.length; i++) {
                var name = arguments[i];
                this.prototype[name] = parent[name];
            }
            return this;
        });
        /* Function.prototype.method 它提供了一个简单的方法,把函数于构造函数原型关联起来。
        之所以有效,是因为所有的构造函数本身都是函数,所以能获得method这个新方法
        Function.prototype.inherits这一函数可以用于提供简单的对象继承,它的代码主要围绕任意对象方法中调用
        this.uber(methodname)为中心,并在让这个uber方法执行它要覆盖的父对象的方法。
        Function.prototype.swiss这是.method函数的增强版,可以用于单一父对象获取多个函数。如果有多个父对象上
        就能获得可用的多对象继承
        */
调用代码:

//如果创建类时指定了父对象,则把klass的原型指向父对象的实例,实现原型链继承
if (parent) {
subclass.prototype = parent.prototype;
klass.prototype = new subclass;
     //为父类添加子类,维护父类的子类集合
parent.subclasses.push(klass);
}

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库

三个例子几本覆盖了Class类的方法,详细例子请参考:

弱类型

[javascript]
var Person = Base.extend({ 
           constructor: function (name) { this.name = name; }, 
           getName: function () { return this.name; } 
       }); 
 
       var User = Person.extend({ 
           constructor: function (name, password) { 
               this.base(name); 
               this.password = password; 
           }, 
           getPassWord: function () { return this.password; } 
       }); 
 
       var p = new Person("123"); 
       alert(p.getName()); 
       var u = new User("456", "abc"); 
       alert(u.getName()); 
       alert(u.getPassWord()); 
 var Person = Base.extend({
            constructor: function (name) { this.name = name; },
            getName: function () { return this.name; }
        });

复制代码 代码如下:

JavaScript Inheritance

        var p = new Person("123");
        alert(p.getName());
        var u = new User("abc", "456");
        alert(u.getPassword());
        alert(u.getName());

//真正用作返回的类,在创建实例时,将调用initialize方法进行初始化
function klass() {
this.initialize.apply(this, arguments);
}

基于原型

代码:

//这里是addMethods的用法,可以在类级别扩充方法
Person.addMethods({
sleep: function() {
return this.say('ZzZ');
}
});
john.sleep();

第二个原因是为了代码的复用。在程序中常常会发现很多对象都会实现同一些方法。类让建立单一的一个定义集中建立对象成为可能。在对象中包含其他对象也包含的对象也是很常见的,但是区别仅仅是一小部分方法的添加或者修改。类继承对这个十分有用,但原型继承甚至更有用。

代码如下:

var Class = (function() {
//临时存储parent的prototype
function subclass() {};

方法

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

//如果没有指定初始化方法,则默认把一个空方法赋给初始化方法
if (!klass.prototype.initialize)
klass.prototype.initialize = Prototype.emptyFunction;

基于类

调用代码:

Person.superclass
// -> null
Person.subclasses.length
// -> 1
Person.subclasses.first() == Pirate
// -> true
Pirate.superclass == Person
// -> true

DouglasCrockfordwww.crockford.com

//声明Person类,并定义初始化方法
var Person = Class.create({
initialize: function(name) {
this.name = name;
},
say: function(message) {
return this.name + ': ' + message;
}
});

And you think you're so clever and classless and free--John Lennon

        //将新产生的value(即经过修改过的子类方法)的valueOf和toString指向原子类的同名方法
        //这里是在修正调用wrap方法之后的遗留问题
value.valueOf = method.valueOf.bind(method);
value.toString = method.toString.bind(method);
}
     //把方法添加到新类中
this.prototype[property] = value;
}

//返回Class的可调用方法
return {
create: create,
Methods: {
addMethods: addMethods
}
};
})();

//给klass添加addMethods方法,在调用create方法之后
    //仍可以调用addMethods方法进行类级别的方法扩充
Object.extend(klass, Class.Methods);
    //给返回的类添加两个属性,superclass:父类,subclasses:子类的集合
klass.superclass = parent;
klass.subclasses = [];

复制代码 代码如下:

    //貌似下面的判断总是为真,不知道为什么这么写,知道的告诉我?
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");
}

复制代码 代码如下:

/* Based on Alex Arnell's inheritance implementation. */

var john = new Pirate('Long John');
john.sleep();
// -> ERROR: sleep is not a method
// every person should be able to sleep, not just pirates!

//向新类添加方法
for (var i = 0; i < properties.length; i++)
klass.addMethods(properties[i]);

编辑:服务器运维 本文来源://创建类的方法,但是这对像JavaScript这样的弱类

关键词: