something(1)

上半年部门里专门有一个分享会,大家讨论原型继承方面的内容,主要讨论原型继承,借用构造函数继承,复制属性继承。
随便聊了聊在其中要注意的问题,比如继承时,对象无法被复制仅能被引用,就像过去学的C语言的指针,以及VB在传递参数时的byref一样。如果原型中的某一个属性是对象,比如[] || {} ,那么子类在修改的时候就会互相影响,所以可以使用借用构造函数,在实例中声明引用类型。或者通过复制属性继承。但是复制属性继承又有一个问题,如果仅仅是for in的循环一次,那么仅仅是一次shallow copy(浅复制),我们还需要进行更深度的复制,就是(deep copy)。

浅克隆

function shallowcopy(parent,child){
    var i,
        child = child||{};
    for(i in parent){
        child[i] = parent[i];
    }
    return child;
}

深克隆

function deepcopy(parent,child){
    var i,
        child = child||{};
    for(i in parent){
      if(parent.hasOwnProperty(i)){
          if(typeof parent[i] === "object"){
            child[i] = (Object.prototype.toString.call(parent[i]) === "[object Array]")?[]:{};
            deepcopy(parent[i],child[i]);
          }else{
            child[i] = parent[i];
          }
      }
    }
    return child;
}

看了下underscore的extend 方法

_.extend = function(obj) {
    each(slice.call(arguments, 1), function(source) {
      if (source) {
        for (var prop in source) {
          obj[prop] = source[prop];
        }
      }
    });
    return obj;
  };

是浅克隆的。

但是Backbone的extend却是另外一种写法了。仅仅是在函数内部用到了underscore的extend方法

var extend = function(protoProps, staticProps) {
    var parent = this;
    var child;

    // The constructor function for the new subclass is either defined by you
    // (the "constructor" property in your `extend` definition), or defaulted
    // by us to simply call the parent's constructor.
    if (protoProps && _.has(protoProps, 'constructor')) {
      child = protoProps.constructor;
    } else {
      child = function(){ return parent.apply(this, arguments); };
    }

    // Add static properties to the constructor function, if supplied.
    _.extend(child, parent, staticProps);

    // Set the prototype chain to inherit from `parent`, without calling
    // `parent`'s constructor function.
    var Surrogate = function(){ this.constructor = child; };
    Surrogate.prototype = parent.prototype;
    child.prototype = new Surrogate;

    // Add prototype properties (instance properties) to the subclass,
    // if supplied.
    if (protoProps) _.extend(child.prototype, protoProps);

    // Set a convenience property in case the parent's prototype is needed
    // later.
    child.__super__ = parent.prototype;

    return child;
  };

还有一种混入的方式,mix-in方式。即是从多个对象中复制出任意的成员并将这些成员组合成一个新对象。

 function mix(){
      var arg,prop,len,child = {};
      for(arg = 0,len = arguments.length;arg<len;arg++){
        for(prop in arguments[arg]){
          if(arguments[arg].hasOwnProperty(prop)){
            child[prop] = arguments[arg][prop];
          }
        }
      }
      return child;
    }

发表评论

电子邮件地址不会被公开。 必填项已用*标注

此站点使用Akismet来减少垃圾评论。了解我们如何处理您的评论数据