JavaScript中的类继承

  • 时间:
  • 浏览:1
  • 来源:大发时时彩官网_去哪玩大发时时彩_哪里可以玩大发时时彩

  JavaScript是有一4个无class的面向对象语言,它使用原型继承而非类继承。这会我想要相似 使用传统面向对象语言如C++和Java的程序运行员们感到困惑。正如大伙所看一遍的,JavaScript的原型继承比类继承具有更强的表现力。

  但首先,要搞清楚大伙为你相似 没法 关注继承?主要有一4个是是因为。首先是方便类型的转换。大伙希望语言系统都都还里能对你相似 相似类的引用进行自动转换。而对于有一4个要求对引用对象进行显示转换的类型系统来说只有获得很少的类型安全性。这对于强类型语言来说有点痛 要,为什么在么在让在像JavaScript曾经的松散型语言中,永远只有对对象引用进行强制转换。

  第两个是是因为是代码的复用。代码中地处絮状拥有相同土法律法律依据的对象是十分常见的。类还都还里能通过一组定义来创建它们。另外地处其他相似的对象也很普遍,你相似 对象中只有少数有关打上去和修改的土法律法律依据地处区别。类的继承还都还里能很有效地避免你相似 问题报告 图片,但原型继承更有效。

  为了说明你相似 点,大伙将介绍其他语法糖,它允许大伙以相似于传统的class的语言来编写代码。为什么在么在让大伙将介绍其他有用的模式,你相似 模式不适用于传统的class语言。最后,大伙将对语法糖进行解释。

  首先,大伙打上去了有一4个Parenizor类,所含set和get有一4个土法律法律依据,分别用来设置和获取value,以及有一4个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接受土法律法律依据的名称和有一4个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土法律法律依据相似。它允许有一4个土法律法律依据调用父类中的土法律法律依据(却说改了名称以避开保留字的限制)。

  为什么在么在让大伙还都还里能曾经写:

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

  你相似 次,myString的值为"-0-".

  JavaScript没法 类,为什么在么在让大伙还都还里能通过编程来实现它。

  通过操作有一4个函数的原型对象,大伙还都还里能实现多重继承,从而使大伙还都还里能用多个类的土法律法律依据来构建有一4个类。混合多重继承为什么在么在让难以实现,并为什么在么在让地处土法律法律依据名称的冲突。大伙还都还里能在JavaScript中实现混合多重继承,为什么在么在让在本例中大伙将使用有一4个更严格的被称之为Swiss继承的形式。

  假设有一4个多NumberValue类,包所含一4个土法律法律依据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土法律法律依据还都还里能随时被调用,曾经类的所有实例在现在和将来时会有你相似 土法律法律依据。大伙还都还里能在任何时会对有一4个类进行扩展。继承具有追溯性,大伙把你相似 叫做类的扩充(Class Augmentation),以避免与Java的extends产生混淆。

  在静态面向对象语言中,为什么在么在我想要我想要有一4个对象与曾经对象略微不同,就都还里能定义有一4个新的类。在JavaScript中,我就将土法律法律依据打上去到单个的对象中,而只有在定义额外的类。你相似 非常强大,为什么在么在我想要只都还里能写很少的类,为什么在么在让类都还都还里能很简单。回想一下,JavaScript对象就像哈希表,我就随时打上去新的值,为什么在么在让值是function,没法 它就成了有一4个土法律法律依据。

  为什么在么在让在顶端的示例中,我根本只有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土法律法律依据,它将有一4个实例土法律法律依据打上去到类中。

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

  它在Function.prototype上打上去了有一4个公共土法律法律依据,为什么在么在让所有的函数都通过Class Augmentation(类的扩充)获得了该土法律法律依据。它接受有一4个名称和有一4个函数,并将它们打上去到函数的原型对象中。

  它返回this. 当我编写有一4个只有返回值的土法律法律依据时,我通常时会返回this,曾经就具有了有一4个级联式的编程风格。

  接下来是inherits土法律法律依据,它用来表示有一4个类从曾经类继承。应该在有一4个类都被定义时会再调用你相似 土法律法律依据,为什么在么在让在继承类的土法律法律依据时会打上去该土法律法律依据。

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进行扩充。大伙创建了有一4个父类的实例,并将其作为新的原型。大伙还修改了构造函数的字段,并将uber土法律法律依据打上去到原型中。

  Uber土法律法律依据在其他人的原型中查找指定的土法律法律依据。这是在寄生继承或对象扩充的情況下调用的函数。为什么在么在让大伙进行类的继承,没法 大伙就都还里能在父类的原型中找到你相似 函数。Return搞笑的话使用函数的apply土法律法律依据来调用function,显示地设置this并传递有一4个数组参数。参数(为什么在么在让有搞笑的话)从arguments数组中获取。可惜arguments数组全部时会有一4个真正的数组,其他大伙不得不再次使用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进行遍历。对每有一4个name,它都从父类的原型中基因重组有一4个成员到新类的原型中。

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

  类的对象非常严格,要将有一4个新成员打上去到对象中,唯一的土法律法律依据却说创建有一4个新类。而在JavaScript中,对象是松散的,还都还里能通过简单的赋值操作将有一4个新成员打上去到对象中。

  为什么在么在让JavaScript中的对象非常灵活,其他你都还里能对类的层次形状进行不同的考虑。淬硬层 次的形状未必太适用,相反,浅层次的形状更高效,更具有表现力。

我从事编写JavaScript代码为什么在么在让有14年了,为什么在么在让我从来没法 发现都还里能使用uber函数。Super在class模式中十分重要,为什么在么在让在原型和函数式模式中全部时会都还里能的。现在看来我早期尝试在JavaScript中支持class模式是有一4个错误。

原文地址:Classical Inheritance in JavaScript

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