JavaScript 創(chuàng)建對(duì)象的多種方式以及優(yōu)缺點(diǎn)

JavaScript 創(chuàng)建對(duì)象的多種方式以及優(yōu)缺點(diǎn)

1.工廠(chǎng)模式

function createPerson(name) {
  var o = new Object();
  o.name = name;
  o.getName = function() {
    console.log(this.name)
  };
  return o;
}

var person1 = createPerson('cause');

缺點(diǎn):對(duì)象無(wú)法識(shí)別,因?yàn)樗械膶?shí)例都指向一個(gè)原型

2.構(gòu)造函數(shù)模式

function Person(name) {
  this.name = name;
  this.getName = function() {
    console.log(this.name);
  }
}

var person = new Person('cause');

優(yōu)點(diǎn):實(shí)例可以識(shí)別為一個(gè)特定的類(lèi)型

缺點(diǎn):每次創(chuàng)建實(shí)例時(shí),每個(gè)方法都要被創(chuàng)建一次

2.1 構(gòu)造函數(shù)模式優(yōu)化

function Person(name) {
  this.name = name;
  this.getName = getName;
  }
}
function getName() {
  console.log(this.name);
}

var person = new Person('cause');

優(yōu)點(diǎn):解決了每個(gè)方法都要被重新創(chuàng)建的問(wèn)題

缺點(diǎn):這叫啥封裝……

3.1 原型模式

function Person(name) {
 
}
 
Person.prototype = {
    name: 'cause',
    getName: function () {
        console.log(this.name);
    }
};
 
var person1 = new Person();

優(yōu)點(diǎn):封裝性好了一點(diǎn)

缺點(diǎn):重寫(xiě)了原型,丟失了constructor屬性

3.2 原型模式優(yōu)化

function Person(name) {

}
Person.prototype = {
  constructor: Person,
  name: "cause",
  getName: function() {
    console.log(this.name);
  }
};

var person1 = new Person();

優(yōu)點(diǎn):實(shí)例可以通過(guò)constructor屬性找到所屬構(gòu)造函數(shù)

缺點(diǎn):原型模式該有的缺點(diǎn)還是有

4. 組合模式

構(gòu)造函數(shù)模式與原型模式雙劍合璧。

function Person(name) {
  this.name = name;
}
Person.prototype = {
  constructor: Person,
  getName: function() {
    console.log(this.name);
  }
};

var person1 = new Person();

優(yōu)點(diǎn):該共享的共享,該私有的私有,使用最廣泛的方式

缺點(diǎn):有的人就是希望全部都寫(xiě)在一起,即更好的封裝性

繼承的多種方式和優(yōu)缺點(diǎn)

1.原型鏈繼承

function Parent() {
  this.name = "cause";
}
Parent.prototype.getName = function() {
  console.log(this.name);
}
function Child() {

}
Child.prototype = new Parent();

var child1 = new Child();
console.log(child1.getName()); // cause

問(wèn)題:

1.引用類(lèi)型的屬性被所有實(shí)例共享,舉個(gè)例子:

function Parent() {
  this.names = ['cause', 'xl'];
}
function Child() {

}

Child.prototype = new Parent();

var child1 = new Child();
console.log(child1.names); // ["kevin", "daisy", "yayu"]

var child2 = new Child();
console.log(child2.names); // ["kevin", "daisy", "yayu"]

2.在創(chuàng)建 Child 的實(shí)例時(shí),不能向Parent傳參

2.借用構(gòu)造函數(shù)(經(jīng)典繼承)

function Parent() {
  this.names = ['cause', 'xl'];
}
function Child() {
  Parent.call(this);
}

var child1 = new Child();
child1.names.push('cayden');
console.log(child1.names); // ["kevin", "daisy", "yayu"]

var child2 = new Child();
console.log(child2.names); // ["kevin", "daisy"]

優(yōu)點(diǎn):

1.避免了引用類(lèi)型的屬性被所有實(shí)例共享

2.可以在 Child 中向 Parent 傳參

舉個(gè)例子:

function Parent (name) {
    this.name = name;
}

function Child (name) {
    Parent.call(this, name);
}

var child1 = new Child('kevin');
console.log(child1.name); // kevin

var child2 = new Child('daisy');
console.log(child2.name); // daisy

缺點(diǎn):

方法都在構(gòu)造函數(shù)中定義,每次創(chuàng)建實(shí)例都會(huì)創(chuàng)建一遍方法。

3.組合繼承

原型鏈繼承和經(jīng)典繼承雙劍合璧。

function Parent (name) {
    this.name = name;
    this.colors = ['red', 'blue', 'green'];
}

Parent.prototype.getName = function () {
    console.log(this.name)
}

function Child (name, age) {
    Parent.call(this, name);
    this.age = age;
}

Child.prototype = new Parent();

var child1 = new Child('kevin', '18');

child1.colors.push('black');

console.log(child1.name); // kevin
console.log(child1.age); // 18
console.log(child1.colors); // ["red", "blue", "green", "black"]

var child2 = new Child('daisy', '20');

console.log(child2.name); // daisy
console.log(child2.age); // 20
console.log(child2.colors); // ["red", "blue", "green"]

優(yōu)點(diǎn):融合原型鏈繼承和構(gòu)造函數(shù)的優(yōu)點(diǎn),是 JavaScript 中最常用的繼承模式。

精益求精

function Parent (name) {
    this.name = name;
    this.colors = ['red', 'blue', 'green'];
}

Parent.prototype.getName = function () {
    console.log(this.name)
}

function Child (name, age) {
    Parent.call(this, name);
    this.age = age;
}

// 關(guān)鍵的三步
var F = function () {};
F.prototype = Parent.prototype;
Child.prototype = new F();

var child1 = new Child('kevin', '18');

最后我們封裝一下這個(gè)繼承方法:

function object(o) {
    function F() {}
    F.prototype = o;
    return new F();
}

function prototype(child, parent) {
    var prototype = object(parent.prototype);
    prototype.constructor = child;
    child.prototype = prototype;
}

// 當(dāng)我們使用的時(shí)候:
prototype(Child, Parent);

更多閱讀

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請(qǐng)結(jié)合常識(shí)與多方信息審慎甄別。
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡(jiǎn)書(shū)系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

友情鏈接更多精彩內(nèi)容