JavaScript代码复用模式

标签: javascript web前端开发 | 发表时间:2014-11-06 22:34 | 作者:trigkit4
出处:http://segmentfault.com/blogs

代码复用及其原则

代码复用,顾名思义就是对曾经编写过的代码的一部分甚至全部重新加以利用,从而构建新的程序。在谈及代码复用的时候,我们首先可以想到的是 继承性。代码复用的原则是:

  优先使用对象组合,而不是类继承

在js中,由于没有类的概念,因此实例的概念也就没多大意义,js中的对象是简单的键-值对,可以动态的创建和修改它们。

但在 js中,我们可以使用构造函数和 new操作符来实例化一个对象,这与其他使用类的编程语言在语法上有其相似之处。

例如:

  var trigkit4 = new Person();

js在调用构造函数 Person时似乎看起来是一个类,但其实际上仍然是一个函数,这让我们产生了一些假定在类的基础上的开发思路和继承模式,我们可以称之为“类式继承模式”。

传统的继承模式是需要 class关键字的,我们假定以上的类式继承模式为 现代继承模式,这是一种不需要以类的方式考虑的模式。

类式继承模式

看下面两个构造函数 Parent()Child()的例子:

  <script type="text/javascript">
    function Parent(name){
        this.name = name || 'Allen';
    }

    Parent.prototype.say = function(){
        return this.name;
    }

    function Child(name){}

    //用Parent构造函数创建一个对象,并将该对象赋值给Child原型以实现继承
    function inherit(C,P){
        C.prototype = new P();//原型属性应该指向一个对象,而不是函数
    }

    //调用声明的继承函数
    inherit(Child,Parent);
</script>

当使用 new Child()语句创建一个对象时,它会通过原型从 Parent()实例获取它的功能,比如:

  var kid = new Child();
kid.say();//Allen

原型链

讨论一下类式继承模式下原型链的工作原理,我们将对象看做是内存中某处的块,该内存块包含数据以及指向其他块的引用。当用 new Parent()语句创建一个对象时,就会创建如下图左边的这样一个块,这个块保存了 name属性,如果想访问 say()方法,我们可以通过指向构造函数 Parent()prototype(原型)属性的隐式链接 __proto__,便可访问右边区块 Parent.prototype

图片描述

那么,当使用 var kid = new Child()创建新对象时会发生什么?如下图:

图片描述

使用 new Child()语句所创建的对象除了隐式链接 __proto__外,它几乎是空的。这种情况下, __proto__指向了在 inherit()函数中使用 new Parent()语句所创建的对象

当执行 kid.say()时,由于最左下角的区块对象并没有 say()方法,因此他将通过原型链查询中间的区块对象,然而,中间的区块对象也没有 say()方法,因此他又顺着原型链查询到最右边的区块对象,而该对象正好有 say()方法。完了吗?

执行到这里的时候并没有完,在 say()方法中引用了 this.name,this指向构造函数所创建的对象,在这里,它指向了 new Child()这个区块,然而, new Child()中并没有 name属性,为此,将查询中间区块,而中间区块正好有 name属性,至此,原型链的查询完毕。

更详细的讨论请查看我这篇文章: JavaScript学习总结(五)原型和原型链详解

共享原型

本模式的法则在于:可复用的成员应该转移到原型中而不是放置在this中。因此,处于继承的目的,任何值得继承的东西都应该放在原型中实现。所以,可以将子对象的原型与父对象的原型设置为相同即可,如下示例所示:

  function inherit(C,P){
    C.prototype = P.prototype;
}

图片描述

子对象和父对象共享同一个原型,并且可以同等的访问 say()方法。然而,子对象并没有继承 name属性

原型继承

原型继承是一种“现代”无类继承模式。看如下实例:

  <script type="text/javascript">
    //要继承的对象
    var parent = {
        name : "Jack"  //这里不能有分号哦
    };

    //新对象
    var child = Object(parent);

    alert(child.name);//Jack
</script>

在原型模式中,并不需要使用对象字面量来创建父对象。如下代码所示,可以使用构造函数来创建父对象,这样做的话,自身的属性和构造函数的原型的属性都将被继承。

  <script type="text/javascript">
    //父构造函数
    function Person(){
        this.name = "trigkit4";
    }
    //添加到原型的属性
    Person.prototype.getName = function(){
        return this.name;
    };

    //创建一个新的Person类对象
    var obj = new Person();

    //继承
    var kid = Object(obj);

    alert(kid.getName());//trigkit4
</script>

本模式中,可以选择仅继承现有构造函数的原型对象。对象继承自对象,而不论父对象是如何创建的,如下实例:

  <script type="text/javascript">
    //父构造函数
    function Person(){
        this.name = "trigkit4";
    }
    //添加到原型的属性
    Person.prototype.getName = function(){
        return this.name;
    };

    //创建一个新的Person类对象
    var obj = new Person();

    //继承
    var kid = Object(Person.prototype);

    console.log(typeof kid.getName);//function,因为它在原型中
    console.log(typeof kid.name);//undefined,因为只有该原型是继承的
</script>

To be continued……

相关 [javascript 代码复用 模式] 推荐:

JavaScript代码复用模式

- - SegmentFault 最新的文章
代码复用,顾名思义就是对曾经编写过的代码的一部分甚至全部重新加以利用,从而构建新的程序. 在谈及代码复用的时候,我们首先可以想到的是 继承性. 优先使用对象组合,而不是类继承. 在js中,由于没有类的概念,因此实例的概念也就没多大意义,js中的对象是简单的键-值对,可以动态的创建和修改它们. 但在 js中,我们可以使用构造函数和 new操作符来实例化一个对象,这与其他使用类的编程语言在语法上有其相似之处.

Javascript 严格模式详解

- - 阮一峰的网络日志
除了正常运行模式,ECMAscript 5添加了第二种运行模式: "严格模式"(strict mode). 顾名思义,这种模式使得Javascript在更严格的条件下运行. 设立"严格模式"的目的,主要有以下几个:.   - 消除Javascript语法的一些不合理、不严谨之处,减少一些怪异行为;.

JavaScript 方法的4种调用模式

- - Harttle Land
函数(Function)是JavaScript的基本模块单元,JavaScript的代码重用, 信息隐藏,对象组合等都可以借助函数来实现. JavaScript中的函数有4种调用模式:. 方法调用(Method Invocation Pattern). 函数调用(Function Invocation Pattern).

javascript严谨模式提升开发效率和质量

- - ITeye博客
JavaScript严谨模式(Strict Mode)提升开发效率和质量(转载). 随着WebApp突飞猛进的发展,Javascript写的WebApp规模越来月庞大,比如典型的代表产品. 腾讯WebQQ、HTML5游戏等等,Javascript越来越需要大量的开发人员多多人协作开发. 同时HTML5、CSS3等新技术和NodeJs项目的高速发展,这几年JavaScript语言借着各种新API陆续被运用到从移动设备到服务器的多个”新领域”中.

Javascript诞生记

- Milido - 阮一峰的网络日志
二周前,我谈了一点Javascript的历史. 今天把这部分补全,从历史的角度,说明Javascript到底是如何设计出来的. 只有了解这段历史,才能明白Javascript为什么是现在的样子. 我依据的资料,主要是Brendan Eich的自述. "1994年,网景公司(Netscape)发布了Navigator浏览器0.9版.

JavaScript,你懂的

- dylan - keakon的涂鸦馆
经常有人问我,JavaScript应该怎么学. 先学基本语法,如果曾学过C等语言,应该1小时内就能掌握了. 再去使用内置的函数、方法和DOM API,熟悉它能干什么;而在学习DOM API的过程中,你还不得不与HTML和CSS打交道. 然后弄懂匿名函数和闭包,学会至少一个常用的JavaScript库(例如jQuery).

Javascript 里跑Linux

- rockmaple - Shellex&#39;s Blog
牛逼到暴的大拿 Fabrice Bellard,用Javascript实现了一个x86 PC 模拟器,然后成功在这个模拟器里面跑Linux(请用Firefox 4 / Google Chrome 11打开,Chome 12有BUG). 关于这个东西… 伊说 “I did it for fun“,大大啊大大啊….

高效 JavaScript

- xtps - ITeye论坛最新讨论
传统上,网页中不会有大量的脚本,至少脚本很少会影响网页的性能. 但随着网页越来越像 Web 应用程序,脚本的效率对网页性能影响越来越大. 而且使用 Web 技术开发的应用程序现在越来越多,因此提高脚本的性能变得很重要. 对于桌面应用程序,通常使用编译器将源代码转换为二进制程序. 编译器可以花费大量时间优化最终二进制程序的效率.

你得学JavaScript

- 蒋冰 - 伯乐在线 -博客
  注:本文由 敏捷翻译 - 蒋少雄 翻译自 Kenny Meyers 的博文.   如果三年前你问我应该学什么语言,我会告诉你是Ruby.   如果你现在想学一门语言的话,你应该学习JavaScript..   我认为,每一位Web开发人员都应该学习JavaScript. 目前推出的许多新技术都支持这个观点.

javascript 贪食蛇

- Xin - 博客园-首页原创精华区
我的程序用javascript与Html中的table结合,实现的简单的贪食蛇游戏,游戏的主要特点,可调整蛇移动速度,可调整蛇移动范围,碰壁、咬到身体则“Game Over. 游戏并不完善,只是实现了主要的功用,有设计不合理的地方,欢迎您感大家提意见.        实现方法:由javascript语言中的setInterval方法驱动整个游戏程序,设置“nowDirection”即蛇的当前移动方向为全局变量,由setInterval方法定时获取蛇的移动方向,由document.onkeydown()捕捉当前按键(上、下、左、右)以修改nowDirection,这样就可以用方向按键控制蛇周期时间的定向移动.