日期:2014-05-16  浏览次数:20444 次

javascript 封装 继承

原文地址:http://www.ruanyifeng.com/blog/2010/05/object-oriented_javascript_encapsulation.html
封装:

所谓"构造函数",其实就是一个普通函数,但是内部使用了this变量。
对构造函数使用new运算符,就能生成实例,并且this变量会绑定在实例对象上。

Javascript规定,每一个构造函数都有一个prototype属性,指向另一个对象。
这个对象的所有属性和方法,都会被构造函数的实例继承。
这意味着,我们可以把那些不变的属性和方法,直接定义在prototype对象上。

Prototype模式的验证方法:
isPrototypeOf() :这个方法用来判断,某个proptotype对象和某个实例之间的关系。
hasOwnProperty():每个实例对象都有一个hasOwnProperty()方法,
??? ??? ??? ??? 用来判断某一个属性到底是本地属性,还是继承自prototype对象的属性。
??? ??? ??? ???
in运算符 :??? in运算符可以用来判断,某个实例是否含有某个属性,不管是不是本地属性。
??? ??? ??? in运算符还可以用来遍历某个对象的所有属性。
??? ??? ???


原文地址:http://www.ruanyifeng.com/blog/2010/05/object-oriented_javascript_inheritance.html??? ??? ???
继承:

 ??? function Animal(){
    this.species = "动物";
  }

??? function Cat(name,color){
    this.name = name;
    this.color = color;
  }

1. 构造函数绑定:最简单的方法,大概就是使用call或apply方法,将父对象的构造函数绑定在子对象上,也就是在子对象构造函数中加一行

??? function Cat(name,color){
    Animal.apply(this, arguments);
    this.name = name;
    this.color = color;
  }
  var cat1 = new Cat("大毛","黄色");
  alert(cat1.species); // 动物

2.prototype模式

??? Cat.prototype = new Animal();
  Cat.prototype.constructor = Cat;
  var cat1 = new Cat("大毛","黄色");
  alert(cat1.species); // 动物

3. 直接继承prototype
???
??? function Animal(){ }
  Animal.prototype.species = "动物";
???
??? Cat.prototype = Animal.prototype;
  Cat.prototype.constructor = Cat;
  var cat1 = new Cat("大毛","黄色");
  alert(cat1.species); // 动物

4. 利用空对象作为中介
??? var F = function(){};
  F.prototype = Animal.prototype;
  Cat.prototype = new F();
  Cat.prototype.constructor = Cat;

5. prototype模式的封装函数
???
??? function extend(Child, Parent) {
    var F = function(){};
    F.prototype = Parent.prototype;
    Child.prototype = new F();
    Child.prototype.constructor = Child;
    Child.uber = Parent.prototype;
  }
??? 函数体最后一行:意思是为子对象设一个uber属性,这个属性直接指向父对象的prototype属性。
??? 这等于是在子对象上打开一条通道,可以直接调用父对象的方法。
??? 这一行放在这里,只是为了实现继承的完备性,纯属备用性质。

6. 拷贝继承
??? function Animal(){}
  Animal.prototype.species = "动物";

??? function extend2(Child, Parent) {
    var p = Parent.prototype;
    var c = Child.prototype;
    for (var i in p) {
      c[i] = p[i];
    }
    c.uber = p;
  }
???
??? //调用
??? extend2(Cat, Animal);
  var cat1 = new Cat("大毛","黄色");
  alert(cat1.species); // 动物


非构造函数的继承:http://www.ruanyifeng.com/blog/2010/05/object-oriented_javascript_inheritance_continued.html

1、什么是"非构造函数"的继承?
??? var Chinese = {
    nation:'中国'
  };
??? var Doctor ={
    career:'医生'
  }
??? 这里要注意,这两个对象都是普通对象,不是构造函数,无法使用构造函数方法实现"继承"
2、object()方法
??? function object(o) {
    function F() {}
    F.prototype = o;
    return new F();
  }
??? //调用
??? var Doctor = object(Chinese);
??? Doctor.career = '医生';

3、浅拷贝:除了使用"prototype链"以外,还有另一种思路:把父对象的属性,全部拷贝给子对象,也能实现继承。

??? function extendCopy(p) {
    var c = {};
    for (var i in p) {
      c[i] = p[i];
    }
    c.uber = p;
    return c;
  }
??? //调用
??? var Doctor = extendCopy(Chinese);
  Doctor.career = '医生';
  alert(Doctor.nation); // 中国

4、深拷贝???
??? function deepCopy(p, c) {
    var c = c || {};
    for (var i in p) {
      if (typeof p[i] === 'object') {
        c[i] = (p[i].constructor === Array) ? [] : {};
        deepCopy(p[i], c[i]);
      } else {
         c[i] = p[i];
      }
    }
    return c;
  }
??? //调用
??? var Doctor = deepCopy(Chinese);
??? Chinese.birthPlaces = ['北京','上海','香港'];
  Doctor.birthPlaces.push('厦门');
??? alert(Doctor.birthPlaces); //北京