• 第5章-继承


    JavaScript提供了一套丰富的代码重用模式。它可以模拟那些基于类的模式,同时可以支持其他更具表现力的模式。我们下面将研究几种最为直接的模式。

    伪类 Pseudoclassical

    JavaScript的原型存在这许多的矛盾,它不直接让对象从其他对象继承,反而插入了一个多余的间接层:通过构造函数产生对象。
    当一个函数对象被创建时,Function构造器产生的函数对象会运行类似这样的一些代码:
    this.prototype = {constructor: this};
    新函数对象被赋予一个Prototype属性,它的值是一个包含consrtuctor属性且属性值为该新函数的对象。
    我们可以定义一个构造器并扩充它的原型

     1     var Mammal = function(name){
     2         this.name = name;
     3     };
     4 
     5     Mammal.prototype.get_name = function(){
     6         return this.name;
     7     };
     8 
     9     Mammal.prototype.says = function(){
    10         return this.saying || '';
    11     };
    12 
    13     var mymammal = new Mammal('QQQ');
    14     var name = mymammal.get_name();
    15 
    16     //我们可以构造另一个伪类来继承Mammal,这是通过定义它的constructor函数并替换它的prototype为一个Mammal的实例来实现的:
    17 
    18     var Cat = function(name){
    19         this.name = name;
    20         this.saying = 'OW';
    21     };
    22 
    23     Cat.prototype = new Mammal();
    24 
    25     Cat.prototype.purr = function(n){
    26         var i, s = '';
    27         for(i = 0;i < n;i++){
    28             if(s){
    29                 s += '-';
    30             }
    31             s += 'r';
    32         }
    33         return s;
    34     };
    35 
    36     Cat.prototype.get_name = function(){
    37         return this.says() + ' ' + this.name + ' ' + this.says();
    38     };
    39 
    40     var myCat = new Cat('XMM');
    41     var says = myCat.says();    //"OW"
    42     var myname = myCat.get_name(); //"OW XMM OW"
    43     var pr = myCat.purr(5);    //"r-r-r-r-r"

    这种方法没有私有属性,所有的属性都是公开的,无法访问父类的方法。更糟糕的是,使用构造器函数存在一个严重的危害,如果你在调用构造器函数时忘记了在前面加上new前缀,那么this将不会绑定到一个新对象上。而是绑定到全局对象上

    原型 Prototype

    让我们先用对象字面量去构造一个有用的对象

     1     var myMammal = {
     2         name: 'QQQ',
     3         get_name: function(){
     4             return this.name;
     5         },
     6         says: function(){
     7             return this.says || ' ';
     8         }
     9     };
    10 
    11     //定制新的实例
    12     var myCat = Object.create(myMammal);
    13     myCat.name = 'XMM';
    14     myCat.says = 'OW';
    15     myCat.pr = function(n){
    16         var i, s = '';
    17         for(i = 0;i < n;i++){
    18             if(s){
    19                 s += '-';
    20             }
    21             s += 'r';
    22         }
    23         return s;
    24     };
    25     myCat.get_name =  function(){
    26         return this.says() + ' ' + this.name + ' ' + this.says();
    27     };

    这是一种“差异化继承”。通过定制一个新的对象,我们指明它与所基于的基本对象的区别。

    函数化 Function

    迄今为止,我们所看到的继承模式的一个弱点就是没办法保护隐私。对象的所有属性都是可见的。我们无法得到私有变量和私有函数。现在,我们有一个更好的选择,那就是应用模块模式
    我们从构造一个生成对象的函数开始。我们以小写字母开头,因为它并不需要new前缀。该函数包含4个步骤

    【1】创建一个新对象,有很多的方式去创建一个对象,他可以构造一个对象字面量,或者用构造函数,或者使用Object.create(),或者调用一个会返回一个对象的函数。
    【2】有选择的定义私有变量和方法
    【3】给这个对象扩充方法。这些方法拥有特权去访问参数
    【4】返回那个新对象

    这里是一个函数化构造器的伪代码模板:

     1     var constructor = function(spec,my){
     2         var that,其他私有变量;
     3         my = my || {};
     4 
     5         把共享的变量和函数添加到my中
     6 
     7         that = 一个新对象
     8 
     9         添加给that的特权方法
    10 
    11         return that;
    12     };

    让我们把这个模式应用到mammal例子里。此处不需要my,所以我们先抛开它,但会使用一个spec对象。

     1     var mammal = function (spec){
     2         var that = {};
     3 
     4         that.get_name: function(){
     5             return this.name;
     6         };
     7         that.says: function(){
     8             return this.says || ' ';
     9         };
    10 
    11         return that;
    12     };
    13 
    14     var myMammal = mammal({name: 'Herb'});
    不要在该奋斗的年纪而选择了安逸
  • 相关阅读:
    强行拉取git分支到覆盖到本地
    提交git报错:rejected non fast forward
    表单验证
    获取ipv6转换ipv4
    使用js获取外网ip
    --打坐篇-学习的一些笔记-03--
    --心法篇-《我和我的Angular》-01-学习笔记--
    --打坐篇-学习的一些笔记-02--
    --打坐篇-学习的一些笔记-01--
    --前端派-练功房-01-关于this指向的一些案例补充--
  • 原文地址:https://www.cnblogs.com/qqandfqr/p/5967591.html
Copyright © 2020-2023  润新知