1.冒泡排序:
只須要比較n-1趟,因此循環次數爲數組長度-1。php
function BubbleSort(arr){ for(var i=0;i<arr.length-1;i++){ for(var j=0;j<arr.length-1;j++){ if(arr[j+1]<arr[j]){ var temp; temp = arr[j+1]; arr[j+1] = arr[j]; arr[j] = arr[j+1]; } } } return arr; }
2.快速排序:
利用二分法和遞歸實現快速排序。ajax
function quickSort(arr){ if(arr.length == 0){ return []; } //利用Math.floor()方法向下取整找到中間位置 var cIndex = Math.floor(arr.length / 2); //再用splice()方法將數組中間位置的元素取出來 var c = arr.splice(cIndex,1); var l = [],r = []; for(var i = 0;i<arr.length;i++){ if(arr[i]<c){ l.push(arr[i]); }else{ r.push(arr[i]); } } return quickSort(l).concat(c,quickSort(r)); }
3.JS基本規範:
不要在同一行聲明多個變量,正確寫法以下:數組
var a = 1, b = 2, c = 3;
建議使用對象字面量的寫法替代new Array這種寫法:var arr = [1,2,3,4];
儘可能不要使用全局變量;
For循環和IF語句必須使用大括號;
Switch語句必須帶有Default分支;
for-in 循環中的變量應該使用Var關鍵字限定做用域,避免做用域污染緩存
4.JS的基本數據類型
undefined、Null、String、Boolean、Number服務器
5.Js中數組的一些操做
<1>map():遍歷數組,返回回調返回值組成的新數組閉包
var arr = [1,2,3,4]; var arr = arr.map(function(item){ return item * item; }) console.log(arr); //[1,4,9,16] var users = [ {name:"老王",age: 70}, {name:"大王",age: 50}, {name:"小王",age: 30} ]; var ages = users.map(function(user){ return user.age; }) console.log(ages); //[70,50,30]
<2>forEach():遍歷數組,但沒法break,能夠用try catch語句中的throw new Error()來中止異步
var users = [ {name:"老王",age: 70}, {name:"大王",age: 50}, {name:"小王",age: 30} ]; var names = []; users.forEach(function (item){ names.push(item.name); }); console.log(names); //["老王", "大王", "小王"]
<3>filter():過濾模塊化
var arr = [1,2,3,4,5]; var newArr = arr.filter(function(item){ return item>3; }); console.log(newArr); //[4,5]
<4>some():有一項返回true,則總體都爲true函數
var arr = [1,2,3,4,5]; var result = arr.some(function(item){ return item>4; }); console.log(result); //true
<5>every():有一項返回false,則總體返回false組件化
var arr = [1,2,3,4,5]; var result = arr.every(function(item){ return item>6; }); console.log(result); //false
<6>join():經過指定鏈接符生成字符串
var arr = [1,2,3,4,5]; var result = arr.join("-=-"); console.log(result); //1-=-2-=-3-=-4-=-5
<7>push()/pop():末尾推入和彈出,改變原數組, 返回推入/彈出項,會修改原數組
var arr = [1,2,3,4]; var result1 = arr.push(5); console.log(result1) //5 console.log(arr); //[1,2,3,4,5] var result2 = arr.pop(); console.log(result2); //5 console.log(arr); //[1,2,3,4]
<8>shift()/unshift():
shift()移除數組第一項,返回該值;
unshift()添加一個元素進數組第一項,返回新數組長度
var arr = [1,2,3,4]; var result1 = arr.shift(); console.log(result1); //1 console.log(arr); //[2,3,4] var result2 = arr.unshift(1); console.log(result2); //4 console.log(arr); //[1,2,3,4]
<9>sort(fn)/reverse():排序數組和反轉數組,會修改原數組
var arr = [1,6,3,5,4,2]; arr.sort(function(a,b){ return a-b; //a-b由小到大排序,b-a由大到小排序 }); console.log(arr); //[1,2,3,4,5,6] arr.reverse(); console.log(otherResult); //[6,5,4,3,2,1]
<10>concat():鏈接數組,不影響原數組淺拷貝。若是參數不是數組,直接當成數組元素添加到數組中,並返回一個新的數組實例。
var arr1 = [1,2,3]; var arr2 = ["Sami","Nick","Michael"]; var result = arr1.concat(arr2); console.log(arr1); //[1,2,3] console.log(arr2); //["Sami","Nick","Michael"] console.log(result); //[1,2,3,"Sami","Nick","Michael"]
<11>slice(start,end):返回截斷後的新數組,不改變原數組。第一個參數起始位置,第二個結束位置。截取的數組不包含結束位置上的元素。
var arr = [1,2,3,4,5]; var result = arr.slice(0,2); console.log(result); //[1,2] console.log(arr); //[1,2,3,4,5]
<12>splice(start,number,value...):返回刪除元素組成的數組,value 爲插入項,改變原數組。
var arr = [1,2,3,4,5]; var result = arr.splice(1,2); console.log(arr); //[1,4,5]; console.log(result); //[2,3];
<13>indexOf(value,fromIndex)、lastIndexOf(value,fromIndex):
查找數組項,返回對應的下標。indexOf從前日後查找,lastIndexOf從後往前查找。
var arr = [1,2,7,4,5,6,7]; var index = arr.indexOf(7); console.log(index); //2 var index = arr.indexOf(7,3); console.log(index); //6 var index = arr.lastIndexOf(7); console.log(index); //6 var index = arr.lastIndexOf(7,3); console.log(index); //2
6.事件偵聽器通用對象:
var EventUtil = { addEvent:function(element,type,handler){ if(element.addEventListener){ element.addEventListener(type,handler,false); }else if(element.attachEvent){ element.attachEvent("on" + type,handler); }else{ element["on" + type] = handler; } }, removeEvent:function(element,type,handler){ if(element.removeEventListener){ element.removeEventListener(type,handler,false); }else if(element.detachEvent){ element.detachEvent("on" + type,handler); }else{ element["on" + type] = null; } }, getEvent:function(){ return event ? event: window.event; }, getTarget:function(event){ return event.target || event.srcElement; }, preventDefault:function(event){ if(event.preventDefault){ event.preventDefault(); }else{ event.returnValue = false; } }, stopPropagation:function(event){ if(event.stopPropagation){ event.stopPropagation(); }else{ event.cancelBubble(); } } } //調用方法 var btn = document.getElementById("myBtn"); var handler = function(){ event = EventUtil.getEvent(); EventUtil.preventDefault(); alert("Clicked"); }; EventUtil.addEvent(btn,click,handler);
7.JS的內置對象:
數據封裝對象:Object、Array、Boolean、Number、String;
其餘對象:Math、Date、Function、Error、RegExp、Arguments
8.閉包:指有權訪問另外一個函數做用域中變量的函數。
function parentFunc(){ var a = 1; function childFunc(){ console.log(a); } return childFunc(); }
閉包的特徵:
<1>函數內再嵌套函數;
<2>內部函數能夠調用外部函數的參數和變量;
<3>參數和變量不會被垃圾回收機制回收。
閉包的好處:可以實現封裝和緩存。使用閉包主要是爲了封裝對象的私有屬性和私有方法,閉包能夠避免全局變量的污染。
閉包的缺點:閉包會常駐內存,會增大內存使用量,使用不當很容易形成內存泄漏。
閉包經典問題:
function parentFunc(){ var arr = []; for(var i = 0;i<5;i++){ arr[i] = function (){ return i; } } return arr; } console.log(parentFunc()[0]()); //5 console.log(parentFunc()[1]()); //5
這裏就展示出了幾個關鍵信息,首先分析一下代碼:循環中建立了一個匿名函數並將其賦值給arr數組中對應索引的元素,匿名函數做用是返回i值。此時,arr數組中存放的是匿名函數,而匿名函數尚未執行。當調用parentFunc()函數時返回arr數組,再單獨執行數組中的元素保存的匿名函數,此時循環已經執行完,因此i值爲5。接下來再去調用其它數組元素中的匿名函數也樣會得到數值5。
要解決這個閉包所產生的問題,有兩種辦法:
<1>當即執行匿名函數
function parentFunc(){ var arr = []; for(var i = 0;i<5;i++){ arr[i] = (function (){ return i; })(); } return arr; } console.log(parentFunc()); //[0,1,2,3,4]
<2>使用let關鍵字聲明變量:使用let聲明變量會造成塊級做用域
function parentFunc(){ var arr = []; for(let i = 0;i<5;i++){ arr[i] = function (){ return i; }; } return arr; } console.log(parentFunc()[0]()); //0
9.JS做用域:分爲全局做用域和函數做用域
全局做用域,代碼在程序中的任何地方都能訪問,window對象的內置屬性都擁有全局做用域;
函數做用域,在固定的代碼片斷才能訪問。
10.做用域鏈:做用域鏈的做用是保證執行環境裏有權訪問的變量和函數是有序的,做用域鏈的變量只能向上訪問,變量訪問到window對象即被終止,做用域鏈向下訪問變量是不被容許的。
11.原型和原型鏈:
每一個對象都會在其內部初始化一個屬性-prototype(原型)。當咱們訪問一個對象的屬性時,若是這個對象的內部不存在這個屬性,就會去prototype中查找這個屬性,這個prototype又會有本身的prototype,因而就會像鏈條同樣一直找下去造成原型鏈。
(由於全部的對象都是由Object對象繼承而來,所以最終查找到Object的prototype結束)
12.組件化:利用組件化思想將多個頁面都須要用的功能組件封裝起來,提升代碼複用性,下降耦合性,加強可維護性和可讀性。
13.模塊化:主要用途是封裝對象
模塊化的優勢:避免全局變量變量污染,命名衝突;提升代碼複用率;提升了可維護性。
最經常使用的模塊化封裝對象的方法是:構造函數模式+原型模式。
構造函數內寫屬性,原型中放方法和重寫構造函數指針。
function Person(name,age){ this.name = name; this.age = age; } Person.prototype = { constructor: Person, sayName: function(){ alert(this.name); } } var person1 = new Person("老王", 70); var person2 = new Person("小王", 20); alert(person1.name === person2.name); //false,構造函數內屬性不公用 alert(person1.sayName === person2.sayName); //true,原型中的方法共用
組合使用構造函數模式和原型模式封裝對象的好處在於,每一個新建的實例都擁有本身的屬性,而後共同享有原型中的方法,不用每次建立新實例都從新建立一樣的方法。
14.繼承:實現繼承的經常使用方法是原型鏈+借用構造函數。
原型鏈實現對原型屬性和方法的繼承,借用構造函數實現對實例屬性的繼承。
function SuperType(name){ this.name = name; } SuperType.prototype.sayName = function(){ alert(this.name); } function SubType(age){ //繼承屬性 SuperType.call(this,name); this.age = age; } //繼承方法 SubType.prototype = new SuperType(); SubType.prototype.constructor = SubType; SubType.prototype.sayAge = function(){ alert(this.age); } var p1 = new SubType("老王", 70); var p2 = new SubType("小王", 20); p1.sayName(); //老王 p2.sayName(); //小王 p1.sayAge(); //70 p2.sayAge(); //20
15.Ajax:ajax的核心是XMLHttpRequest(XHR)
<1>如何建立一個ajax
//get方法 var xhr = new XMLHttpRequest(); xhr.open("get","example.php",true); //發送的請求類型、請求的URL、是否異步發送請求 xhr.send(null); xhr.onreadystatechange= function(){ if(xhr.readyState === 4){ if(xhr.status === 200){ success(xhr.responseText); }else{ console.log(xhr.status); } } } //post方法 var data = new FormData(document.forms[0]); xhr.open("post","example.php",true); xhr.send(data);
<2>同步和異步的區別:
同步:用戶請求,等待,響應,刷新頁面展現內容再操做;
異步:用戶請求的同時可繼續對頁面操做,響應完成不刷新頁面展現新內容。
<3>
Ajax優勢:
異步請求響應快,用戶體驗好;頁面無刷新、數據局部更新;按需取數據,減小了冗餘請求和服務器的負擔;
Ajax缺點:
異步回調問題、this指向問題、路由跳轉back問題;對搜索引擎的支持比較弱,對於一些手機還不是很好的支持
<4>post通常用於修改服務器上的資源,對發送的數據沒有限制;而get通常用於請求獲取數據。
16.事件代理:
事件代理又稱之爲事件委託,是綁定事件的經常使用技巧。即把本來須要綁定的事件委託給父元素,讓父元素擔當事件監聽的職務。
事件代理的原理是DOM元素的事件冒泡。
使用事件代理的好處是能夠提升性能,節省內存佔用,減小事件註冊。能夠實現當新增子對象時無需再對其綁定。
好比在table上代理td的click事件。
17.this對象:
·this老是指向函數的直接調用者(而非間接調用者);
·若是有new關鍵字,this指向new出來的新對象
·在事件中,this指向觸發這個事件的對象,但IE中的attachEvent中的this指向window對象。
18.事件模型:
·冒泡型事件:當你使用事件冒泡時,子元素先觸發,父元素後觸發;
·捕獲型事件:當你使用事件捕獲時,父元素先觸發,子元素後觸發;
·DOM事件流:同時支持兩種事件模型,冒泡型事件和捕獲型事件;
·阻止冒泡:阻止事件冒泡。在w3c中使用stopPropagation()方法,在IE中使用cancelBubble = true;
·阻止捕獲:阻止事件的默認行爲。在w3c中使用preventDefault()方法,在IE中使用returnValue = false。
19.XML和JSON的區別:
·JSON相對XML,數據體積更小,傳遞速度更快些;
·JSON與JS的交互更方便,更容易解析處理,更好的數據交互;
·JSON對數據的描述性比XML較差;
·JSON的傳輸速度遠遠快於XML。
20.JS定義對象的方法:
·對象字面量: var obj = {};
·構造函數: var obj = new Object();
·Object.create: var obj = Object.create(object.prototype);
21.