源码网商城,靠谱的源码在线交易网站 我的订单 购物车 帮助

源码网商城

JavaScript代码复用模式详解

  • 时间:2020-10-05 16:27 编辑: 来源: 阅读:
  • 扫一扫,手机访问
摘要:JavaScript代码复用模式详解
[b]代码复用及其原则 [/b] [code]代码复用[/code],顾名思义就是对曾经编写过的代码的一部分甚至全部重新加以利用,从而构建新的程序。在谈及代码复用的时候,我们首先可以想到的是[code]继承性[/code]。代码复用的原则是:
[code]优先使用对象组合,而不是类继承[/code]
在js中,由于没有类的概念,因此实例的概念也就没多大意义,js中的对象是简单的键-值对,可以动态的创建和修改它们。 但在[code]js[/code]中,我们可以使用构造函数和[code]new[/code]操作符来实例化一个对象,这与其他使用类的编程语言在语法上有其相似之处。 例如:
[code]var trigkit4 = new Person();[/code]
[code]js[/code]在调用构造函数[code]Person[/code]时似乎看起来是一个类,但其实际上仍然是一个函数,这让我们产生了一些假定在类的基础上的开发思路和继承模式,我们可以称之为“类式继承模式”。 传统的继承模式是需要[code]class[/code]关键字的,我们假定以上的类式继承模式为[code]现代继承模式[/code],这是一种不需要以类的方式考虑的模式。 [b]类式继承模式 [/b] 看下面两个构造函数[code]Parent()[/code]和[code]Child()[/code]的例子:
[code]<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>[/code]
当使用[code]new Child()[/code]语句创建一个对象时,它会通过原型从[code]Parent()[/code]实例获取它的功能,比如:
[code]var kid = new Child();
kid.say();
//Allen[/code]
[b]原型链 [/b] 讨论一下类式继承模式下原型链的工作原理,我们将对象看做是内存中某处的块,该内存块包含数据以及指向其他块的引用。当用[code]new Parent()[/code]语句创建一个对象时,就会创建如下图左边的这样一个块,这个块保存了[code]name[/code]属性,如果想访问[code]say()[/code]方法,我们可以通过指向构造函数[code]Parent()[/code]的[code]prototype[/code](原型)属性的隐式链接[code]__proto__[/code],便可访问右边区块[code]Parent.prototype[/code]。 [img]http://files.jb51.net/file_images/article/201411/2014110711464535.jpg[/img] 那么,当使用[code]var kid = new Child()[/code]创建新对象时会发生什么?如下图: [img]http://files.jb51.net/file_images/article/201411/2014110711464736.jpg[/img] 使用[code]new Child()[/code]语句所创建的对象除了隐式链接[code]__proto__[/code]外,它几乎是空的。这种情况下,[code]__proto__[/code]指向了在[code]inherit()[/code]函数中使用[code]new Parent()[/code]语句所创建的对象 当执行[code]kid.say()[/code]时,由于最左下角的区块对象并没有[code]say()[/code]方法,因此他将通过原型链查询中间的区块对象,然而,中间的区块对象也没有[code]say()[/code]方法,因此他又顺着原型链查询到最右边的区块对象,而该对象正好有[code]say()[/code]方法。完了吗? 执行到这里的时候并没有完,在[code]say()[/code]方法中引用了[code]this.name[/code],this指向构造函数所创建的对象,在这里,它指向了[code]new Child()[/code]这个区块,然而,[code]new Child()[/code]中并没有[code]name[/code]属性,为此,将查询中间区块,而中间区块正好有[code]name[/code]属性,至此,原型链的查询完毕。 更详细的讨论请查看我这篇文章:[url=http://www.1sucai.cn/article/55951.htm]javascript学习笔记(五)原型和原型链详解[/url] [b]共享原型 [/b] 本模式的法则在于:可复用的成员应该转移到原型中而不是放置在this中。因此,处于继承的目的,任何值得继承的东西都应该放在原型中实现。所以,可以将子对象的原型与父对象的原型设置为相同即可,如下示例所示:
[code]function inherit(C,P){
    C.prototype = P.prototype;
}[/code]
[img]http://files.jb51.net/file_images/article/201411/2014110711464737.jpg[/img] 子对象和父对象共享同一个原型,并且可以同等的访问[code]say()[/code]方法。然而,子对象并没有继承[code]name[/code]属性 [b]原型继承[/b] 原型继承是一种“现代”无类继承模式。看如下实例:
[code]<script type="text/javascript">
    //要继承的对象
    var parent = {
        name : "Jack"  //这里不能有分号哦
    };[/code]
[code]    //新对象
    var child = Object(parent);[/code]
[code]    alert(child.name);//Jack
</script>[/code]
在原型模式中,并不需要使用对象字面量来创建父对象。如下代码所示,可以使用构造函数来创建父对象,这样做的话,自身的属性和构造函数的原型的属性都将被继承。
[code]<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>[/code]
本模式中,可以选择仅继承现有构造函数的原型对象。对象继承自对象,而不论父对象是如何创建的,如下实例:
[code]<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>[/code]
  • 全部评论(0)
联系客服
客服电话:
400-000-3129
微信版

扫一扫进微信版
返回顶部