Js_面向对象_02

来源:互联网 发布:詹姆斯生涯数据统计 编辑:程序博客网 时间:2024/06/06 05:09

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

    function Cat(name, color) {            this.name = name;            this.color = color;      }      Cat.prototype.type = "猫科动物";      Cat.prototype.eat = function() {        alert("吃老鼠")    };     var cat1 = new Cat("大毛", "黄色");      var cat2 = new Cat("二毛", "黑色");      console.log(cat1.type); // 猫科动物    cat1.eat();             // 吃老鼠    这时cat1和cat2会自动含有一个 constructor 属性,     指向它们的构造函数。    console.log(cat1.constructor == Cat); //true    console.log(cat2.constructor == Cat); //true    instanceof运算符, 验证原型对象与实例对象之间的关系。      alert(cat1 instanceof Cat); //true    alert(cat2 instanceof Cat); //true    这时所有实例的type属性和eat() 方法,     其实都是同一个内存地址, 指向prototype对象,     因此就提高了运行效率。      alert(cat1.eat == cat2.eat); //true

Prototype模式的验证方法

6.1 isPrototypeOf()     判断,某个proptotype对象和某个实例之间的关系。    alert(Cat.prototype.isPrototypeOf(cat1)); //true6.2 hasOwnProperty()   有自己的属性    每个实例对象都有一个hasOwnProperty()方法,    用来判断某一个属性到底是本地属性,还是继承自prototype对象的属性。    alert(cat1.hasOwnProperty("name")); // true   6.3 in运算符     1.判断某个实例是否含有某个属性,不管是不是本地属性。    alert("type" in cat1); // true    2.in运算符还可以用来遍历某个对象的所有属性。    for(var prop in cat1){        alert("cat1["+prop+"]="+cat1[prop]);     }

Javascript面向对象编程(二)构造函数的继承

function Animal() {        this.species = "动物";  }function Cat(name, color) {      //在extend方法中uber要在Cat中进行体现    Cat.uber.constructor.call(this);         this.name = name;        this.color = color;  }

1.构造函数绑定

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

2.prototype模式

Cat.prototype = new Animal();  Cat.prototype.constructor = Cat;  console.log(Cat.prototype.constructor == Animal);var cat1 = new Cat("大毛", "黄色");  console.log(cat1.species); // 动物代码解析:第一行:将Cat的prototype对象指向一个Animal的实例;相当于完全删除了prototype 对象原先的值,然后赋予一个新值;任何一个prototype对象都有一个constructor属性,指向它的构造函数;Cat.prototype.constructor指向Animal第二行:所以加第二行其实  每一个实例也有一个constructor属性,     默认调用prototype对象的constructor属性。----------小例子://父构造函数(父类)function P1(name, sex){    this.name = name;    this.sex = sex;}P1.prototype.showName = function(){    alert("123123");}function P2(age){    this.age = age;}P2.prototype = new P1("中国人", "boy");P2.prototype.constructor = P2;var pp = new P2("18");console.log(pp);console.log(pp.name)

3.利用空对象作为中介
解决直接机继承浪费资源的问题

var F = function() {};  F.prototype = Animal.prototype;  Cat.prototype = new F();  Cat.prototype.constructor = Cat;代码解析F是空对象, 所以几乎不占内存。 这时,修改Cat的prototype对象,就不会影响到Animal的prototype对象。 封装上面function extend(Child, Parent) {                        var F = function() {};        F.prototype = Parent.prototype;        Child.prototype = new F();        Child.prototype.constructor = Child;        Child.uber = Parent.prototype;  }extend(Cat, Animal);  var cat1 = new Cat("大毛", "黄色");  alert(cat1.species); // 动物封装方法最后一行解析:子对象上打开一条通道, 可以直接调用父对象的方法。(备用)

4.拷贝继承

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); // 动物

Javascript面向对象编程(三)非构造函数的继承
一、什么是”非构造函数”的继承?
这两个对象都是普通对象,不是构造函数,无法使用构造函数方法实现”继承”。

var Chinese = { //对象一:      nation:'中国'  };  var Doctor ={ //对象二:    career:'医生'  }

二、object()方法

function object(o) {    function F() {}    F.prototype = o;    return new F();  }把子对象的prototype属性,指向父对象使用:var Doctor = object(Chinese);Doctor.career = '医生';alert(Doctor.nation); //中国代码解析:先在父对象的基础上,生成子对象:然后,再加上子对象本身的属性:这时,子对象已经继承了父对象的属性了。  

三、浅拷贝

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); // 中国但是,这样的拷贝有一个问题。如果父对象的属性等于数组或另一个对象,那么实际上,子对象获得的只是一个内存地址,而不是真正拷贝,因此存在父对象被篡改的可能。例子:  Chinese.birthPlaces = ['北京','上海','香港'];  var Doctor = extendCopy(Chinese);  Doctor.birthPlaces.push('厦门');  alert(Doctor.birthPlaces); //北京, 上海, 香港, 厦门  alert(Chinese.birthPlaces); //北京, 上海, 香港, 厦门所以,extendCopy()只是拷贝基本类型的数据,我们把这种拷贝叫做"浅拷贝"。这是早期jQuery实现继承的方式

四、深拷贝
所谓”深拷贝”,就是能够实现真正意义上的数组和对象的拷贝。
它的实现并不难,只要递归调用”浅拷贝”就行了。

  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); //北京, 上海, 香港, 厦门  alert(Chinese.birthPlaces); //北京, 上海, 香港
0 0