js语言精粹——继承

js语言精粹——继承

伪类

当一个函数对象被创建时,Function构造器产生的函数对象会运行类似这样的代码:

this.prototype = {constructor: this};

当采用构造器调用模式,即使用new前缀去调用一个函数时,这将修改函数执行的方式。如果new运算符是一个方法而不是一个运算符,它可能会像这样执行:

Function.method('new', function(){
  //beget函数在《对象》这章出现,创建一个新对象,继承自构造器函数的对象原型
  var that = Object.beget(this.prototype);//this指向调用new函数的具体function。
  var other = this.apply(that, arguments);
  return (typeof other === 'object' && other)||that;
});

构造器函数的缺陷:

  • 没有私有环境 所有的属性是公开的, 无法访问super(父亲)的方法。
  • 如果忘记使用new前缀 , 那么this将不会被绑定到一个新对象上,同时,this绑定在全局变量上,不但没有扩充新对象,反而将破坏全局变量,并且没有提警告。

对象说明符

在编写构造器时使其接受一个简单的对象说明符可能会更加友好。那个对象包含了将要构建的对象规格说明。与其这样写

var myObject = maker(f,l,,m,s,c);

不如这么写:

var myobject = maker{{
  first: f,
  last: l,
  state: s,
  city: c
}}

原型

var myMammal = {
  name: 'Herb the Mammal',
  get_name: function(){
     return this.name;
  },
  says: function(){
    return this.saying||'';
  }
}

差异化继承: 通过定制一个新对象,指明它与所基于的基本对象的区别。
用处:对某种数据结构从其他数据结构继承的情形。

var myCat = Object.beget(myMammal);
myCat.name = 'Henrietta';
myCat.saying = 'mm';
myCat.purr = function(n){
  return n;
}
myCat.get_name = function(){
  return this.says+' '+this.name;
}

函数化

构造一个不需要new前缀产生对象的函数,包括以下几个步骤:

  1. 创建一个新对象。
  2. 选择性的定义私有实例变量和方法。这些就是函数通过var语句定义的普通变量。
  3. 给新对象扩充方法。拥有特权去访问方法
  4. 返回新对象 。
var mammal = function(spec){
  var that = {};
  that.get_name = function(){
    return spec.name;
  };
  that.says = function(){
    return spec.saying||'';
  }
  return that;
}
cat继承mammal;
var cat = function(spec){
  spec.saying = spec.saying||'meow';
  var that = mammal(spec);
  that.purr = function(n){
    var i, s = '';
    for(i = 0;i<n;i+=1){
      if(s){
        s+='-';
      }
      s+='r';
    }
    return s;
  };
  that.get_name = function(){
    return that.says()+' ' + spec.name + ' ' +that.says();
  }
  return that;
}
var myCat = cat({name: 'Henrietta'});

如果对象的所有状态都是私有的,那么该对象就成为一个‘防伪(tamper-proof)’对象。该对象的属性可以被替换或删除,但该对象的完整性不会受到损害。如果我们用函数化的样式创建一个对象,并且该对象的所有方法都不使用this或that,那么该对象就是持久性的。一个持久性的对象就是一个简单功能函数的集合。

部件

var eventuality = function(that) {
  var registry = {};
  that.fire = function(event){
    var array, func, handler,i,type;
    type = typeof event === 'string'?event:event.type;
     //如果这个事件存在一组事件处理程序中, 那么就遍历它们并按顺序依次执行。
     if(registry.hasOwnProperty(type)){
       array = registry[type];
       for(i = 0;i<array.length;i+=1){
         handler = array[i];
         func = handler.method;
         if(typeof func === 'string'){
           func = this[func]; 
         }
         //调用一个处理程序,如果该条目包含参数,那么传递它们过去。否则,传递该事件对象,
         func.apply(this, handler.parameters||[event]);
       }
     }
     return this;
    };
    //注册和绑定事件
    that.on = function(type, method, parameters){
      var handler = {
         method: method,
         parameters: parameters
      };
      if(registry.hasOwnProperty(type)){
        registry[type].push(handler);
      }else{
        registry[type] = [handler];
      }
      return this;
    };
    return that;
}
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值