javascript
《javascript高级程序设计》第六章总结
6.1 理解對象
| 屬性類型 | 屬性特性 | 行為描述 |
| 數據屬性 | Configurable | 表示是否能通過delete刪除屬性從而重新定義屬性。 |
| 數據屬性 | Enumerable | 表示能否通過for-in循環返回屬性。對于直接在對象中定義的屬性,默認為true |
| 數據屬性 | Writable | 表示是否可以修改屬性的值。 |
| 數據屬性 | value | 表示這個屬性的內部值。 |
| 訪問器屬性 | Configurable | 表示是否能通過delete刪除屬性從而重新定義屬性。 |
| 訪問器屬性 | Enumerable | 表示能否通過for-in循環返回屬性。對于直接在對象中定義的屬性,默認為true |
| 訪問器屬性 | Get | 在讀取屬性時調用的函數 |
| 訪問器屬性 | Set | 在寫入屬性時調用的函數 |
常用方法
defineProperty()???????? 修改屬性的特性
defineProperties()????? 定義多個屬性的特性
getOwnPropertyDescriptor()???? 獲取指定屬性的描述符
6.2 創建對象
工廠模式
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");person1.sayName(); //"Nicholas"person2.sayName(); //"Greg"?
構造函數模式
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"); function Person(name, age, job){this.name = name;this.age = age;this.job = job;this.sayName = function(){alert(this.name);};}var person = new Person("Nicholas", 29, "Software Engineer");person.sayName(); //"Nicholas" Person("Greg", 27, "Doctor"); //adds to windowwindow.sayName(); //"Greg"var o = new Object();Person.call(o, "Kristen", 25, "Nurse");o.sayName(); //"Kristen"?
原型模式
原型prototype
1. prototype的概念
prototype是構造函數的一個屬性, 該屬性指向一個對象. 而這個對象將作為該構造函數所創建的所有實例的基引用(base reference), 可以把對象的基引用想像成一個自動創建的隱藏屬性. 當訪問對象的一個屬性時, 首先查找對象本身, 找到則返回; 若不, 則查找基引用指向的對象的屬性(如果還找不到實際上還會沿著原型鏈向上查找,? 直至到根). 只要沒有被覆蓋的話, 對象原型的屬性就能在所有的實例中找到.
原型默認為Object的新實例, 由于仍是對象, 故可以給該對象添加新的屬性:
?
// prototype默認為new Object(); 為了方便, 記為p_obj function Person(name) { this.name = name; } // 為 p_obj 增加 sayName 屬性 Person.prototype.sayName = function(){alert(this.name); } var john = new Person("John"); // john 的 base reference指向p_obj var eric = new Person("Eric"); // eric 的 base reference也是指向p_obj // 注意sayName代碼中的this將指向實例化后的對象(this綁定) john.sayName(); // john對象本身沒有sayName屬性, 于是訪問原型對象p_obj的sayName屬性 eric.sayName(); // 訪問同一個原型對象p_obj的sayName屬性 var tmp = Person.prototype; tmp.boss = "David"; // 于這個運行點, p_obj已經被修改 // 根據上述屬性訪問流程, 新的修改(boss屬性)能反映到所有的實例, 包括已經創建和即將創建的 alert("John's boss is " + john.boss); alert("Eric's boss is " + eric.boss); // hisCar和sayCar屬性將增加到john對象而不是p_obj對象.. john.hisCar = "Audi"; john.sayCar = function(){alert(this.name + " has a car of " + this.hisCar); } john.sayCar(); // ..因此下一句將錯誤, 因為eric對象本身和原型p_obj都沒有sayName屬性 /* eric.sayCar(); */?
2.2 原型鏈
除了能修改prototype指向的對象, 還能修改prototype指向哪一個對象, 即為prototype賦予一個不同的對象. 這可以實現一種簡單的繼承:
?
如果先實例化出一個對象, 再為構造函數prototype賦予一個不同的對象, 將會: 已經創建的對象的基引用不變, 將來創建的對象的基引用為新的原型對象:
?
var f1 = {echo: function() { alert("sound"); } }; function Foo() {}; var foo = new Foo(); // foo的基引用指向Object實例 Foo.prototype = f1; /* 未定義, 因為這是"foo對象自己或者基引用指向的對象有echo屬性嗎?"而不是"foo對象自己或者Foo.prototype指向的對象有echo屬性嗎?" */ alert(foo.echo); var foo2 = new Foo(); // foo2的基引用指f1對象 foo2.echo(); // output: sound所有的構造函數的prototype都不能為空, 就是說Superman.prototype = null 會被解釋引擎無視;? 另一方面, Object構造函數也有prototype屬性(該屬性是只讀的, 可以為原型增加屬性,但不能賦予不同的對象), 故因此可以有多層的原型鏈, 但原型鏈的根必定會是Object.prototype . 這意味著給Object.prototype增加屬性影響到所有對象:
?
Object.prototype.echo = function() {alert("hello"); } // echo屬性將增加到所有對象固有對象和自定義對象 var arr = new Array(); arr.echo(); Array.echo(); function ObjCons() { this.dummy = "d"; } var obj = new ObjCons(); obj.echo(); ObjCons.echo();3. 構造函數和new的實質
構造函數是一個地地道道的函數, 一個函數之所以能成為構造函數, 是因為new運算符:
?
this.msg = "window"; function Test() {alert(this.msg); } Test(); // window var test = new Test(); // undefined. 因為test對象沒有定義msg屬性二者區別在于如何切入對象: Test() 在某個對象(例子中為window)的上下文上執行代碼, 即this指向這個對象; new Test()創建一個新對象, 并以這個新的對象為上下文(this指向新對象)執行代碼, 然后返回這個新對象.?
假如有個函數:
結合以上的所有論述, 可以推測new Test()行為的偽代碼表示為:
????? 創建一個新對象temp;
????? temp.constructor = Test;
????? temp.(base reference) = Test.prototype; // 這一句先于代碼體執行, 意味著構造函數里的this.xxx能訪問原型對象的屬性xxx
????? bind: this = temp; // 將this綁定到temp對象
????? // 開始執行函數代碼
????? var dummy = "have money";
????? this.wish = dummy; // 為temp對象添加wish屬性
????? doSomeThing();
????? ....
????? // 結束執行函數代碼
????? return temp;
這個未必會符合內部的二進制實現, 但卻能很好地解釋了JavaScript的特性
轉載于:https://www.cnblogs.com/shuyuxuan/p/3868707.html
超強干貨來襲 云風專訪:近40年碼齡,通宵達旦的技術人生總結
以上是生活随笔為你收集整理的《javascript高级程序设计》第六章总结的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 《Windows Phone 8 Dev
- 下一篇: servlet学习