相信但凡作為乙個前端工程師,都被面試到過這個面試題目,hr考察的就是對oop思想的理解。
作為乙個從後端轉過來的慫逼,oop一直是心中的永遠的痛啊。
這幾天一直在通讀js高階程式設計,重複理解js建立物件的幾種方式,以及原型鏈和constructor等關鍵點。
談到建立物件,我們要從最原始的方式說起,也是最簡單的方式,就是直接建立乙個object例項,然後新增屬性和方法。
1、簡單方式
var o=new object();簡單方式不僅有這種object建構函式形式,還有物件字面量o.name='lucy';
o.age="20";
o.job = "doctor";
o.showname=function()
var o =這種寫法看上去沒啥問題,但是在建立多個p,就需要重複的**,給p新增屬性和方法,所以這種寫法終究還是不算通用。所以後面就乾脆把建立物件的過程抽象出來了,就有了工廠模式。}
2、工廠模式
function createperson(name,age,job)現在可以通過呼叫這個函式,無數次建立物件了,但是卻並不能確切地知道物件的型別。因為ecmascript的建構函式可用來建立特定型別的物件,所以建構函式模式就出現了。return o;
}var p = createperson('wly','23','前端工程師');
p.showname();
alert(p.constructor == createperson); //false
alert(p instanceof createperson); //false
3、建構函式模式
function person(name,age,job)建構函式模式最大的問題:同一建構函式的不同例項的相同方法是不一樣的。}var p1 = new person('lily','23','前端工程師');
var p2 = new person('lucy','24','前端工程師');
alert(p1.constructor == person); //true
alert(p2.constructor == person); //true
alert(p1 instanceof person); //true
alert(p2 instanceof person); //true
alert(p1 instanceof object); //true
alert(p2 instanceof object); //true
alert(p1.sayinfo == p2.sayinfo); //false
p1,p2都有個constructor屬性,該屬性指向的就是person。而物件的constructor屬性本來就是用來標識物件型別的。不過檢測物件型別,還是用instanceof比較好些。至於其中的_prototo__,constructor以後另做詳解。
那建構函式又有什麼缺點呢,p1和p2都有sayinfo方法,但是是不同例項的同名函式,所以是不相等的( alert(p1.sayinfo == p2.sayinfo) 是false),也就是說建構函式的每個方法事實上是在每個例項中重新重建了一遍,所以難免有點浪費記憶體。
後面就乾脆把sayinfo拎出來,成為下面這個樣子。
function person(name,age,job)這兒其實就是p1和p2共享了在全域性作用域的sayinfo函式。但是如果我們定義這個全域性函式只是為了給某個物件呼叫,是不是有點奇怪。假設這個person物件有多個方法,那豈不是要定義多個全域性函式。function sayinfo()
var p1 = new person('lily','23','前端工程師');
var p2 = new person('lucy','24','前端工程師');
alert(p1.sayinfo == p2.sayinfo); //true
4、原型模式
function person(){}我們的初衷是像這樣在所有例項共享屬性和方法,我們無話可說,但是一般很少會這樣用,因為例項應該擁有自己的全部的屬性,這也是為啥很少有人用原型模式的原因。person.prototype.name = "lily";
person.prototype.age = 12;
person.prototype.job = "doctor";
person.prototype.friends = ["tom","lucy"];
person.prototype.sayname = function();
var a = new person();
var b = new person();
a.friends.push("jack");
console.log(a.friends); //"tom","lucy","jack"
console.log(b.friends); //"tom","lucy","jack"
console.log(a.friends == b.friends) //true
5、構造模式和原型模式組合使用
建立物件最常見的方式,就是組合使用建構函式模式和原型模式。建構函式用來定義例項屬性,原型模式用來定義方法和共享屬性。每個例項都會有自己的乙份例項屬性的副本,但同時又可以共享對方付的引用。
function person(name,age,job)獨立的friends屬性,共享的sayname,這是定義引用型別的一種預設模式。person.prototype =
}var a = new person("lily",12,"doctor");
var b = new person("lucy",23,"teacher");
a.friends.push("jack");
console.log(a.friends); //"tom","lucy","jack"
console.log(b.friends); //"tom","lucy"
console.log(a.friends == b.friends) //false
console.log(a.sayname == b.sayname) //true
還有兩種方式:寄生建構函式模式 、穩妥建構函式模式,我認為有需要可以去了解下,感覺這兩種模式只是在特定情況才會去使用,一般是很少會用到的,著重點應該前面5個的演變歷程。
js 建立物件的幾種方式
一 原始方式 解釋 原始方法建立物件,通過new關鍵字生成乙個物件,然後根據js是動態語言的特性新增屬性和方法,構造乙個物件。其中this是表示呼叫該方法的物件。缺點 多次建立物件,則需要重複 多次,不利於 的復用。二 工廠模式 var getage function var getname fun...
js 建立物件的幾種方式
第一種 工廠模式 例1 function createobj name,age return o var per1 createobj 張三 20 per1.sayinfo 缺點 無法知道物件的型別 第二種 建構函式模式 例2 function person name,age var per2 ne...
js建立物件的幾種方式
雖然object建構函式或物件字面量都可以建立單個物件,但這些方式有個明顯的缺點,那就是使用同乙個介面創造很多物件,會產生大量的重複 所以產生了下面幾種模式。1 工廠模式 function createperson name,age,job o.name name o.age age o.job j...