JavaScript 封裝,繼承,原型鏈

 

js是一門基於對象的語言,但它沒有完整的class概念,至少在ES5中是沒有的

封裝--原始模式:

Cat = {

name : '',

color : ''

};

let cat1 = {};

cat1.name = '大花';

cat1.color = 'white';

let cat2 = {};

cat2.name = '二哈';

cat2.color = 'yellow';

 

此時js中沒有類的概念,可以看出:兩個實例的貓 cat1 和 cat2 沒有任何聯繫

因此前人對原始模式進行改進

封裝--構造函數模式

function Cat(name,color) {

  this.name=name;

  this.color=color;

}

let cat1 = new Cat('大花', 'white'); // Cat {name: '大花', color:'white'}

let cat2 = new Cat('二哈', 'yellow');

現在看起來,是不是好多了?兩隻貓用一個構造函數構造出來

但是還存在一個問題,如果兩個貓存在共同的屬性type,以及方法eat,那會造成資源的浪費

封裝--工廠模式

function Cat(name,color) {

  this.name=name;

  this.color=color;

}

Cat.prototype.type = '貓科動物';

Cat.prototype.eat = function () {

  console.log('喫魚');

};

let cat1 = new Cat('大花', 'white');

let cat2 = new Cat('二哈', 'yellow');

console.log(cat1);

console.log(cat1.type);

這樣兩個實例都有type屬性和eat方法,指向同一個地址,做到了節省資源的目的   

console.log(cat1.eat == cat2.eat); // true

爲了配合protype使用,在Object的原型上定義了isPrototypeOf  

console.log(Cat.prototype.isPrototypeOf(cat1)); // true

console.log(cat1.hasOwnProperty('name')); // true   判斷是否是自身屬性,繼承屬性不算

console.log('name' in cat1); // 判斷屬性在不在實例上,繼承也算

繼承--構造函數綁定

使用call或apply方法,將父對象的構造函數綁定在子對象上,即在子對象構造函數中加一行:

function Animal() {

  this.species = '動物';

}

function Cat(name,color) {

  Animal.apply(this, arguments);

  this.name=name;

  this.color=color;

}

let cat1 = new Cat('大花', 'white');

console.log(cat1.species);

繼承--prototype模式

”貓“的 prototype 指向 Animal 的實例,這樣貓的實例就能繼承 Animal 了

function Animal() {

  this.species = '動物';

}

// Animal.prototype.species = '動物‘;

function Cat(name,color) {

  this.name=name;

  this.color=color;

}

Cat.prototype = new Animal();

Cat.prototype.constructor = Cat; // 手動糾正cat1.constructor指向Animal

let cat1 = new Cat('大花', 'white');

console.log(cat1.species);

淺拷貝

把父對象的屬性,全部拷貝給子對象,也能實現繼承

var Chinese = { nation:'中國' };

var Doctor ={ career:'醫生' }

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 = '醫生';

console.log(Doctor.nation); // 中國

淺拷貝存在一個問題,當Chinese中存在一個數組屬性nation: ['漢族',’回族‘,’苗族‘],改變子對象屬性時,父對象屬性有被篡改的風險

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章