摘要:把原型修改為另外一個對象就等于切斷了構造函數與最初原型之間的聯系。組合使用構造函數模式動態原型模式通過檢查某個應該存在的方法是否有效,來決定是否需要初始化原型。
理解對象 屬性類型
數據屬性
數據屬性包含一個數據值的位置。在這個位置可以讀取和寫入值。數據屬性有 4 個描述其行為的特性。
[[Configurable]] :表示能否通過 delete 刪除屬性從而重新定義屬性,能否修改屬性的特 性,或者能否把屬性修改為訪問器屬性。像前面例子中那樣直接在對象上定義的屬性,它們的 這個特性默認值為 true 。 [[Enumerable]] :表示能否通過 for-in 循環返回屬性。像前面例子中那樣直接在對象上定 義的屬性,它們的這個特性默認值為 true 。 [[Writable]] :表示能否修改屬性的值。像前面例子中那樣直接在對象上定義的屬性,它們的 這個特性默認值為 true 。 [[Value]] :包含這個屬性的數據值。讀取屬性值的時候,從這個位置讀;寫入屬性值的時候, 把新值保存在這個位置。這個特性的默認值為 undefined 。 var person = {}; Object.defineProperty(person, "name", { writable: false, value: "Nicholas" }); alert(person.name); //"Nicholas" person.name = "Greg"; alert(person.name); //"Nicholas" 一旦把屬性定義為不可配置的,就不能再把它變回可配置了。 var person = {}; Object.defineProperty(person, "name", { configurable: false, value: "Nicholas" }); alert(person.name); //"Nicholas" delete person.name; alert(person.name); //"Nicholas"
訪問器屬性
訪問器屬性不包含數據值;它們包含一對兒 getter 和 setter 函數(不過,這兩個函數都不是必需的)。在讀取訪問器屬性時,會調用 getter 函數,這個函數負責返回有效的值;在寫入訪問器屬性時,會調用setter 函數并傳入新值,這個函數負責決定如何處理數據。(只指定其中get或者set意味著屬性是不能寫,嘗試寫入屬性會被忽略。)
[[Configurable]] :表示能否通過 delete 刪除屬性從而重新定義屬性,能否修改屬性的特性,或者能否把屬性修改為數據屬性。對于直接在對象上定義的屬性,這個特性的默認值為true 。 [[Enumerable]] :表示能否通過 for-in 循環返回屬性。對于直接在對象上定義的屬性,這個特性的默認值為 true 。 [[Get]] :在讀取屬性時調用的函數。默認值為 undefined 。 [[Set]] :在寫入屬性時調用的函數。默認值為 undefined 。 var book = { _year: 2004, edition: 1 }; Object.defineProperty(book, "year", { get: function(){ return this._year; }, set: function(newValue){ if (newValue > 2004) { this._year = newValue; this.edition += newValue - 2004; } } }); book.year = 2005; alert(book.edition); //2定義多個屬性
Object.defineProperties()
var book = {}; Object.defineProperties(book, { _year: { value: 2004 }, edition: { value: 1 }, year: { get: function(){ return this._year; }, set: function(newValue){ if (newValue > 2004) { this._year = newValue; this.edition += newValue - 2004; } } } });讀取屬性的特性
Object.getOwnPropertyDescriptor()
可以取得給定屬性的描述符。
var book = {}; Object.defineProperties(book, { _year: { value: 2004 }, edition: { value: 1 }, year: { get: function(){ return this._year; }, set: function(newValue){ if (newValue > 2004) { this._year = newValue; this.edition += newValue - 2004; } } } }); var descriptor =Object.getOwnPropertyDescriptor(book,"_year"); alert(descriptor.value); //2004 alert(descriptor.configurable); //false alert(typeof descriptor.get); //"undefined" var descriptor =Object.getOwnPropertyDescriptor(book, "year"); alert(descriptor.value); //undefined alert(descriptor.enumerable); //false alert(typeof descriptor.get); //"function"創建對象 工廠模式
用函數來封裝以特定接口創建對象的細節構造函數模式
缺陷:沒有解決對象識別的問題
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");構造函數模式
function Person(name, age, job){ this.name = name; this.age = age; this.job = job; this.sayName = function(){ alert(this.name); }; } var person1 = new Person("Nicholas", 29, "Software Engineer"); var person2 = new Person("Greg", 27, "Doctor");"
將構造函數當作函數
// 當作構造函數使用 var person = new Person("Nicholas", 29, "Software Engineer"); person.sayName(); //"Nicholas" // 作為普通函數調用 Person("Greg", 27, "Doctor"); // 添加到 window window.sayName(); //"Greg" // 在另一個對象的作用域中調用 var o = new Object(); Person.call(o, "Kristen", 25, "Nurse"); o.sayName(); //"Kristen"
構造函數的問題
每個方法都要在每個實例上重新創建一遍。
function Person(name, age, job){ this.name = name; this.age = age; this.job = job; this.sayName = new Function("alert(this.name)"); // 與聲明函數在邏輯上是等價的 } alert(person1.sayName == person2.sayName); //false原型模式
每個函數都有一個 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
對象實例添加一個屬性時,這個屬性就會屏蔽原型對象中保存的同名屬性。
把原型修改為另外一個對象就等于切斷了構造函數與最初原型之間的聯系。
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組合使用構造函數模式
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,Count,Van" alert(person2.friends); //"Shelby,Count" alert(person1.friends === person2.friends); //false alert(person1.sayName === person2.sayName); //true動態原型模式
通過檢查某個應該存在的方法是否有效,來決定是否需要初始化原型。
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();寄生構造函數模式
創建一個函數,該函數的作用僅僅是封裝創建對象的代碼,然后再返回新創建的對象
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"穩妥構造函數模式
沒有公共屬性,而且其方法也不引用 this 的對象。穩妥對象最適合在一些安全的環境中(這些環境中會禁止使用 this 和 new ),或者在防止數據被其他應用程序(如 Mashup程序)改動時使用。
function Person(name, age, job){ //創建要返回的對象 var o = new Object(); //可以在這里定義私有變量和函數 //添加方法 o.sayName = function(){ alert(name); }; //返回對象 return o; }繼承
依靠原型鏈來實現
原型鏈function SuperType(){ this.colors = ["red", "blue", "green"]; } function SubType(){} //繼承了 SuperType SubType.prototype = new SuperType(); var instance1 = new SubType(); instance1.colors.push("black"); alert(instance1.colors); //"red,blue,green,black" var instance2 = new SubType(); alert(instance2.colors); //"red,blue,green,black"借用構造函數
function SuperType(){ this.colors = ["red", "blue", "green"]; } function SubType(){ // 繼承了 SuperType SuperType.call(this); } var instance1 = new SubType(); instance1.colors.push("black"); alert(instance1.colors); //"red,blue,green,black" var instance2 = new SubType(); alert(instance2.colors); //"red,blue,green"組合繼承
function SuperType(name){ this.name = name; this.colors = ["red", "blue", "green"]; } SuperType.prototype.sayName = function(){ alert(this.name); }; function SubType(name, age){ //繼承屬性 SuperType.call(this, name); this.age = age; } //繼承方法 SubType.prototype = new SuperType(); SubType.prototype.constructor = SubType; SubType.prototype.sayAge = function(){ alert(this.age); }; var instance1 = new SubType("Nicholas", 29); instance1.colors.push("black"); alert(instance1.colors); //"red,blue,green,black" instance1.sayName(); //"Nicholas"; instance1.sayAge(); //29 var instance2 = new SubType("Greg", 27); alert(instance2.colors); //"red,blue,green" instance2.sayName(); //"Greg"; instance2.sayAge(); //27原型式繼承
var person = { name: "Nicholas", friends: ["Shelby", "Court", "Van"] }; var anotherPerson = Object.create(person); anotherPerson.name = "Greg"; anotherPerson.friends.push("Rob"); var yetAnotherPerson = Object.create(person); yetAnotherPerson.name = "Linda"; yetAnotherPerson.friends.push("Barbie"); alert(person.friends); //"Shelby,Court,Van,Rob,Barbie"寄生組合式繼承
function SuperType(name){ this.name = name; this.colors = ["red", "blue", "green"]; } SuperType.prototype.sayName = function(){ alert(this.name); }; function SubType(name, age){ //繼承屬性 SuperType.call(this, name); this.age = age; } //繼承方法 SubType.prototype =SuperType.prototype; SubType.prototype.constructor = SubType; SubType.prototype.sayAge = function(){ alert(this.age); }; var instance1 = new SubType("Nicholas", 29); instance1.colors.push("black"); alert(instance1.colors); //"red,blue,green,black" instance1.sayName(); //"Nicholas"; instance1.sayAge(); //29 var instance2 = new SubType("Greg", 27); alert(instance2.colors); //"red,blue,green" instance2.sayName(); //"Greg"; instance2.sayAge(); //27
文章版權歸作者所有,未經允許請勿轉載,若此文章存在違規行為,您可以聯系管理員刪除。
轉載請注明本文地址:http://m.specialneedsforspecialkids.com/yun/89816.html
摘要:其中負載均衡那一節,基本上是參考的權威指南負載均衡的內容。開發指南讀了一半,就是看這本書理解了的事件循環。哈哈創京東一本騙錢的書。 歡迎大家前往騰訊云+社區,獲取更多騰訊海量技術實踐干貨哦~ 本文由騰訊IVWEB團隊 發表于云+社區專欄作者:link 2014年一月以來,自己接觸web前端開發已經兩年多了,記錄一下自己前端學習路上看過的,以及道聽途說的一些書,基本上按照由淺入深來介紹...
摘要:其中負載均衡那一節,基本上是參考的權威指南負載均衡的內容。開發指南讀了一半,就是看這本書理解了的事件循環。哈哈創京東一本騙錢的書。 歡迎大家前往騰訊云+社區,獲取更多騰訊海量技術實踐干貨哦~ 本文由騰訊IVWEB團隊 發表于云+社區專欄作者:link 2014年一月以來,自己接觸web前端開發已經兩年多了,記錄一下自己前端學習路上看過的,以及道聽途說的一些書,基本上按照由淺入深來介紹...
摘要:其中負載均衡那一節,基本上是參考的權威指南負載均衡的內容。開發指南讀了一半,就是看這本書理解了的事件循環。哈哈創京東一本騙錢的書。歡迎大家前往騰訊云+社區,獲取更多騰訊海量技術實踐干貨哦~ 本文由騰訊IVWEB團隊發表于云+社區專欄 作者:link 2014年一月以來,自己接觸web前端開發已經兩年多了,記錄一下自己前端學習路上看過的,以及道聽途說的一些書,基本上按照由淺入深來介紹。...
摘要:三種使用構造函數創建對象的方法和的作用都是在某個特殊對象的作用域中調用函數。這種方式還支持向構造函數傳遞參數。叫法上把函數叫做構造函數,其他無區別適用情境可以在特殊的情況下用來為對象創建構造函數。 一、工廠模式 工廠模式:使用字面量和object構造函數會有很多重復代碼,在此基礎上改進showImg(https://segmentfault.com/img/bVbmKxb?w=456&...
閱讀 2306·2021-11-24 09:39
閱讀 2550·2021-11-22 15:24
閱讀 2990·2021-09-02 09:48
閱讀 3032·2021-07-26 22:01
閱讀 1444·2019-08-30 11:09
閱讀 1684·2019-08-29 18:47
閱讀 615·2019-08-29 15:40
閱讀 2144·2019-08-29 15:22