摘要:一創建對象工廠模式構造函數模式和都是的不同實例。寄生構造函數模式不使用和創建要返回的對象可以在這里添加私有變量和函數添加方法注意,在以這種模式創建的對象中,除了使用方法之外,沒有其他辦法訪問的值
一:創建對象
1 工廠模式
function createPerson(name, age, jod){ var obj = new Object(); obj.name = name; obj.age = age; obj.job = job; obj.sayName = function(){ console.log(this.name); }; return obj; } var person1 = createPerson("NEVAR", 23, "Front-end Engineer"); var person2 = createPerson("Amy", 27, "Doctor");
2 構造函數模式
function Person(name, age, job){ this.name = name; this.age = age; this.job = job; this.sayName = function(){ console.log(this.name); } } var person1 = new Person("NEVAR", 23, "Front-end Engineer"); var person2 = new Person("Amy", 27, "Doctor"); //person1和person2都是Person的不同實例。 alert(person1.constructor == Person); //true alert(person2.constructor == Person); //true //即是Object的實例也是Person的實例 alert(person1 instanceof Object); //true alert(person1 instanceof Person); //true //構造函數產生的是兩個不同實例,同名函數是不相等的 alert(person1.sayName == person2.sayName); //false
3 原型模式
function Person(){ } Person.prototype.name = "NEVAR"; Person.prototype.age = 23; Person.prototype.job = "Front-end Engineer"; Person.prototype.sayName = function(){ console.log(this.name); }; var person1 = new Person(); person1.sayName(); //NEVAR var person2 = new Person(); person2.sayName; //NEVAR console.log(person1.sayName == person2.sayName);// true var person3 = new Person(); person3.name = "PP"; console.log(person3.name); //PP 來自實例 delete person3.name; console.log(person3.name); //NEVAR 來自原型 alert(person1.hasOwnProperty("name")); //false 來自原型 alert(person3.hasOwnProperty("name")); //true 來自實例 alert("name" in person1); //true in操作符的使用 function hasPrototypeProperty (obj, name){ return !obj.hasOwnProperty(name) && (name in obj) } //判斷屬性來自實例 真 然后取反 //并且name屬性存在于obj原型鏈上 說明這個 屬性是屬于prototype的 alert(hasPrototypeProperty(person1,"name")) // true alert(hasPrototypeProperty(person3,"name")) // false alert(Object.keys(Person.prototype)) //"name,age,job,sayName" //Person的可枚舉屬性
不過以上方法太過于麻煩 每次都要寫重復的prototype
function Person(){ } Person.prototype = { name : "NEVAR", age : "23", job : "Front-end Engineer", sayName : function(){ console.log(this.name); } };
constructor 屬性不再指向Person 了 指向Object
var friend = new Person(); alert(friend instanceof Object); //true alert(friend instanceof Person); //true alert(friend.constructor == Person); //false alert(friend.constructor == Object); //true
于是可以這樣
Person.prototype = { constructor : Person, name : "NEVAR", age : "23", job : "Front-end Engineer", sayName : function(){ console.log(this.name); } };
原型的動態性
var friend = new Person(); Person.prototype.sayHi = function(){ alert("Hi"); } friend.sayHi();//Hi //這時沒有問題,如果我們重寫原型對象 那么情況就不一樣了 function Person(){ } var friend = new Person(); Person.prototype = { constructor: Person, name : "NEVAR", age : 23, job : "Front-end Engineer", sayName : function () { alert(this.name); } }; friend.sayName(); //error
重寫原型對象切斷了現有原型與任何之前已經存在的對象實例之間的聯系;它們引用的仍然是最初的原型。
原型模式也不是沒有缺點。首先,它省略了為構造函數傳遞初始化參數這一環節,結果所有實例在默認情況下都將取得相同的屬性值
對于那些包含基本值的屬性倒也說得過去,畢竟(如前面的例子所示),通過在實例上添加一個同名屬性,可以隱藏原型中的對應屬性。然而,對于包含引用類型值的屬性來說,問題就比較突出了
function Person(){ } Person.prototype = { constructor: Person, name : "Nicholas", age : 29, job : "Software Engineer", friends : ["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
4組合使用構造函數模式和原型模式
function Person(name, age, job){ this.name = name; this.age = age; this.job = job; this.friends = ["Shelby","Court"]; } Person.prototype = { constructor : Person, sayName : function(){ console.log(this.name); } } var person1 = new Person("NEVAR", 23, "Front-end Engineer"); var person2 = new Person("Amy", 27, "Doctor"); person1.friends.push("Van"); console.log(person1.friends) //"Shelby,Court,Van" console.log(person2.friends) //"Shelby,Court" console.log(person1.friends === person2.friends); // false console.log(person1.sayName === person2.sayName); //true
5動態原型模式
它把所有信息都封裝在了構造函數中,而通過在構造函數中初始化原型(僅在必要的情況下),又保持了同時使用構造函數和原型的優點。換句話說,可以通過檢查某個應該存在的方法是否有效,來決定是否需要初始化原型。
function Person(name, age, job){ this.name = name; this.age = age; this.job = job; if(typeof this.sayName != function){ Person.prototype.sayName = function(){ console.log(this.name); } } } var person1 = new Person("NEVAR", 23, "Front-end Engineer"); friend.sayName();
6寄生構造函數模式
//不使用this和new function Person(name, age, job){ //創建要返回的對象 var o = new Object(); //可以在這里添加私有變量和函數 //添加方法 o.sayName = function(){ console.log(name); } return o; }
注意,在以這種模式創建的對象中,除了使用sayName()方法之外,沒有其他辦法訪問name 的值
文章版權歸作者所有,未經允許請勿轉載,若此文章存在違規行為,您可以聯系管理員刪除。
轉載請注明本文地址:http://m.specialneedsforspecialkids.com/yun/78983.html
摘要:繼承原型鏈如果構造函數或對象的原型指向構造函數或對象,的原型再指向構造函數或對象,以此類推,最終的構造函數或對象的原型指向的原型。 繼承 原型鏈 如果構造函數或對象A的原型指向構造函數或對象B,B的原型再指向構造函數或對象C,以此類推,最終的構造函數或對象的原型指向Object的原型。由此形成了一條鏈狀結構,被稱之為原型鏈。按照上述的描述,在B中定義的屬性或方法,可以在A中使用并不需要...
摘要:使用最多的繼承模式是組合繼承,這種模式使用原型鏈繼承共享的屬性和方法,而借用構造函數繼承實例屬性。原型式繼承,可以在不必預先定義構造函數的情況下實現繼承,其本質是執行給定對象的淺復制。 1、原型鏈實現繼承 function SuperType() { this.property = true; } SuperType.prototype.getSuperValue = func...
摘要:即另外,注意到構造函數里的屬性,都沒有經過進行初始化,而是直接使用進行綁定。并且在模式下,構造函數沒有使用進行調用,也會導致報錯。調用構造函數千萬不要忘記寫。 1. 基礎 JavaScript不區分類和實例的概念,而是通過原型來實現面向對象編程。Java是從高級的抽象上設計的類和實例,而JavaScript的設計理念,聽起來就好比Heros里的Peter,可以復制別人的能力。JavaS...
摘要:實際上,可以將其理解為某種形式的繼承。如果上下文是,則使用全局對象代替。例如的第個參數是上下文,后續是實際傳入的參數序列中允許更換上下文是為了共享狀態,尤其是在事件回調中。 公開記錄學習JS MVC,不知道能堅持多久= =。以《基于MVC的JavaScript web富應用開發》為主要學習資料。接上一篇類的學習,發現實在是看暈了,有些例子是能看懂在干嘛,但是不知道為什么這樣做,有的甚至...
摘要:實現原型鏈的方式如下讓原型對象稱為另一個構造函數的實例這個實例繼承了的屬性上述代碼繼承是通過來實現,創建的實例,并將該實例賦給。無疑,集兩者之大成,這才是最常用的繼承模式。 原型鏈 JavaScript的繼承主要依靠原型鏈來實現的。我們知道,構造函數,原型,和實例之間的關系:每個構造函數都有一個原型對象,原型對象都包含一個指向構造函數的指針,而實例都包含一個原型對象的指針。 實現原型鏈...
摘要:第二個問題是在創建子類型的實例時,不能向超類型的構造函數中傳遞參數。實際上,應該說是沒有辦法在不影響所有對象實例的情況下,給炒類型的構造函數傳遞參數。借用構造函數偽造對象或經典繼承即在子類型構造函數的內部調用超類型構造函數。 繼承 許多 OO 語言支持兩種繼承方式:接口繼承和實現繼承。接口繼承只繼承方法簽名,而實現繼承則繼承實際的方法。如前所述,由于函數沒有簽名,在 ECMAScri...
閱讀 4643·2021-10-25 09:48
閱讀 3221·2021-09-07 09:59
閱讀 2208·2021-09-06 15:01
閱讀 2706·2021-09-02 15:21
閱讀 2741·2019-08-30 14:14
閱讀 2194·2019-08-29 13:59
閱讀 2527·2019-08-29 11:02
閱讀 2544·2019-08-26 13:33