IT培訓(xùn)網(wǎng)
IT在線學(xué)習(xí)
面向?qū)ο蟮恼Z言有一個標(biāo)志,那就是它們都有類的概念,而通過類可 以創(chuàng)建任意多個具有相同屬性和方法的對象。前面提到過,ECMAScript 中沒有類的概念,因此它的對象也與基于類的語言中的對象有所不同。
ECMA把對象定義為:“無序?qū)傩缘募,其屬性可以包含基本值、對象或者函?shù)。對象的每個屬性或方法都有一個名字,而每個名字都映射到一個值。
我們之前在學(xué)習(xí)創(chuàng)建對象時,使用字面量方式和Object構(gòu)造函數(shù)的方式都可以進行創(chuàng)建對象,但是我們也發(fā)現(xiàn)了這兩種方式只適合用來創(chuàng)建單個對象,想要創(chuàng)建大量對象時,一份代碼就要書寫多次,顯然的產(chǎn)生了代碼冗余。接下來來介紹幾種其他創(chuàng)建對象的方式。
工廠模式創(chuàng)建對象:
上面我們說使用Object構(gòu)造函數(shù)的方式進行創(chuàng)建多個對象時,會產(chǎn)生大量重復(fù)代碼,那自然而然我們就會想到將重復(fù)性的代碼封裝成為一個函數(shù),這個函數(shù)就是工廠函數(shù)。
- // 工廠模式實際上就是封裝函數(shù)
- function createStar(name, age, sex){
- // 1.創(chuàng)建一個空對象(原材料)
- var obj = {};
- // 2.添加屬性和方法(加工)
- obj.name = name;
- obj.age = age;
- obj.sex = sex;
- obj.skill = function(){
- console.log('sing dance');
- }
- // 3.返回出對象(出廠)
- return obj
- }
- // 創(chuàng)建對象
- var star1 = createStar('何美男',25,'boy');
- console.log(star1);
- star1.skill(); // sing dance
使用工廠模式創(chuàng)建對象雖然可以實現(xiàn)批量創(chuàng)建對象,但是卻出現(xiàn)了新的問題,即創(chuàng)建出的對象指向不明確。使用instanceof操作符檢測對象類型時,都是屬于object。
- var star2 = createStar('大黃', 3, 'boy');
- console.log(star2);
- star2.skill();
- console.log(typeof star1, typeof star2); // object object
- console.log(star2 instanceof Object); // true
構(gòu)造函數(shù)創(chuàng)建對象:
構(gòu)造函數(shù)實際上就是一個函數(shù),只是這個函數(shù)是專門用來創(chuàng)建對象的,他的特點:
1.構(gòu)造函數(shù)首字母大寫,為了區(qū)分普通函數(shù);
2.不需要創(chuàng)建對象,屬性和方法直接添加在this上,不需要return返回
3.構(gòu)造函數(shù)調(diào)用時,一定要使用new;
- // 1.聲明構(gòu)造函數(shù)
- function Teacher(name, age, sex){
- // 添加屬性
- this.name = name;
- this.age = age;
- this.sex = sex;
- // 添加方法
- this.skill = function(){
- console.log('布置作業(yè)');
- }
- }
- // 2.實例化對象
- var t1 = new Teacher('小王',20,'girl');
- console.log(t1);
- t1.skill(); // 布置作業(yè)
- var t2 = new Teacher('小李', 25, 'boy');
- console.log(t2);
- t2.skill(); // 布置作業(yè)
我們需要明確 new操作符做了什么?
1.隱式的創(chuàng)建了一個對象;
2.讓this指向這個空對象;
3.讓實例對象的__ proto __指向構(gòu)造函數(shù)的prototype;
4.執(zhí)行代碼,給this添加屬性和方法;
5.隱式的返回創(chuàng)建好的對象;
所以在使用構(gòu)造函數(shù)創(chuàng)建對象時一定要使用new操作符。
使用構(gòu)造函數(shù)創(chuàng)建對象解決了創(chuàng)建出的對象指向不明確,構(gòu)造函數(shù)的主要問題就是每個方法都要在每個實例上重新創(chuàng)建一遍。在前面的例子中,t1 和 person2 都有一個名為 skill()的方法,但那兩個方法不是同一個 Function 的實例。創(chuàng)建兩個完成同樣任務(wù)的 Function 實例的確沒有必要,我們可以通過代碼證實:
- console.log(t1.skill() == t2.skill()); // false-比較的是地址
原型創(chuàng)建對象:
我們創(chuàng)建的每個函數(shù)都有一個 prototype(原型)屬性,這個屬性是一個指針,指向一個對象, 而這個對象的用途是包含可以由特定類型的所有實例共享的屬性和方法。使用原型對象的好處是可以 讓所有對象實例共享它所包含的屬性和方法。換句話說,不必在構(gòu)造函數(shù)中定義對象實例的信息,而是 可以將這些信息直接添加到原型對象中,如下面的例子所示。
- function Stu(){}
- // 2.添加屬性和方法
- Stu.prototype.name = '小明';
- Stu.prototype.age = 18;
- Stu.prototype.skill = function(){
- console.log('沉迷敲代碼');
- }
- // 3.實例化對象
- var s1 = new Stu();
發(fā)現(xiàn)對象里邊是空的,打開可以看到所有的屬性和方法都在__proto__原型屬性上
理解原型對象
無論什么時候,只要創(chuàng)建了一個新函數(shù),就會根據(jù)一組特定的規(guī)則為該函數(shù)創(chuàng)建一個prototype 屬性,這個屬性指向函數(shù)的原型對象。在默認(rèn)情況下,所有原型對象都會自動獲得一個 constructor (構(gòu)造函數(shù))屬性,這個屬性包含一個指向 prototype 屬性所在函數(shù)的指針。
創(chuàng)建了自定義的構(gòu)造函數(shù)之后,其原型對象默認(rèn)只會取得 constructor 屬性;當(dāng)調(diào)用構(gòu)造函數(shù)創(chuàng)建一個新實例后,該實例的內(nèi)部將包含一個指針(內(nèi)部 屬性),指向構(gòu)造函數(shù)的原型對象。__proto__這個連接存在于實例與構(gòu)造函數(shù)的原型對象之間,而不是存在于實例與構(gòu)造函數(shù)之間。
針對上述原型模式創(chuàng)建對象的代碼,我們可以畫出它的圖例關(guān)系:
更多內(nèi)容
>>本文地址:http://m.littlerockbway.com/zhuanye/2021/69434.html
聲明:本站稿件版權(quán)均屬中公教育優(yōu)就業(yè)所有,未經(jīng)許可不得擅自轉(zhuǎn)載。
1 您的年齡
2 您的學(xué)歷
3 您更想做哪個方向的工作?