一复旬、前顏(yan)
對象(Object Oriented,OO)對于基于類的語言來說是再普通不過的一個概念 了冲泥,比如C++驹碍,Java等等。
而在es5(以下js指es5)中凡恍,由于沒有類的概念志秃,因此它的對象與其他基于類的語言的對象是不同的。
因此在js中嚼酝,關于對象的創(chuàng)建方法也有所不一樣浮还。
本文介紹各種創(chuàng)建js對象的方法,以及優(yōu)缺點闽巩。
二钧舌、通過Object創(chuàng)建對象
var cat = new Object();
cat.name = 'kiki1';
cat.age = 1;
cat.speak = function () {
console.log('Hello I am ', this.name);
}
缺點:當需要創(chuàng)建多個相似對象時,會產生大量的重復代碼涎跨,比如這時候我想再創(chuàng)建一個cat2延刘,這時就得重復一遍以上代碼。
var cat2 = new Object();
cat2.name = 'kiki2';
cat2.age = 2;
cat2.speak = function () {
console.log('Hello I am ', this.name);
}
三六敬、通過對象字面量語法對象
var cat = {
name: 'kiki1',
age: 1,
speak: function () {
console.log('Hello I am ', this.name);
}
}
特點:通過此方法來創(chuàng)建對象相比Object創(chuàng)建對象代碼簡潔了很多
缺點:與通過Object創(chuàng)建對象的缺點一致
為了解決以上問題,以下模式來了驾荣。
四外构、通過工廠模式創(chuàng)建對象
function createCat(name, age) {
var o = new Object();
o.name = name;
o.age = age;
o.speak = function () {
console.log('Hello I am ', this.name);
}
return o;
}
var cat1=createCat('kiki1',1);
var cat2=createCat('kiki2',2);
cat1.speak(); //Hello I am kiki1
cat2.speak(); //Hello I am kiki2
特點:通過工廠模式創(chuàng)建對象普泡,可以解決創(chuàng)建多個相似對象的問題。
缺點:無法識別對象审编,即無法知道一個對象的類型撼班。
五、通過構造函數(shù)模式創(chuàng)建對象
通過構造函數(shù)模式創(chuàng)建對象垒酬,能夠很好的解決工廠模式創(chuàng)建對象的問題砰嘁。
function Cat(name, age) {
this.name = name;
this.age = age;
this.speak = function () {
console.log('Hello I am ', this.name);
}
}
let cat1 = new Cat('kiki1', 1);
let cat2 = new Cat('kiki2', 2);
cat1.speak(); //Hello I am kiki1
cat2.speak(); //Hello I am kiki2
// 檢測對象類型
console.log(cat1 instanceof Cat); // true
console.log(cat2 instanceof Cat); // true
// 不同實例上的同名函數(shù)是不相等
console.log(cat1.speak == cat2.speak); // false
特點:
1筷笨、通過new Cat來創(chuàng)建實例
2张遭、可以通過instanceof來檢測對象類型
缺點:
使用構造函數(shù)的缺點在于码耐,每個方法都會在實例上重新創(chuàng)建一遍琼锋,所以不同實例上的同名函數(shù)是不相等的,即無法共享方法饺蚊。比如上面的例子中的cat1.speak和cat2.speak是不相等的托呕。
為了解決此缺點差牛,請看原型模式音羞。
六景描、原型模式
function Cat() { }
Cat.prototype.name = 'kiki1';
Cat.prototype.age = 1;
Cat.prototype.speak = function () {
console.log('Hello I am ', this.name);
}
Cat.prototype.data = [1, 2];
let cat1 = new Cat();
let cat2 = new Cat();
console.log(cat1.speak == cat2.speak); // true
// 引用類型屬性十办,不同實例之間互相影響
console.log(cat2.data); // [1,2]
cat1.data.push(3);
console.log(cat1.data); // [1,2,3]
console.log(cat2.data); // [1,2,3]
特點:共享方法,比如上面的例子中超棺,cat1.speak和cat2.speak是相等的向族。
缺點:由于引用類型的屬性也是共享的,因此不同實例之間會互相影響
六棠绘、組合模式
組合模式:即構造函數(shù)模式+原型模式件相。
采用組合模式可以解決構造函數(shù)模式和原型模式的問題,又擁有構造函數(shù)和原型模式的特點弄唧,集兩種模式之長适肠。
通過構造函數(shù)模式定義實例屬性,通過原型模式定義共享方法和共享屬性候引。
function Cat(name, age, data) {
this.name = name;
this.age = age;
this.data = data;
}
Cat.prototype.speak = function () {
console.log('Hello I am ', this.name);
}
let cat1 = new Cat('kiki1', 1, [1, 2, 3]);
let cat2 = new Cat('kiki2', 2, [3, 4, 5]);
console.log(cat1.speak == cat2.speak); // true
console.log(cat1.data); // [1,2,3]
console.log(cat2.data); // [3,4,5]
綜上對比侯养,組合模式是最優(yōu)雅的創(chuàng)建對象的方式。