JS建立對象的幾種方法

1:Object構造函數建立

var Person =new Object();
Person.name = 'Jason';Person.age = 21;複製代碼

2:使用對象字面量表示法來建立對象

var Person={};   //等同於var Person =new Object();
var Person={
name:"Jason",
age:21
}複製代碼

對象字面量是對象定義的一種簡寫形式,第一種和第二種建立形式的缺點就是:他們用同一個接口建立不少對象和,會產生大量的重複代碼,若是你有500個對象,那麼你就要輸入500次不少相同的代碼。bash

3:使用工廠模式建立對象

function createPerson(name,age,job)
{ var o = new Object(); 
o.name = name; 
o.age = age; 
o.job = job; 
o.sayName = function()
{  alert(this.name);  };
 return o;
 }
var person1 = createPerson('Nike',29,'teacher');
var person2 = createPerson('Arvin',20,'student');複製代碼

在使用工廠模式建立對象的時候,咱們均可以注意到,在createPerson函數中,返回的是一個對象。那麼咱們就沒法判斷返回的對象到底是一個什麼樣的類型。因而就出現了第四種建立對象的模式函數

4 使用構造函數建立對象

function Person(name,age,job)
{ this.name = name; 
this.age = age; 
this.job = job; 
this.sayName = function(){ alert(this.name); }; 
}
var person1 = new Person('Nike',29,'teacher');
var person2 = new Person('Arvin',20,'student');複製代碼

對比ui

工廠模式,咱們能夠發現如下區別:this

1.沒有顯示地建立對象spa

2.直接將屬性和方法賦給了this對象prototype

3.沒有return語句code

4.終於能夠識別的對象的類型。對於檢測對象類型,咱們應該使用instanceof操做符,咱們來進行自主檢測對象

alert(person1 instanceof Object);//turealert
(person1 instanceof Person);//turealert
(person2 instanceof Object);//turealert
(person2 instanceof Object);//ture複製代碼

同時咱們也應該明白,按照慣例,構造函數始終要應該以一個大寫字母開頭,而非構造函數則應該以一個小寫字母開頭。接口

構造函數執行的流程:

1 建立一個新的對象(遇到new 的時候)ip

2 將構造函數的做用域賦給新的對象(所以this就指向這個對象)

3 執行構造函數中的代碼(爲這個對象添加屬性)

4 返回新對象

那麼構造函數確實挺好用的,可是它也有它的缺點:

每一個對象裏面都有公用的函數,意味着每次建立都會穿件這個函數,所以能夠這個函數放到外面,可是會污染全局做用域。

就是每一個方法都要在每一個實例上從新建立一遍,方法指的就是咱們在對象裏面定義的函數。若是方法的數量不少,就會佔用不少沒必要要的內存。因而出現了第五種建立對象的方法

5:原型建立對象模式

function Person(){}
Person.prototype.name = 'Nike';
Person.prototype.age = 20;
Person.prototype.jbo = 'teacher';
Person.prototype.sayName = function(){ alert(this.name);};
var person1 = new Person();person1.sayName();複製代碼

使用原型建立對象的方式,可讓全部對象實例共享它所包含的屬性和方法。

若是是使用原型建立對象模式,請看下面代碼:

function Person(){}
Person.prototype.name = 'Nike';
Person.prototype.age = 20;
Person.prototype.jbo = 'teacher';
Person.prototype.sayName = function()
{ alert(this.name);};
var person1 = new Person();
var person2 = new Person();
person1.name ='Greg';alert(person1.name); 
//'Greg' --來自實例alert(person2.name); //'Nike' --來自原型複製代碼

前面的例子中,每添加一個屬性和方法都要敲一遍Person.prototype。爲減小沒必要要的輸入,從視覺上更好封裝原型的功能。常見的作法:

function Person(){}
Person.prototype={
name:"NIke",
age:11,
sayName:function(){
alert(this.name);
 }
};複製代碼

在上面的代碼中,咱們將Person.prototype設置爲等於一個以對象字面量形式建立新對象,最終結果相同,但有一個例外:constructor屬性不在指向Person了。

原型prototype

咱們所建立的每個函數,解析器都會向函數中添加一個屬性prototype這個屬性對應着一個對象,這個對象就是咱們所謂的原型對象。

若是函數做爲普通函數調用,prototype沒有任何做用

當函數以構造函數調用時,它所建立的對象中都會有一個隱含的屬性指向該構造函數的原型對象,咱們能夠經過__proto__來訪問該屬性

原型對象就至關於一個公共的區域,全部同一個類的實例均可以訪問到這個原型對象,咱們將對象中共有的內容,統一設置到原型對象中,

當咱們訪問對象的一個屬性或方法時,它會先在對象自身中尋找,若是有則直接使用,若是沒有則去原型對象尋找。

函數名.a=123;//只會添加到函數名該類的裏面
函數名.prototype.a=123//會添加到原型對象裏面複製代碼

使用 in 檢查對象中是否含有某個屬性時,若是對象中沒有可是原型中有,也會返回true

console.log("屬性" in 對象名)複製代碼

使用對象的hasOwnProperty()來檢查對象自身(實例)中是否存在該屬性,使用該方法只有當對象自身含有屬性時,纔會返回true

對象名.hasOwnProperty("屬性名")複製代碼

原型對象也是對象,因此它也有原型:

當咱們使用一個對象的屬性或者方法時,會在自身尋找,

自身若是有,則直接使用

若是沒有則去原型對象中尋找,若是原型對象中有,則使用。

若是沒有則去原型的原型對象去尋找,直到object對象的原型,object對象的原型沒有原型,若是在object中依然沒有找到,則返回undefined

當爲對象實例添加一個屬性時,這個屬性就會屏蔽原型對象中保存的同名屬性。

這時候咱們就可使用構造函數模式與原型模式結合的方式,構造函數模式用於定義實例屬性,而原型模式用於定義方法和共享的屬性

6:組合使用構造函數模式和原型模式

function Person(name,age,job)
{ this.name =name; 
this.age = age;
 this.job = job;}
Person.prototype = { 
constructor:Person,
 sayName: function()
{ alert(this.name); };
}
var person1 = new Person('Nike',20,'teacher');複製代碼

建立自定義類型的最多見方式,就是組合使用構造函數模式和原型模式

實例屬性都是在構造函數中定義的,而全部實例共享的屬性constructor和方法sayName()則是在原型中定義。這種模式是ECMAScript中使用最普遍,承認度最高的一種建立自定義類型的方法,能夠說這是用來定義引用類型的一種默認模式。

相關文章
相關標籤/搜索