本文為大家分享了javascript創建物件的9種方式,供大家參考,具體內容如下
【1】使用Object建構子
[缺點]使用同一個介面創建許多對象,會產生大量重複程式碼
var person = new Object(); person.name = "Nicholas"; person.age = 29; person.job = "Software Engineer"; person.sayName = function(){ alert(this.name); }
【2】使用物件字面量
[缺點]使用同一個介面創建許多對象,會產生大量重複程式碼
var person = { name: "Nicholas", age : 29, job: "Software Engineer", sayName: function(){ alert(this.name); } };
【3】工廠模式:抽象了創建具體物件的過程,考慮到ECMAScript中無法創建類,開發人員就發明了一種函數,用函數來封裝以特定接口創建對象的細節
[缺點]解決了創建多個相似物件的問題,但沒有解決物件辨識的問題
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('Nicholas',29,'software Engineer'); var person2 = createPerson('greg',27,'doctor');
【4】建構子模式:沒有明確地建立對象,直接將屬性和方法賦給了this對象,沒有return語句
[缺點]每個方法都要在每個實例上重新建立一遍
function Person(name,age,job){ this.name = name; this.age = age; this.jog = job; this.sayName = function(){ alert(this.name); }; //与声明函数在逻辑上是等价的 //this.sayName = new Function('alert(this.name)'); } var person1 = new Person("Nicholas",29,"software Engineer"); var person2 = new Person("Greg",27,"doctor");
【4.1】建構子拓展模式:把函數定義轉移到建構子外部
[缺點1]在全域作用域中定義的函數實際上只能被某個物件調用,這讓全域作用域有點名不副實
[缺點2]若物件需要定義很多方法,就要定義很多全域函數,這個自訂引用型別就沒有封裝性可言
function Person(name,age,job){ this.name = name; this.age = age; this.job = job; this.sayName = sayName; } function sayName(){ alert(this.name); } var person = new Person('小火柴','20','student') person.sayName(); console.log(Person);
【5】原型模式:我們創建的每個函數都有一個prototype(原型)屬性,這個屬性是一個指針,指向一個對象,而這個對象的用途是包含可以由特定類型的所有實例共享的屬性和方法。如果按照字面意思來理解,prototype就是透過呼叫建構函式而創建的物件實例的原型物件
function Person(){ Person.prototype.name = "Nicholas"; Person.prototype.age = 29; Person.prototype.job = "software Engineer"; Person.prototype.sayName = function(){ alert(this.name); } } var person1 = new Person(); person1.sayName();//"Nicholas" var person2 = new Person(); person2.sayName();//"Nicholas" alert(person1.sayName == person2.sayName);//true
【5.1】更簡單的原型模式:為了減少不必要的輸入,也為了從視覺上更好地封裝原型的功能,用一個包含所有屬性和方法的物件字面量來重寫整個原型物件。
[缺點]以這種方式重設constructor屬性會導致它的[[Enumerable]]特性被設定為true,預設情況下原生的constructor屬性是不可枚舉的
function Person(){}; Person.prototype = { constructor : Person, name: "Nicholas", age: 29, job: "software Engineer", sayName : function(){ alert(this.name); } };
【5.2】解決enumerable問題的原型模式
function Person(){}; Person.prototype = { name: "Nicholas", age: 29, job: "software Engineer", sayName : function(){ alert(this.name); } }; Object.defineProperty(Person.prototype,"constructor",{ enumerable : false, value : Person });
[原型模式缺點1]重寫原型物件切斷了現有原型與已存在物件實例之間的聯繫,它們所引用的仍是最初的原型。
function Person(){} var friend = new Person(); Person.prototype = { constructor: Person, name: "Nicholas", age: 29, job: "Software Engineer", sayName: function(){ alert(this.name); } }; friend.sayName();//error
[原型模式缺點2]引用型態屬性的共享性問題突出
function Person(){} Person.prototype = { constructor: Person, name: "Nicholas", age: 29, job: "Software Engineer", friend : ["shelby","Court"], sayName: function(){ alert(this.name); } }; var person1 = new Person(); var person2 = new Person(); person1.friends.push("Van"); alert(person1.friends);//["shelby","Court","Van"]; alert(person2.friends);//["shelby","Court","Van"]; alert(person1.friends === person2.friends);//true
【6】組合模式:組合使用建構函式模式和原型模式是建立自訂類型最常見的方式。建構函數模式用於定義實例屬性,而原型模式用於定義方法和共享的屬性。這種混成模式也支援向建構函式傳遞參數,是用來定義參考類型的一種預設模式
function Person(name,age,job){ this.name = name; this.age = age; this.job = job; this.friends = ["shelby","Court"]; } Person.prototype = { constructor: Person, sayName : function(){ alert(this.name); } } var person1 = new Person("Nicholas",29,"Software Engineer"); var person2 = new Person("Greg",27,"Doctor"); person1.friends.push("Van"); alert(person1.friends);// ["shelby","Court","Van"]; alert(person1.friends);// ["shelby","Court"]; alert(person1.friends === person2.friends);//false alert(person1.sayName === person2.sayName);//true
【7】動態原型模式:把所有資訊都封裝在建構函式中,透過在建構函式中初始化原型(僅在必要情況下),又保持了同時使用建構函式和原型的優點。換句話說,可以透過檢查某個存在的方法是否有效,來決定是否要初始化原型。
[注意]使用動態原型模式時,不能使用物件字面量來重寫原型。如果在已經創建了實例的情況下重寫原型,那麼就會切斷現有實例與新實例之間的聯繫
function Person(name,age,job){ //属性 this.name = name; this.age = age; this.job = job; //方法 if(typeof this.sayName != "function"){ Person.prototype.sayName = function(){ alert(this.name); }; } } var friend = new Person("Nicholas",29,"Software Engineer"); friend.sayName();
【8】寄生建構函數模式:建立一個函數,該函數的作用只是封裝建立物件的程式碼,然後再傳回新建立的物件
function Person(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 friend = new Person("Nicholas",29,"Software Engineer"); friend.sayName();//"Nicholas"
【寄生建構函式模式應用】建立一個具有額外方法的特殊陣列。由於不能直接修改Array建構函數,因此可以使用這個模式
function SpecialArray(){ //创建数组 var values = new Array(); //添加值 values.push.apply(values,arguments); //添加方法 values.toPipedString = function(){ return this.join('|'); }; //返回数组 return values; } var colors = new SpecialArray("red","blue","green"); alert(colors.toPipedString());//"red|blue|green"
【9】穩健建構子模式:所謂穩健物件指沒有公共屬性,其方法也不引用this的物件。穩妥物件最適合在一些安全環境中(這些環境會禁止使用this和new)或在防止資料被其他應用程式改動時使用。
function Person(name,age,job){ //创建要返回的对象 var o = new Object(); //可以在这里定义私有变量和函数 //添加方法 o.sayName = function(){ alert(name); }; //返回对象 return o; } //在稳妥模式创建的对象中,除了使用sayName()方法之外,没有其他方法访问name的值 var friend = Person("Nicholas",29,"Software Engineer"); friend.sayName();//"Nicholas"
以上就是javascript創建物件的九種方式,希望對大家的學習有所幫助。