JavaScript學習——面向物件(一)——建立物件(工廠模式和構造器模式)
面向物件
JavaScript中的物件定義是:無序屬性的集合,其屬性值可以包含基本值,物件以及函式。
建立物件的方式:
1,使用工廠模式建立物件:
使用工廠模式建立物件就是建立一個Object物件,再給物件新增屬性和方法,工廠模式雖然解決了建立多個相同的物件建立的問題,但是不能識別物件的型別。
<!DOCTYPE html> <html> <head> <meta charset="UTF-8"> <title>建立物件的幾種方式-工廠模式</title> <script> function createPerson(name,age,job){ var obj=new Object(); obj.name=name; obj.age=age; obj.job=job; obj.sayName=function(){ alert("我的名字是"+this.name); }return obj; } var person1=createPerson("豬八戒",28,"醫生"); var person2=createPerson("孫悟空",18,"教師"); </script> </head> <body> </body> </html>
2,使用構造器模式建立物件
<!DOCTYPE html> <html> <head> <meta charset="UTF-8"> <title>建立物件的幾種方式-工廠模式</title> <script> function createPerson(name,age,job){ var obj=new Object(); obj.name=name; obj.age=age; obj.job=job; obj.sayName=function(){ alert("我的名字是"+this.name); } return obj; } var person1=createPerson("豬八戒",28,"醫生"); var person2=createPerson("孫悟空",18,"教師"); </script> </head> <body> </body> </html>
從程式碼可以看出,構造模式和工廠建立的物件的區別是:
沒有顯示的建立物件
直接將屬性和方法賦值給了this物件
沒有return語句
建立建構函式的注意事項:建構函式的名稱第一個字母應該大寫,普通 的函式的名稱都是小寫,構造本身也是函式,也能夠被呼叫。
使用建構函式建立一個物件必須要使用new操作符,使用new操作符呼叫建構函式經歷的4個步驟:
建立一個新物件
將建構函式的作用域賦值給新物件(this指向了這個物件)
執行建構函式中的程式碼(為物件新增屬性和方法)
返回一個新的物件
將建構函式當作普通函式來使用時候:
在全域性作用域中呼叫一個函式的時候,this指向Global物件(也就是window物件)在呼叫完後可以使用window物件來呼叫方法
//將建構函式當作普通函式來使用的時候
Person("沙和尚",38,"服務員"); //新增到window中去了
window.sayName()
將建構函式放在另一個物件中使用的時候:
使用call()方法在某個特定的物件的作用域中呼叫Person方法,是在o物件中呼叫的,所以o物件就擁有了所有的屬性和方法
var o=new Object();
Person.call(o,"Kirs",25,"Nurse");
o.sayName(); //Kirs的職位是:Nurse
建構函式建立物件的問題:在每使用一次建構函式建立一個物件,都會為該物件建立對應的 屬性和方法,每個屬性和方法都是物件自己的,同種型別的不同物件的方法都不相同,但是他們所作的工作都是相同的。如下:物件person1的方法和person2的方法都是輸出這個物件的name屬性值,但是person2和person1的方法是不相等的,像這樣每建立一個物件就建立一個函式沒有必要。
<!DOCTYPE html> <html> <head> <title> 物件的方法 </title> <script> function Person(name,age){ this.name=name; this.age=age; this.sayName=function(){ alert("我是"+this.name); } }; var person1=new Person("豬八戒",12); var person2=new Person("孫悟空",20); person1.sayName(); person2.sayName(); alert(person1.sayName==person2.sayName); //輸出false </script> </head> </html>
我們可以把函式放在外面,而在裡面將sayName屬性的值指向外面的函式,如下:
<!DOCTYPE html> <html> <head> <title> 物件的方法定義 </title> <script> function sayName(){ alert(this.name); } function Person(name,age){ this.name=name; this.age=age; //this.sayName=sayName();這個樣是錯誤的,()是呼叫方法 this.sayName=sayName; } var person1=new Person("豬八戒",29); var person2=new Person("孫悟空",20); person1.sayName(); person2.sayName(); alert(person2.sayName==person1.sayName); //true </script> </head> </html>
這樣,person1和person2就共享了全域性作用域中的同一個函式,不用為每一個物件都建立一個方法,但是這樣又會出現了新的問題:如果一個建構函式擁有多個方法,那麼就需要為在全域性作用域中建立多個方法,這樣一來我們自定義的引用型別就沒有封裝性可言了。我們可以使用原型來解決這個問題。
o