js面向對象

建立對象的方法

1.字面量javascript

// 優勢:簡單方便
// 缺點:每建立一個對象都要從新寫,且建立多個比較佔內存
var obj1 = {
    name: 'liuhui1'
};
var obj2 = new Object({
    name: 'liuhui2'
});
var obj3 = Object.create({
    name: 'liuhui3'
});

2.工廠模式html

// 優勢:改善了字面量方法建立多個類似對象的問題,不須要編寫重複的代碼
// 缺點:沒有解決對象是別的問題,不知道對象的類型是什麼
function person () {
    var obj = new Object();
    obj.name = 'liuhui4';
    obj.sayName = function () {
      console.log(this.name);
    };
    return obj;
}
var obj4 = person();
console.log(obj4.sayName());

3.構造函數模式java

// 優勢:建立並定義了對象類型的屬性和方法,能夠標示爲特定的類型(自定義構造函數,原生:Object/Array)
// 缺點:方法沒有被共享,每次實例一個對象都要重複綁定一個獨立的方法
function Person (name) {
    this.name = name;
    this.sayName = function () {
        console.log(this.name);
    };
    this.newFun = newFun;
}
// 解決辦法:將方法寫在全局,可是就變成全局方法了跟封裝的觀念相違背了
// 新增代碼
function newFun () {
    console.log('new name: ' + this.name);
}
var obj5 = new Person('liuhui5');
console.log(obj5.sayName());

4.原型模式函數

// 優勢:將方法封裝到相應的原型對象上,私有並實例能夠共享這些屬性和方法
// 缺點:全部屬性和方法都共享了,改變實例的屬性和方法會影響原型對象上的屬性和方法
function Person1 () {

}
Person1.prototype = {
    constructor: Person1,
    name: 'liuhui6',
    sayName: function () {
        console.log(this.name);
    }
};
var obj6 = new Person1();
console.log(obj6.sayName());

5.組合模式(構造函數+原型模式)尚未徹底理解優化

// 優勢:構造函數用於定義實例屬性和方法,原型模式用於共享定義的屬性和方法
function Person2 (name) {
    this.newName = function () {
        console.log(name);
    }
}
Person2.prototype = {
    constructor: Person2,
    name: 'liuhui7',
    sayName: function () {
        console.log(this.name);
    }
};
var obj7 = new Person2();
var obj8 = new Person2('liuhui8');

繼承的方法

1.藉助構造函數實現繼承ui

// 缺點:父級構造函數屬性和方法沒有被共享
function Parent1 () {
    this.name = 'parent1';
    this.play = [1, 2, 3];
}
function Child1 () {
    Parent1.call(this); // 關鍵:執行父級構造函數,深複製
    this.type = 'child1';
}
Parent1.prototype.say = function () {
    console.log('hello1');
};
console.log(new Child1());
var s1 = new Child1();
var s2 = new Child1();
s1.play.push(4);
console.log(s1.play, s2.play, s1.hasOwnProperty('play'), 'test1');

2.藉助原型鏈實現繼承this

// 缺點:原型鏈上的屬性和方法是共享
function Parent2 () {
    this.name = 'parent2';
    this.play = [1, 2, 3];
}
function Child2 () {
    this.type = 'child';
}
Parent2.prototype.say = function () {
    console.log('hello2');
};
Child2.prototype = new Parent2(); // 關鍵:將子級執行父級構造函數實現繼承,淺複製
console.log(new Child2(), new Child2().say());
var s3 = new Child2();
var s4 = new Child2();
s3.play.push(4);
console.log(s3.play, s4.play, s3.hasOwnProperty('play'), 'test2');

3.組合方式prototype

// 缺點:父級構造函數執行了兩遍
function Parent3 () {
    this.name = 'parent3';
    this.play = [1, 2, 3];
}
function Child3 () {
    Parent3.call(this); // 關鍵1
    this.type = 'child3';
}
Parent3.prototype.say = function () {
    console.log('hello3');
};
Child3.prototype = new Parent3(); // 關鍵2
var s5 = new Child3();
var s6 = new Child3();
s5.play.push(4);
console.log(s5, s6, s5.hasOwnProperty('play'), 'test');

4.組合方式優化1code

// 缺點:實例屬性constructor指向父級構造函數,使用instanceof不能正確判斷對象類型
function Parent4 () {
    this.name = 'parent4';
    this.play = [1, 2, 3];
}
function Child4 () {
    Parent4.call(this);
    this.type = 'child4';
}
Parent4.prototype.say = function () {
    console.log('hello4');
};
Child4.prototype = Parent4.prototype;
Child4.prototype.constructor = Child4; // 新增代碼,讓實例指向其真實的構造函數
var s7 = new Child4();
var s8 = new Child4();
s7.play.push(4);
console.log(s7, s8);
// 判斷是子原型Child4實例化仍是Parent4直接實例化的
console.log(s7 instanceof Child4, s8 instanceof Parent4); // 判斷不了
console.log(s7.constructor, s8.constructor, s7.hasOwnProperty('play'), 'test');

5.組合方式優化2htm

function Parent5 () {
    this.name = 'parent5';
    this.play = [1, 2, 3];
}
function Child5 () {
    Parent5.call(this);
    this.type = 'child5';
}
Parent5.prototype.say = function () {
    console.log('hello5');
};
Child5.prototype = Object.create(Parent5.prototype);
Child5.prototype.constructor = Child5;
var s9 = new Child5();
var s10 = new Child5();
s9.play.push(4);
console.log(s9 instanceof Child5, s9 instanceof Parent5);
console.log(s9.constructor, s10.constructor, s9.hasOwnProperty('play'), 'test11');

參考

相關文章
相關標籤/搜索