摘要:組合使用構造函數(shù)模式和原型。構造函數(shù)用于定義實例屬性,原型鏈用于定定方法和共享的屬性。為了避免矛盾和意外的結果總是指定基數(shù)參數(shù)。
原型對象與原型鏈本文主要記錄平時開發(fā)遇到的知識點和小技巧
JavaScritp 引擎在訪問對象的屬性時,如果在對象本身中沒有找到,則會去原型鏈中查找,如果找到,直接返回值,如果整個鏈都遍歷且沒有找到屬性,則返回 undefined.原型鏈一般實現(xiàn)為一個鏈表,這樣就可以按照一定的順序來查找。
原型鏈是一個由對象組成的有限對象鏈,實現(xiàn)繼承和共享屬性。
var base = { name: "base", getInfo: function() { return this.name; }, getMoreInfo: function() { return this.id + ":" + this.name; } } var ext1 = { id: 0, name: "ext1" __proto__: base } var ext2 = { id: 9, __proto__: base } var ext3 = { id: 10, __proto__: base } console.log(ext1.id); // 0 console.log(ext1.getInfo()); // ext1 console.log(ext2.id); // 9 console.log(ext2.getInfo()); // base console.log(ext3.id); // 10 console.log(ext3.getMoreInfo()); // 10:base //getMoreInfo與getInfo 函數(shù)中的 this 表示原始對象,而并非原型對象.
// 構造函數(shù),所有創(chuàng)建的對象都會有y屬性 function Foo(y) { this.y = y; } // 創(chuàng)建共享屬性x Foo.prototype.x = 10; // 創(chuàng)建共享方法calculate Foo.prototype.calculate = function(z) { return this.x + this.y + z; } // 使用foo模式創(chuàng)建b、c var b = new Foo(10); // 此時b.y為10 var c = new Foo(20); // 此時c.y為20 //b、c分別調用共享方法 console.log(b.calculate(10)); // 30 console.log(c.calculate(10)); // 40 // 注意一點,this這個值在一個繼承機制中,仍然是指向它原本屬于的對象,而不是從原型鏈上找到它時, 它所屬于的對象。
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("Grey"); console.log(person1.friends); // ["Shelby", "Court", "Grey"] console.log(person2.friends); // ["Shelby", "Court", "Grey"] console.log(person1.friends === person2.friends); // true 原型對象的問題,公共屬性可能會被篡改。這也是為什么很少看到有人使用原型鏈的原因。
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(); var person2 = new Person(); person1.friends.push("Grey"); console.log(person1.friends); // ["Shelby", "Court", "Grey"] console.log(person2.friends); // ["Shelby", "Court"] //組合使用構造函數(shù)模式和原型。 //構造函數(shù)用于定義實例屬性,原型鏈用于定定方法和共享的屬性。數(shù)值轉換
使用 parseInt()你可以從字符串中獲取數(shù)值,該方法接受另一個基數(shù)參數(shù),可以省略,但不推薦。
當字符串以0開頭的時候,就有可能會出問題。
例如,部分時間進入表單域,在ECMAScript 3中,開頭為”0′′ 的字符串被當做8進制處理了,但這已在ECMAScript 5中改變了。為了避免矛盾和意外的結果,總是指定基數(shù)參數(shù)。
var month = "06", year = "09"; month = parseInt(month, 10); year = parseInt(year, 10);
此例中,如果你忽略了基數(shù)參數(shù),如parseInt(year), 返回的值將是 0。
因為“09”被當做8進制(好比執(zhí) 行 parseInt( year, 8 )), 而09在8進制中不是個有效數(shù)字。
替換方法是將字符串轉換成數(shù)字,包括:
+"08" // 8 Number("08") // 8 顯式轉換 "08" - 0 // 8 隱式轉換Module模式
1.模塊化,可重用
2.封裝了變量和function, 與全局的命名空間不接觸, 松耦合
3.只暴露可用public的方法,其它私有方法全部隱藏.
var Calculator = function (eq) { //這里可以聲明私有成員 var eqCtl = document.getElementById(eq); return { // 暴露公開的成員 add: function (x, y) { var val = x + y; eqCtl.innerHTML = val; } }; }; // 我們可以通過如下的方式來調用: var calculator = new Calculator("eq"); calculator.add(2, 2);
當然,我們也可以使用匿名函數(shù)來完成它,并且引用全局對象。
(function ($, YAHOO) { // 這里,我們的代碼就可以使用全局的jQuery對象了,YAHOO也是一樣 } (jQuery, YAHOO));
Module模式的一個限制就是所有的代碼都要寫在一個文件,但是在一些大型項目里,將一個功能分離成多 個文件是非常重要的,因為可以多人合作易于開發(fā)。
var blogModule = (function (my) { my.AddPhoto = function () { //添加內部代碼 }; return my; } (blogModule));
上面的代碼盡管可以執(zhí)行,但是必須先聲明blogModule,然后再執(zhí)行上面的擴展代碼,也就是說步驟不 能亂,怎么解決這個問題呢?我們可以在傳入?yún)?shù)的時候進行一些改變:
var blogModule = (function (my) { // 添加一些功能 return my; } (blogModule || {}));
通過這樣的代碼,每個多帶帶分離的文件都保證這個結構,那么我們就可以實現(xiàn)任意順序的加載。
自執(zhí)行函數(shù)在JavaScript里,任何function在執(zhí)行的時候都會創(chuàng)建一個執(zhí)行上下文。
因為為function聲明的變量和 function有可能只在該function內部,這個上下文,在調用function的時候,提供了一種簡單的方式來創(chuàng) 建自由變量 或 私有的子function。
當你聲明一個函數(shù)的時候,通過在后面加個括弧就可以實現(xiàn)自執(zhí)行:
// 因為想下面第一個聲明的function可以在后面加一個括弧()就可以自己執(zhí)行了,比如foo(), // 因為foo僅僅是function() { /* code */ }這個表達式的一個引用 var foo = function(){ /* code */ } // ...是不是意味著后面加個括弧都可以自動執(zhí)行? function(){ /* code */ }(); // SyntaxError: Unexpected token // 但是如果你在括弧()里傳入一個表達式,將不會有異常拋出 // 但是foo函數(shù)依然不會執(zhí)行 function foo(){ /* code */ }( 1 ); // 因為它完全等價于下面這個代碼,一個function聲明后面,又聲明了一個毫無關系的表達式: function foo(){ /* code */ }(1);
那么想要運行自執(zhí)行函數(shù)有很多種方法:
(function () { /* code */ } ()); // 推薦使用這個 (function () { /* code */ })(); // 但是這個也是可以用的 // 由于括弧()和 JS的 &&,異或,逗號等操作符是在函數(shù)表達式和函數(shù)聲明上消除歧義的 // 所以一旦解析器知道其中一個是表達式了,其它的也都默認為表達式. // 比如: var i = function () { return 10; }(); true && function () { /* code */ }(); 0, function () { /* code */ }();
如果你不在意返回值,或者不怕難以閱讀, 甚至可以在function前面加一元操作符號:
!function () { /* code */ } (); ~function () { /* code */ } (); -function () { /* code */ } (); +function () { /* code */ } (); // 使用new關鍵字,也可以用 new function () { /* code */ } new function () { /* code */ } () // 如果需要傳遞參數(shù),只需要加上括弧()自執(zhí)行匿名函數(shù)的應用
自執(zhí)行匿名函數(shù)應用最多的場景可能就是閉包了。
閉包可以創(chuàng)建額外的scope,這可以被用來組合相關的或有依賴性的代碼。用這種方式可以最大限度地減少代碼干擾的危害。但是濫用閉包也會產生一系列的副作用,比如內存泄露。在實際開發(fā)中,我們應該合理的應用閉包。
看一個例子:
for (var i=1; i<=5; i++) { setTimeout( function() { console.log(i); }, i * 1000 ); }
這是一個經典的閉包題,我們想要的結果其實是輸出1-5,可是卻發(fā)現(xiàn)輸出的是5個6.
那是因為javascript是單線程,執(zhí)行代碼是以輪詢的形式進行執(zhí)行。
換句話說,setTimeout函數(shù)的代碼,被放到了第二梯隊,第一梯隊是執(zhí)行for循環(huán),循環(huán)完畢之后,才會執(zhí)行setTimeout里的function。
所以當for循環(huán)執(zhí)行完畢之后,i的值已經是6了。
那么我們可以用匿名函數(shù)閉包來解決這個問題:
for (var i=1; i<=5; i++) { (function(i) { setTimeout( function() { console.log(i); }, i*1000 ); })(i) }
在setTimeout的外層包裹一個自執(zhí)行匿名函數(shù),并傳入i,根據(jù)閉包的特性,此時每次循環(huán)時的i值都保存在對應的閉包中,而不在受到外層i的影響,setTimeout里的function中輸出的i值,訪問的是其對應閉包中的值。
這個題目是考閉包的,其實我們使用值的傳遞,一樣可以得到同樣的結果,只不過那樣的話,可能就不是考官想要的答案了。
for (var i=1; i<=5; i++) { setTimeout( function(i) { console.log(i); }, i*1000 ,i); }
我們知道,函數(shù)的參數(shù)如果是普通類型值,是按值傳遞的。因此可以取巧,直接傳值,來得到想要的答案。
文章版權歸作者所有,未經允許請勿轉載,若此文章存在違規(guī)行為,您可以聯(lián)系管理員刪除。
轉載請注明本文地址:http://systransis.cn/yun/84748.html
摘要:特意對前端學習資源做一個匯總,方便自己學習查閱參考,和好友們共同進步。 特意對前端學習資源做一個匯總,方便自己學習查閱參考,和好友們共同進步。 本以為自己收藏的站點多,可以很快搞定,沒想到一入?yún)R總深似海。還有很多不足&遺漏的地方,歡迎補充。有錯誤的地方,還請斧正... 托管: welcome to git,歡迎交流,感謝star 有好友反應和斧正,會及時更新,平時業(yè)務工作時也會不定期更...
Web前端開發(fā)是創(chuàng)建Web頁面或app等前端界面呈現(xiàn)給用戶的過程。第一階段:前端基礎(HTML / CSS / JavaScript / jQuery)初識HTML+CSS【學習筆記】HTML基礎完結篇html基礎知識——標簽詳解html基礎知識——與用戶交互!(表單標簽)html基礎知識——css樣式①史上最全Html和CSS布局技巧面試題匯總 HTML+CSS篇CSS 最核心的幾個概念純HTM...
閱讀 2082·2023-04-25 21:11
閱讀 2971·2021-09-30 09:47
閱讀 2284·2021-09-24 09:48
閱讀 4445·2021-08-23 09:43
閱讀 903·2019-08-30 15:54
閱讀 571·2019-08-28 18:01
閱讀 1409·2019-08-27 10:55
閱讀 595·2019-08-27 10:55