大发时时彩官网_网络大发时时彩平台_网络大发时时彩网站 - 大发时时彩官网,网络大发时时彩平台,网络大发时时彩网站是知名的中文新闻门户网站,大发时时彩官网,网络大发时时彩平台,网络大发时时彩网站也是全球互联网中文新闻资讯最重要的原创内容供应商之一。依托中新社遍布全球的采编网络,每天24小时面向广大网民和网络媒体。

JavaScript中的类继承

  • 时间:
  • 浏览:1

  JavaScript是六个多无class的面向对象语言,它使用原型继承而非类继承。这会让有有哪些使用传统面向对象语言如C++和Java的任务管理器员们感到困惑。正如其他人所想看 的,JavaScript的原型继承比类继承具有更强的表现力。

  但首先,要搞清楚其他人为有哪些还里能了 关注继承?主要有六个多原因分析分析着。首先是方便类型的转换。其他人希望语言系统还里能对有有哪些例如类的引用进行自动转换。而对于六个多要求对引用对象进行显示转换的类型系统来说还里能了获得很少的类型安全性。这对于强类型语言来说怪怪的要,有之前 在像JavaScript那我 的松散型语言中,永远还里能了对对象引用进行强制转换。

  第六个原因分析分析着是代码的复用。代码中地处一定量拥有相同措施的对象是十分常见的。类还里能通过一组定义来创建它们。另外地处其他例如的对象也很普遍,有有哪些对象中还里能了少数有关加上和修改的措施地处区别。类的继承还里能很有效地外理有有哪些大问题,但原型继承更有效。

  为了说明这其他,其他人将介绍其他语法糖,它允许其他人以例如于传统的class的语言来编写代码。有之前 其他人将介绍其他有用的模式,有有哪些模式不适用于传统的class语言。最后,其他人将对语法糖进行解释。

  首先,其他人加上了六个多Parenizor类,蕴藏set和get六个多措施,分别用来设置和获取value,以及六个多toString措施,用来对parens中的value进行包装。

function Parenizor(value) {
    this.setValue(value);
}

Parenizor.method('setValue', function (value) {
    this.value = value;
    return this;
});

Parenizor.method('getValue', function () {
    return this.value;
});

Parenizor.method('toString', function () {
    return '(' + this.getValue() + ')';
});

  语法看起来怪怪的不太一样,有之前 应该很好懂。措施method接受措施的名称和六个多function,并将什儿 function作为公共措施加上到类中。

  有之前 其他人还里能那我 写:

myParenizor = new Parenizor(0);
myString = myParenizor.toString();

  正如你所期望的,myString的值为"(0)".

  现在其他人创建那我 类继承Parenizor,除了toString措施中对于value为空或0的情况汇报会输出"-0-"外其余都和Parenizor相同。

function ZParenizor(value) {
    this.setValue(value);
}

ZParenizor.inherits(Parenizor);

ZParenizor.method('toString', function () {
    if (this.getValue()) {
        return this.uber('toString');
    }
    return "-0-";
});

  这里的inherits措施与Java中的extends措施例如,uber措施也与Java中的super措施例如。它允许六个多措施调用父类中的措施(却说改了名称以避开保留字的限制)。

  有之前 其他人还里能那我 写:

myZParenizor = new ZParenizor(0);
myString = myZParenizor.toString();

  什儿 次,myString的值为"-0-".

  JavaScript还里能了 类,有之前 其他人还里能通过编程来实现它。

  通过操作六个多函数的原型对象,其他人还里能实现多重继承,从而使其他人还里能用多个类的措施来构建六个多类。混合多重继承有之前 难以实现,并有之前 地处措施名称的冲突。其他人还里能在JavaScript中实现混合多重继承,有之前 在本例中其他人将使用六个多更严格的被称之为Swiss继承的形式。

  假设有六个多NumberValue类,蕴藏六个多措施setValue,该措施检查value是否为某个特定范围内的数字,必要的之前 会抛出异常。其他人只还里能ZParenizorsetValuesetRange措施,而还里能了toString措施。还里能了 其他人还里能那我 写:

ZParenizor.swiss(NumberValue, 'setValue', 'setRange');

  那我 只会将其他人还里能的措施加上到类中。

  ZParenizor还有另外有一种写法。除了从Parenizor类继承,其他人还还里能在构造函数中调用Parenizor的构造函数,并传递返回的结果。通过什儿 措施,其他人给构造函数加上特权措施,而不会再去为其加上公共措施。

function ZParenizor2(value) {
    var that = new Parenizor(value);
    that.toString = function () {
        if (this.getValue()) {
            return this.uber('toString');
        }
        return "-0-"
    };
    return that;
}

  类的继承是is-a关系(公有继承),而寄生继承是was-a-but-now's-a关系(私有继承与公有继承)。构造函数在对象的构造中发挥了很大的作用。注意ubersuper措施仍然可用于特权措施。

  JavaScript的动态性允许其他人加上或替换现有类的措施,method措施还里能随时被调用,那我 类的所有实例在现在和将来还里能有什儿 措施。其他人还里能在任何之前 对六个多类进行扩展。继承具有追溯性,其他人把什儿 叫做类的扩充(Class Augmentation),以外理与Java的extends产生混淆。

  在静态面向对象语言中,有之前 你要我六个多对象与那我 对象略微不同,就还里能定义六个多新的类。在JavaScript中,你要将措施加上到单个的对象中,而还里能了在定义额外的类。什儿 非常强大,有之前 你只还里能写很少的类,有之前 类都还里能很简单。回想一下,JavaScript对象就像哈希表,你要随时加上新的值,有之前 值是function,还里能了 它就成了六个多措施。

  有之前 在上边的示例中,我根本还里能了ZParenizor类。我要 简单地修改我的实例。

myParenizor = new Parenizor(0);
myParenizor.toString = function () {
    if (this.getValue()) {
        return this.uber('toString');
    }
    return "-0-";
};
myString = myParenizor.toString();

  我将toString措施加上到我的myParenizor实例中,而还里能了 使用任何形式的继承。其他人还里能修改单个的实例,有之前 语言是无class的。

  为了使上边的示例能正常工作,我写了六个sugar措施。首先是method措施,它将六个多实例措施加上到类中。

Function.prototype.method = function (name, func) {
    this.prototype[name] = func;
    return this;
};

  它在Function.prototype加上上了六个多公共措施,有之前 所有的函数都通过Class Augmentation(类的扩充)获得了该措施。它接受六个多名称和六个多函数,并将它们加上到函数的原型对象中。

  它返回this. 当我编写六个多还里能了返回值的措施时,我通常还里能返回this,那我 就具有了六个多级联式的编程风格。

  接下来是inherits措施,它用来表示六个多类从那我 类继承。应该在六个多类都被定义之前 再调用什儿 措施,有之前 在继承类的措施之前 加上该措施。

Function.method('inherits', function (parent) {
    this.prototype = new parent();
    var d = {}, 
        p = this.prototype;
    this.prototype.constructor = parent; 
    this.method('uber', function uber(name) {
        if (!(name in d)) {
            d[name] = 0;
        }        
        var f, r, t = d[name], v = parent.prototype;
        if (t) {
            while (t) {
                v = v.constructor.prototype;
                t -= 1;
            }
            f = v[name];
        } else {
            f = p[name];
            if (f == this[name]) {
                f = v[name];
            }
        }
        d[name] += 1;
        r = f.apply(this, Array.prototype.slice.apply(arguments, [1]));
        d[name] -= 1;
        return r;
    });
    return this;
});

  其他人继续对Function进行扩充。其他人创建了六个多父类的实例,并将其作为新的原型。其他人还修改了构造函数的字段,并将uber措施加上到原型中。

  Uber措施在此人 的原型中查找指定的措施。这是在寄生继承或对象扩充的情况汇报下调用的函数。有之前 其他人进行类的继承,还里能了 其他人就还里能在父类的原型中找到什儿 函数。Return句子使用函数的apply措施来调用function,显示地设置this并传递六个多数组参数。参数(有之前 有句子)从arguments数组中获取。可惜arguments数组还里能六个多真正的数组,其他其他人不得不再次使用apply来调用的slice措施。

  最后,是swiss措施。

Function.method('swiss', function (parent) {
    for (var i = 1; i < arguments.length; i += 1) {
        var name = arguments[i];
        this.prototype[name] = parent.prototype[name];
    }
    return this;
});

  Swiss措施对arguments进行遍历。对每六个多name,它都从父类的原型中克隆qq六个多成员到新类的原型中。

  JavaScript还里能像class语言一样来使用,但它也具有相当独特的表现力。其他人研究了类的继承,Swiss继承,寄生继承,类的扩充以及对象的扩充。什儿 一定量代码的复用模式来自于有一种被认为比Java更小,更简单的语言。

  类的对象非常严格,要将六个多新成员加上到对象中,唯一的措施却说创建六个多新类。而在JavaScript中,对象是松散的,还里能通过简单的赋值操作将六个多新成员加上到对象中。

  有之前 JavaScript中的对象非常灵活,其他你还里能对类的层次形态学 进行不同的考虑。淬硬层 次的形态学 暂且太适用,相反,浅层次的形态学 更高效,更具有表现力。

我从事编写JavaScript代码有之前 有14年了,有之前 我从来还里能了 发现还里能使用uber函数。Super在class模式中十分重要,有之前 在原型和函数式模式中还里能还里能的。现在看来我早期尝试在JavaScript中支持class模式是六个多错误。

原文地址:Classical Inheritance in JavaScript

相关链接:http://www.cnblogs.com/sanshi/archive/30009/07/08/1519036.html