编程小贴士

给你的编程提供小点子


JavaScript中的类继承

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

Java JavaScript
强类型 弱类型
静态 动态
基于类 基于原型
函数
构造器 函数
方法 函数

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

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

要展示这一点,我们要介绍一个小小的“甜点”可以主我们像一个常规的类语言一样写代码。我们然后会展示一些在类语言中没有的有用的模式。最后,我们会就会解释这些“甜点”。

类继承

首先,我们建立一个Parenizor类,它有成员 valuegetset方法,还有一个会将value包装在括号内的toString方法。

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方法接受一个方法名和一个函数,并把它们放入类中作为公共方法。

现在我们可以写成

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

正如期望的那样,myString"(0)"

现在我们要建立另一个继承自Parenizor的类,它基本上是一样的除了toString方法将会产生"-0-"如果value是零或者空。

function ZParenizor(value) {
    this.setValue(value);
}
 
ZParenizor.inherits(Parenizor);
 
ZParenizor.method(&quote;toString&quote;, function () {
    if (this.getValue()) {
        return this.uber('toString');
    }
    return "-0-";
});

inherits方法类似于Java的extends uber方法类似于Javasuper。它令一个方法调用父类的方法(更改了名称是为了避免和保留字冲突)。

我们可以写成这样

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

这次, myString"-0-".

JavaScript 并没有类,但我们可以编程达到这个目的。

多继承

通过操作一个函数的prototype对象,我们可以实现多继承。混合多继承难以实现而且可能会遭到名称冲突的危险。我们可以在JavaScript中实现混合多继承,但这个例子我们将使用一个较规范的形式称为瑞士继承SwissI nheritance.

假设有一个NumberValue类有一个setValue方法用来检查 value是不是在一个指定范围内的一个数,并在适当的时候抛出异常。我们只要它的setValuesetRange方法给我们的ZParenizor。我们当然不想要它的toString方法。这样,我们写到:

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

这个将仅仅添加需要的方法。

寄生继承

这是另一个书写 ZParenizor类的方法。并不从 Parenizor继承,而是写了一个调用了Parenizor构造器的构造器,并对结果修改最后返回这个结果。这个构造器添加的是特权方法而非公共方法。

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

类继承是一种“是……”的关系,而寄生继承是一个关于“原是……而现在是……”的关系。构造器在对象的构造中扮演了大量的角色。注意uber (代替super关键字)对特权方法仍有效。

类扩展

JavaScript的动态性让我们可以对一个已有的类添加或替换方法。我们可以在任何时候调用方法。我们可以随时地扩展一个类。继承不是这个方式。所以我们把这种情况称为“类扩展”来避免和Java的extends──也叫扩展,但不是一回事──相混淆。

对象扩展

在静态面向对象语言中,如果你想要一个对象和另一个对象有所区别,你必须新建立一个类。但在JavaScript中,你可以向单独的对象添加方法而 不用新建类。这会有巨大的能量因为你就可以书写尽量少的类,类也可以写得更简单。想想JavaScript的对象就像哈希表一样。你可以在任何时候添加新 的值。如果这个值是一个函数,那他就会成为一个方法。

这样在上面的例子中,我完全不需要 ZParenizor类。我只要简单修改一下我的实例就行了。

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

我们给 myParenizor实例添加了一个 toString方法而没有使用任何继承。我们可以演化单独的实例因为这个语言是无类型的。

小甜点

要让上面的例子运行起来,我写了四个“甜点”方法。首先,method方法,可以把一个实例方法添加到一个类中。

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

这个将会添加一个公共方法到 Function.prototype中,这样通过类扩展所有的函数都可以用它了。它要一个名称和一个函数作为参数。

它返回 this。当我写一个没有返回值的方法时,我通常都会让它返回this。这样可以形成链式语句。

下面是 inherits方法,它会指出一个类是继承自另一个类的。它必须在两个类都定义完了之后才能定义,但要在方法继承之前调用。

Function.method('inherits', function (parent) {
    var d = 0, p = (this.prototype = new parent());
 
    this.method('uber', function uber(name) {
        var f, r, t = d, 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 += 1;
        r = f.apply(this, Array.prototype.slice.apply(arguments, [1]));
        d -= 1;
        return r;
    });
    return this;
});

再来,我们扩展 Function类。我们加入一个 parent类的实例并将它做为新的prototype。我们也必须修正constructor字段,同时我们加入uber方法。

uber方法将会在自己的prototype中查找某个方法。这个是寄生继承或类扩展的一种情况。如果我们是类继承,那么我们要找到parentprototype中的函数。return语句调用了函数的apply方法来调用该函数,同时显示地设置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;
});

The swiss方法对每个参数进行循环。每个名称,它都将parent的原型中的成员复制下来到新的类的prototype中。

总结

JavaScript可以像类语言那样使用,但它也有一种十分独特的表现层次。我们已经看过了类继承、瑞士继承、寄生继承、类扩展和对象扩展。这一等系列代码复用的模式都能来自这个一直被认为是很小、很简单的JavaScript语言。

类对象属于“硬的”。给一个“硬的”对象添加成员的唯一的方法是建立一个新的类。在JavaScript中,对象是“软的”。要给一个“软”对象添加成员只要简单的赋值就行了。

因为JavaScript中的类是这样地灵活,你可能会还想到更复杂的类继承。但深度继承并不合适。浅继承则较有效而且更易表达。

128 Responses to “ JavaScript中的类继承 ”

  1. see pron说道:

    E0nJzw Major thankies for the blog article.Really looking forward to read more. Fantastic.

  2. This is a topic which is near to my heart Cheers! Where are your contact details though?

  3. xem tu vi 2019说道:

    motorcycle accident claims I started creating templates, but I don at know how to make demos in my Joomla website, for my visitors to test them..

  4. girl coloring说道:

    Looking around I like to look around the web, regularly I will just go to Digg and follow thru

  5. what is mca说道:

    Major thankies for the blog post.Really looking forward to read more. Will read on…

  6. Lung Cleanse说道:

    Very good blog post.Really thank you! Keep writing.

  7. This is a great tip especially to those new to the blogosphere. Simple but very precise information Thank you for sharing this one. A must read article!

  8. I think this is a real great blog article.Thanks Again. Will read on

  9. Is this a paid theme or did you modify it yourself?

  10. may dong phuc说道:

    Thanks for sharing, this is a fantastic blog article.Really looking forward to read more. Fantastic.

  11. Oluwadamilare说道:

    This excellent website definitely has all of the info I wanted about this subject and didn at know who to ask.

  12. site说道:

    Your style is so unique in comparison to other folks I ave read stuff from. Many thanks for posting when you ave got the opportunity, Guess I all just bookmark this page.

  13. Im grateful for the blog article.Thanks Again. Much obliged.

  14. Very nice info and right to the point. I am not sure if this is truly the best place to ask but do you guys have any ideea where to hire some professional writers? Thank you

  15. Really appreciate you sharing this blog article. Will read on

  16. here说道:

    Really enjoyed this blog.Really thank you! Much obliged.

  17. w88world.com说道:

    it and I all be book-marking it and checking back frequently!

  18. Some really prime posts on this web site , saved to my bookmarks.

  19. Wow, awesome weblog structure! How long have you ever been running a blog for? you make blogging look easy. The entire look of your web site is great, let alone the content!

  20. I regard something genuinely special in this website.

  21. bo kit arduino说道:

    Really enjoyed this blog.Much thanks again. Will read on

  22. this website说道:

    wow, awesome article post.Really looking forward to read more. Want more.

  23. this website说道:

    It?s hard to seek out knowledgeable individuals on this matter, but you sound like you know what you?re talking about! Thanks

  24. woking cab说道:

    It?s really a great and helpful piece of info. I am glad that you simply shared this helpful info with us. Please keep us informed like this. Thanks for sharing.

  25. Many thanks for sharing this first-class write-up. Very interesting ideas! (as always, btw)

  26. We are аА аЂа group of volunteers and opаА аЂа•nаАаб‚Т€Т“ng аА аЂаn аА аЂаd?itional

  27. This is a set of words, not an essay. you will be incompetent

  28. Just Browsing While I was browsing today I saw a excellent article about

  29. Wow, fantastic blog layout! How long have you been blogging for? you make blogging look easy. The overall look of your website is wonderful, let alone the content!

  30. H1B说道:

    there right now. (from what I ave read) Is that what you are using on your blog?

  31. share now说道:

    Your style is very unique in comparison to other folks I have read stuff from. I appreciate you for posting when you ave got the opportunity, Guess I all just bookmark this site.

  32. Thank you for your article.Thanks Again. Cool.

  33. find more说道:

    Say, you got a nice article.Much thanks again. Will read on

  34. Nwokolo说道:

    info for a very lengthy time. Thank you and good luck.

  35. mo hinh mut xop说道:

    Very nice write-up. I absolutely love this site. Thanks!

  36. trang tri noel说道:

    Interesting article. Were did you got all the information from?

  37. klm promo code说道:

    please visit the internet sites we adhere to, like this one particular, because it represents our picks in the web

  38. It as not that I want to replicate your web page, but I really like the style. Could you tell me which design are you using? Or was it tailor made?

  39. You generated some decent points there. I looked on-line for that problem and discovered the majority of people will go coupled with with all your internet site.

  40. Thanks so much for the article. Keep writing.

  41. Beyonce说道:

    Very nice post. I just stumbled upon your weblog and wished to say that I have truly enjoyed browsing your blog posts. After all I all be subscribing to your rss feed and I hope you write again soon!

  42. bo dam说道:

    Im no expert, but I consider you just made an excellent point. You naturally understand what youre talking about, and I can truly get behind that. Thanks for staying so upfront and so truthful.

  43. for details说道:

    Very good post. I certainly appreciate this website. Keep writing!

  44. hoc tieng nhat说道:

    Major thankies for the blog article.Thanks Again. Great.

  45. Wow! Thank you! I permanently wanted to write on my site something like that. Can I take a part of your post to my site?

  46. giay nam cong so说道:

    Very good write-up. I definitely appreciate this website. Continue the good work!

  47. My brother recommended I may like this web site. He was entirely right. This put up truly made my day. You can not believe simply how a lot time I had spent for this information! Thank you!

  48. David说道:

    Some truly superb posts on this internet site , regards for contribution.

  49. stella说道:

    Im obliged for the post.Really looking forward to read more. Really Cool.

  50. Your style is really unique compared to other people I ave read stuff from. I appreciate you for posting when you ave got the opportunity, Guess I all just bookmark this blog.

  51. There is obviously a bunch to identify about this. I suppose you made various good points in features also.

  52. I think this is a real great blog post. Want more.

  53. aliexpress说道:

    Thanks to my father who told me concerning this weblog,

  54. You are my breathing in, I possess few web logs and rarely run out from to brand.

  55. Tapete说道:

    I truly appreciate this blog. Really Great.

  56. Blusa Tejidas说道:

    Thanks-a-mundo for the blog article.Thanks Again. Want more.

  57. local说道:

    I truly appreciate this post. I’а†ve been looking everywhere for this! Thank goodness I found it on Bing. You have made my day! Thanks again

  58. blue nike说道:

    italian honey fig How can I insert a tag cloud into my blog @ blogspot?

  59. value说道:

    Very neat article post.Really looking forward to read more. Really Great.

  60. School admission说道:

    This is very interesting, You are a very skilled blogger. I have joined your feed and look forward to seeking more of your excellent post. Also, I ave shared your site in my social networks!

  61. School admission说道:

    You made some decent points there. I looked on the internet for the subject and found most people will consent with your blog.

  62. ps4 ark servers说道:

    Wow, wonderful blog layout! How long have you been blogging for? you made blogging look easy. The overall look of your web site is fantastic, let alone the content!

  63. info about the issue and found most people will go along with your views on this web site.

  64. Major thanks for the article.Really thank you! Cool.

  65. Moskito说道:

    Wonderful put up, definitely regret not heading on the USO style dinner. Keep up the great perform!

  66. Muchos Gracias for your blog article. Keep writing.

  67. This actually answered my predicament, thank you! jordans free shipping

  68. Open heavens说道:

    paul smith ?? Listed Here Is A Solution That as Even Assisting bag-masters Grow

  69. tm objection说道:

    I value the blog post.Really looking forward to read more. Keep writing.

  70. really excellent post, i undoubtedly actually like this incredible web-site, go on it

  71. for more info说道:

    Thanks for sharing, this is a fantastic article.Thanks Again.

  72. Well I definitely enjoyed studying it. This information provided by you is very constructive for good planning.

  73. Major thanks for the blog. Really Great.

  74. wow, awesome post.Really looking forward to read more. Awesome.

  75. I used to be able to find good information from your blog posts.

  76. PlаА аЂа•аА аЂаse let me know where аАааБТ“ou got your thаА аЂа•mаА аЂа•.

  77. tututorials说道:

    Way cool! Some very valid points! I appreciate you penning this article and also the rest of the website is also very good.

  78. I truly appreciate this blog.Much thanks again.

  79. I value the blog.Really thank you! Want more.

  80. Thanks for the blog post.Really thank you! Awesome.

  81. producer说道:

    This actually answered my drawback, thanks!

  82. pool builders说道:

    I think this is a real great article.Thanks Again.

  83. Major thankies for the blog post.Really looking forward to read more. Will read on…

  84. Super-Duper blog! I am loving it!! Will be back later to read some more. I am bookmarking your feeds also

  85. It as not that I want to duplicate your web site, but I really like the design. Could you tell me which design are you using? Or was it tailor made?

  86. This particular blog is really interesting and also amusing. I have chosen many handy tips out of this blog. I ad love to come back again and again. Thanks a lot!

  87. devotionals说道:

    I think other site proprietors should take this website as an model, very clean and excellent user friendly style and design, let alone the content. You are an expert in this topic!

  88. official site说道:

    very good post, i certainly love this web site, carry on it

  89. visit website说道:

    Wow that was unusual. I just wrote an very long comment but after I clicked submit my comment didn at show up. Grrrr well I am not writing all that over again. Anyway, just wanted to say great blog!

  90. write for us说道:

    Usually I do not read article on blogs, but I wish to say that this write-up very compelled me to try and do so! Your writing style has been surprised me. Thank you, quite nice post.

  91. over here说道:

    It as not that I want to replicate your web-site, but I really like the design and style. Could you let me know which design are you using? Or was it tailor made?

  92. see more说道:

    I simply could not go away your site before suggesting that I really loved the usual info an individual provide to your visitors? Is gonna be back ceaselessly to investigate cross-check new posts

  93. Israel Hookers说道:

    Wow, fantastic blog layout! How long have you been blogging for? you made blogging look easy. The overall look of your site is great, let alone the content!. Thanks For Your article about sex.

  94. Wow, marvelous weblog format! How lengthy have you been running a blog for? you make blogging look easy. The entire look of your site is wonderful, as well as the content!

  95. It as not that I want to copy your web page, but I really like the design and style. Could you let me know which style are you using? Or was it tailor made?

  96. Loving the info on this website , you have done outstanding job on the blog posts.

  97. Major thankies for the article.Really looking forward to read more. Really Great.

  98. There may be noticeably a bundle to know about this. I assume you made certain good points in features also.

  99. I truly appreciate this blog article.Really thank you! Really Cool. click here

  100. Wonderful blog! I found it while browsing on Yahoo News. Do you have any tips on how to get listed in Yahoo News? I ave been trying for a while but I never seem to get there! Appreciate it

  101. Im thankful for the post.Thanks Again. Really Great.

  102. Im grateful for the article.Really thank you! Keep writing.

  103. twitter说道:

    You have remarked very interesting details! ps nice site.

  104. just go to说道:

    I see something truly special in this internet site.

  105. Im obliged for the blog article.Really looking forward to read more.

  106. ads说道:

    It as not that I want to copy your web-site, but I really like the layout. Could you tell me which style are you using? Or was it tailor made?

  107. visit website说道:

    Keep up the superb piece of work, I read few posts on this website and I believe that your web site is really interesting and has got circles of superb information.

  108. check out说道:

    Wow! Thank you! I permanently wanted to write on my site something like that. Can I implement a fragment of your post to my website?

  109. wow, awesome article post.Really looking forward to read more. Great.

  110. du hoc phap说道:

    Very informative article. You really grabbed my interest with the way you cleverly featured your points. I agree with most of your content and I am analyzing some areas of interest.

  111. ford an lac说道:

    Your location is valueble for me. Thanks!

  112. clickhere说道:

    It’а†s in reality a nice and useful piece of info. I am glad that you simply shared this helpful information with us. Please keep us up to date like this. Thanks for sharing.

  113. It as not that I want to replicate your internet site, but I really like the style and design. Could you tell me which theme are you using? Or was it especially designed?

  114. casino说道:

    Muchos Gracias for your post.Really thank you!

  115. This unique blog is really cool and also diverting. I have found helluva useful advices out of this amazing blog. I ad love to visit it every once in a while. Cheers!

  116. I will immediately grab your rss feed as I can not to find your e-mail subscription link or e-newsletter service. Do you ave any? Please allow me realize so that I could subscribe. Thanks.

  117. daftar pb说道:

    You made some decent points there. I looked on the internet for that problem and located most individuals will go together with with the web site.

  118. soi cau mb说道:

    Your kindness will be tremendously appreciated.

  119. official site说道:

    Very good blog post.Much thanks again. Really Great.

  120. more info说道:

    Im obliged for the article.Much thanks again. Want more.

  121. You are my role designs. Thanks for your article

  122. MIAMI SEO说道:

    Really informative article post. Keep writing.

  123. This is one awesome blog post.Really thank you! Much obliged.

  124. other details说道:

    We all talk a little about what you should talk about when is shows correspondence to because Maybe this has more than one meaning.

  125. good morning说道:

    Thanks a lot for the blog.Really looking forward to read more. Great.

  126. Thanks a lot for the post.Really thank you! Cool.

  127. You are my aspiration, I have few blogs and very sporadically run out from post. Fiat justitia et pereat mundus.Let justice be done, though the world perish. by Ferdinand I.

  128. Very informative article post. Really Cool.

Leave a Reply

Your email address will not be published.

You may use these HTML tags and attributes: <a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <strike> <strong>