轉載自個人我的博客javascript
歡迎你們批評指正php
這裏最須要學習的老師的代碼中,每一部分功能都由函數控制,沒有建立一個所有變量。且最後有一個函數來控制執行代碼。這個更多的是思想上的學習吧!html
在chrome上相加時,直接兩個數拼接到一塊兒了,而不是數值相加。由於輸入的值,在獲取時,默認是字符串類型的。java
在IE8下提示對象不支持「addEventListener」屬性或方法
。緣由是IE8不支持標準的DOM事件綁定函數,它使用attachEvent
git
JavaScript,一種直譯式腳本語言,是一種動態類型、基於原型的語言,內置支持類。它的解釋器被稱爲JavaScript引擎,爲瀏覽器的一部分,普遍用於客戶端的腳本語言,最先是在HTML網頁上使用,用來給HTML網頁增長動態功能。然而如今JavaScript也可被用於網絡服務器,如Node.js。github
上面是維基百科上的解釋。不過讓JavaScript流行起來的緣由應該是JavaScript 是目前全部主流瀏覽器上惟一支持的腳本語言。下面是MDN對其核心功能的解釋web
核心的 JavaScript 中包含有一組核心的對象,包括 Array,Date 和 Math,以及一組核心的語言要素,包括操做符,控制結構和語句。出於多種目的,能夠經過爲其增補附加的對象,對核心 JavaScript 加以擴展;例如:正則表達式
客戶端: JavaScript 提供了用於控制瀏覽器(Navigator 或者其它瀏覽器)以及其中的文檔對象模型(DOM)的對象,從而擴展了核心 JavaScript。例如,客戶端擴展容許應用程序在 HTML 的表單中加入元素,以便響應用戶事件,好比鼠標點擊,表單輸入和頁面導航。chrome
服務器端: JavaScript 提供了服務於在服務器上運行 JavaScript 的對象,從而擴展了核心 JavaScript。例如,服務器端擴展能夠容許應用程序訪問關係型數據庫,在應用程序的不一樣調用間提供信息的連續性,甚至於處理服務器之上的文件。數據庫
能夠有三種方法加載在HTML頁面中引入JavaScript代碼:
內聯式: 在HTML標籤的style屬性中定義樣式,在onclick這樣的屬性中定義Javascript代碼;
嵌入式: 在頁面中使用<script>
標籤訂義Javascript代碼;
引用外部文件: 在<script>
標籤中定義src
屬性引入Javascript文件.
注意:在<head>
或者<body>
中均可以建立<script>
標籤來建立或者引入JavaScript代碼。
搜索一下,爲何咱們讓你把<script>
放在</body>
前。
瀏覽器在解釋HTML頁面時,是按照前後順序的,所在放在前面的JS
代碼就會先被執行。正是由於這種特性,因此放在<head>
中的<script>
代碼會阻塞頁面的渲染。
其實有些JS代碼能夠放在<head></head >
之間,好比IE9如下瀏覽器兼容HTML5標籤的js代碼,這是一個底層的兼容腳本,不涉及任何頁面邏輯。那麼它應該放在<head></head >
間。
新版瀏覽器<script>
標籤可使用defer
屬性來延遲加載。
最簡單的不就是把能放在body
中的代碼放進去嗎?擴展閱讀中有詳細介紹。
建立一個JavaScript文件,好比util.js
;
實踐判斷各類數據類型的方法,並在util.js
中實現如下方法:
這裏比較簡單,能夠參考個人另外一篇博客JavaScript類型識別.
// 判斷arr是否爲一個數組,返回一個bool值 function isArray(arr) { return typeof (arr) === "object" && Object.prototype.toString.call(arr) === "[object Array]"; } // 判斷fn是否爲一個函數,返回一個bool值 function isFunction(fn) { return typeof (fn) === "function"; }
在ECMAScript5中,判斷數組類型能夠直接使用Array.isArray()
。
Array.isArray([]); //true Array.isArray(function(){}); //false
瞭解值類型和引用類型的區別,瞭解各類對象的讀取、遍歷方式,並在util.js
中實現如下方法:
// 使用遞歸來實現一個深度克隆,能夠複製一個目標對象,返回一個完整拷貝 // 被複制的對象類型會被限制爲數字、字符串、布爾、日期、數組、Object對象。不會包含函數、正則對象等 function cloneObject(src) { // your implement } // 測試用例: var srcObj = { a: 1, b: { b1: ["hello", "hi"], b2: "JavaScript" } }; var abObj = srcObj; var tarObj = cloneObject(srcObj); srcObj.a = 2; srcObj.b.b1[0] = "Hello"; console.log(abObj.a); console.log(abObj.b.b1[0]); console.log(tarObj.a); // 1 console.log(tarObj.b.b1[0]); // "hello"
思路以下
題目考的主要是有些對象的使用=
直接賦值,並非真正的複製,而是將一個新的變量指向了當前對象,共享同一個地址。在修改原對象時,新對象也會跟着改變。
通過測試,數字、字符串、布爾、日期、能夠直接賦值,修改不會產生影響。因此就思考了在使用typeof
值爲對象或者是原始類型時的狀況。且對象類型爲Date
對象時,也使用直接賦值的方式。
再考慮對象類型爲Array
或者Object
的狀況。對於結果聲明其類型。
接着往下走,在遍歷對象時,只考慮其自身的屬性,而不考慮繼承來屬性。若其自身值仍是對象,那麼 就遞歸調用,進一步解析、賦值,不然直接賦值。
實現:
function cloneObject(src) { var result ;//返回的複製後的結果。 if (typeof(src)==="object"){ //對象爲日期對象時也直接賦值。 if(Object.prototype.toString.call(src)==="[object Date]"){ result = src; }else{ //判斷對象的類型是Array仍是Object,結果類型更改。 result = (Object.prototype.toString.call(src)==="[object Array]")? [] : {}; for (var i in src){ if (src.hasOwnProperty(i)) { //排除繼承屬性 if (typeof src[i] === "object") { result[i] = cloneObject(src[i]); //遞歸賦值 } else { result[i] = src[i]; //直接賦值 } } } } }else{ //對於原始類型直接賦值。 result = src; } return result; }
學習數組、字符串、數字等相關方法,在util.js
中實現如下函數
// 對數組進行去重操做,只考慮數組中元素爲數字或字符串,返回一個去重後的數組 function uniqArray(arr) { // your implement } // 使用示例 var a = [1, 3, 5, 7, 5, 3]; var b = uniqArray(a); console.log(b); // [1, 3, 5, 7]
思路以下:
新建一下新數組
循環原數組
判斷新數組內元素,原數組是否含有.含有則跳過
這裏使用了數組的indexOf
方法,找到某個元素在數組中的索引。簡化了查找過程,若使用最簡單的遍歷尋找的話須要嵌套循環,是這樣的,先在循環中取原數組的值,再循環在新數組中查找,如有相等的狀況就不添加。(這是個人第一想法,顯然比如今複雜不少).
參看來自MDN的Array對象.裏面介紹了一下數組的方法.
返回新數組.
實現:
function uniqArray(arr) { // your implement var result = []; //建立一個新數組。 for (var i = 0, l = arr.length; i < l; i++) { if (result.indexOf(arr[i]) === -1) { //查找是否已經含有該元素 result.push(arr[i]); //添加到新數組 } } return result; //返回新數組 }
trim
函數,去除字符串首尾空白實現一個簡單的trim
函數,用於去除一個字符串,頭部和尾部的空白字符
//1.字符串查找 // 假定空白字符只有半角空格、Tab // 練習經過循環,以及字符串的一些基本方法,分別掃描字符串str頭部和尾部是否有連續的空白字符,而且刪掉他們,最後返回一個完成去除的字符串 function simpleTrim(str) { // your implement } //2.正則 // 不少同窗確定對於上面的代碼看不下去,接下來,咱們真正實現一個trim // 對字符串頭尾進行空格字符的去除、包括全角半角空格、Tab等,返回一個字符串 // 嘗試使用一行簡潔的正則表達式完成該題目 function trim(str) { // your implement } // 使用示例 var str = ' hi! '; str = trim(str); console.log(str); // 'hi!'
實現以下:
//1.字符串查找 //這裏就是利用兩個循環,找到頭尾第一個不是空格且不是tab符的元素。記錄它們的索引,以後截取字符串。 function simpleTrim(str) { // your implement var result = ""; for (var i = 0, il = str.length; i < il; i++) { //從頭查找 if (str[i] != " " && str[i] != "\t") { break; //查找到第一個不爲空格及tab符的元素 } } for (var j = str.length - 1; j >= 0; j--) { //從尾查找 if (str[j] != " " && str[j] != "\t") { break; } } result = str.slice(i, j + 1); //截取須要的字符串。 return result; } //2.正則 function trim(str) { // your implement var result = ""; result = str.replace(/^\s+|\s+$/g, ""); //使用正則進行字符串替換 return result; }
// 實現一個遍歷數組的方法,針對數組中每個元素執行fn函數,並將數組索引和元素做爲參數傳遞 function each(arr, fn) { // your implement } // 其中fn函數能夠接受兩個參數:item和index // 使用示例 var arr = ['java', 'c', 'php', 'html']; function output(item) { console.log(item) } each(arr, output); // java, c, php, html // 使用示例 var arr = ['java', 'c', 'php', 'html']; function output(item, index) { console.log(index + ': ' + item) } each(arr, output); // 0:java, 1:c, 2:php, 3:html
思路以下:
這裏的實現有點相似ECMA5中數組的forEach()
方法
由示例可知:item爲必須參數,index爲可選參數.
且item爲數組項,index爲數組索引.
這樣就簡單了,循環傳參.
實現:
function each(arr, fn) { // your implement for (var i = 0, l = arr.length; i < l; i++) {//遍歷傳參 fn(arr[i], i); } }
// 獲取一個對象裏面第一層元素的數量,返回一個整數 function getObjectLength(obj) {} // 使用示例 var obj = { a: 1, b: 2, c: { c1: 3, c2: 4 } }; console.log(getObjectLength(obj)); // 3
實現:
//使用for in遍歷時,直接獲取到的就是第一層的結果 //排除繼承來的屬性,使用外部變量保存循環次數 function getObjectLength(obj) { var count = 0; for (var i in obj) { if (obj.hasOwnProperty(i)) { count++; } } return count; }
// 判斷是否爲郵箱地址 function isEmail(emailStr) { // your implement } // 判斷是否爲手機號 function isMobilePhone(phone) { // your implement }
實現思路
這裏參考我對於正則表達式入門的兩篇博客
手機號碼的匹配
這裏匹配的狀況是最簡單的狀況,並無特別完美,好比限制開頭第二位數字的範圍:188,158經過,而123,191,不經過等等。
可利用多選分支,例如:/^1[3|5][0-9]{9}$|^18\d{9}$/
。不過如今虛擬運營商的加入,號碼段變多了,因此直接用最簡單的方法,也沒事。
郵箱的匹配
在@前能出現哪些東西?這裏使用(\w+\.)*
來匹配出現.
的狀況,表示出現0次或屢次由於.
後不能緊跟@,因此後面緊跟\w+
匹配普通的字母數字狀況。
@後出現的郵箱後綴並不固定因此使用\w+
來匹配。
最後考慮域名結尾的級聯狀況因此用(\.\w+)+
。
實現以下:
// 判斷是否爲郵箱地址 function isEmail(emailStr) { // your implement var reg = /^(\w+\.)*\w+@\w+(\.\w+)+$/; return reg.test(emailStr); } // 判斷是否爲手機號 function isMobilePhone(phone) { // your implement var reg = /^1\d{10}$/; return reg.test(phone); }