最近一直有小夥伴跟我說JS
有不少知識點常常不用,已經忘記的差很少了。平時找一個小問題都要在網上找半天,但願能有一套比較全面的筆記或者文章。可是網上的文章太過於分散,學習起來不是很方便。恰巧最近比較閒,因此爲你們整理出來了一套比較全面的JS
基礎階段的文章,對於初學者仍是頗有幫助的,若是你是一名熟練掌握JS
的攻城獅,你可能會以爲文章寫得太過於囉嗦,可是爲了照顧你們,囉嗦一點仍是有必要的。javascript
這篇文章主要講的是關於JS
基礎的知識點,後面會陸續更新DOM
、JS高階
、Ajax
、H5C3
、JQ
,包括一些主流的框架,可是本人時間有限,不可能專門去花費時間來寫,並且工做量也是很是大的,因此喜歡的小夥伴能夠點一波關注,後續會陸續更新。css
因爲是本身所寫,因此裏面有些語言可能表達的有些不明確,不明白的能夠給我留言。html
javascript是一種運行在客戶端
的腳本語言
客戶端: 即接受服務的一端
,與服務端相對應,在前端開發中,一般客戶端指的就是瀏覽器
。前端
腳本語言: 也叫解釋型語言
,特色是執行一行
,解釋一行
,若是發現報錯,代碼就中止執行。java
javascript的三個組成部分:ECMAScript
、BOM
、DOM
ECMAScript: 定義了javascript
的語法規範。程序員
BOM: 一套操做瀏覽器功能的API
。segmentfault
DOM: 一套操做頁面元素的API
。數組
一、script標籤的書寫方式瀏覽器
書寫Javascript
代碼有兩種方式,第一種是直接在script
標籤中書寫,第二種是將代碼寫在js
文件中,經過script
的src
屬性進行引入。
直接在script
中書寫javascript
代碼:框架
<!-- type="text/javascript" 能夠省略 --> <script type="text/javascript"> alert("今每天氣真好呀"); </script>
經過script標籤引入一個JS文件,須要指定src
屬性:
<!-- 表示引用了test.js文件,而且script標籤內不能夠繼續寫代碼 --> <script src="test.js"></script>
若是script
標籤指定了src
屬性,說明是想要引入一個js
文件,這個時候不能繼續在script
標籤中寫js
代碼,即使寫了,也不會執行。
二、script標籤的書寫位置
script
標籤的書寫位置,原則上來講,能夠在頁面中的任意位置書寫。
寫在head
標籤中,style
標籤以後:
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>Document</title> <link rel="stylesheet" href="demo.css"> <!-- 寫在這裏 --> <script src="demo.js"></script> </head> <body> </body> </html>
瀏覽器有一個特性,就是在遇到<body>
標籤時纔開始呈現內容。若是在head
裏面引用js
文件的話,意味着必需要等到所有的javascript
代碼都被下載、解析和執行完成以後,才能開始呈現頁面的內容。若是文件數量一旦過多,將會影響頁面加載速度,此時頁面有可能會在加載完成前一片空白。
寫在</body>
標籤的前面:
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>Document</title> <link rel="stylesheet" href="demo.css"> </head> <body> <!-- 寫在這裏 --> <script src="demo.js"></script> </body> </html>
在解析javascript
代碼以前,頁面的內容已經徹底呈如今瀏覽器當中了,用戶會明顯感受頁面加載變快了。
console.log
控制檯輸出日誌console.dir
對象的形式打印一個對象document.write
往頁面中寫入內容alert
彈框警告confirm
確認框prompt
輸入框不被程序執行的代碼。用於程序員標記代碼,在後期的修改,以及他人的學習時有所幫助,在JS中,分爲單行註釋
和多行註釋
以及文檔註釋
。
單行註釋
//這是單行註釋,只能註釋一行
多行註釋
/* 這是多行註釋,不能嵌套 */
文檔註釋
/** * 求圓的面積 * @param r {number} 圓的半徑 * @returns {number} 圓的面積 * 這是文檔註釋 */ function getArea (r) { return Math.PI * r * r; }
註釋的做用
變量,能夠變化的量
,變量是在計算機中存儲數據的一個標識符
。能夠把變量當作存儲數據的容器
。
變量與字面量:
10
、20
、「abc」
、true
這種從字面上就能看出來類型和值的量叫作字面量。// 1- 同時聲明而且賦值 var num = 100; console.log(num); // 100 // 2- 先聲明瞭一個變量,再賦值 var num1; num1 = 100; console.log(num1); // 100 // 3- 沒有聲明變量,直接賦值(能夠,可是不推薦) num2 = 200; console.log(num2); // 200 // 4- 有變量聲明,可是沒有賦值(能夠,沒有賦值,變量的值默認是個undefined) var num9; console.log(num9); // undefined // 5- 既沒有聲明,也沒有賦值,直接用。 console.log(num3); //報錯 num3 // 6- 一個 var,逗號分隔 能夠同時聲明多個變量 var name = "Levi丶", age = 18, gender = "男";
命名規則(必須遵照):
$
符號組成,開頭不能是數字。命名規範(建議遵照):
方法一: 聲明一個新的變量
// 交換 num1 和 num2的值 var num1 = 11; var num2 = 22; var temp; temp = num1; // num1=11 temp=11 num1 = num2; // num1=22 num2=22 num2 = temp; // temp=11 num2=11
方法二: 不經過聲明變量的方式
// 不使用臨時變量 var num1 = 11; var num2 = 22; // num1 = 11 + 22 num1 = num1 + num2; // num1=33 // num2 = 33 - 22 num2 = num1 - num2; // num2=11 // num1 = 33 - 11 num1 = num1 - num2; // num1=22
基本數據類型包括了:number
、string
、boolean
、undefined
、null
使用
typeof
關鍵字查看數據類型
typeof(name); // 括號能夠省略 typeof name;
進制
0
和1
0
開頭的數值,數值序列:0-7
0x
開頭的數值,數值序列:0-9
、A-F
、a-f
浮點數
所謂浮點數,就是該數當中必須包含一個小數點,而且小數點後面至少有一位數字。
科學計數法:
//如何表示0.003和20000? var num = 3e-3; // 0.003 var num2 = 2e+4; // 20000
浮點數的精度問題:
0.1 + 0.2 = ? // 0.30000000000000004 0.07 * 100 = ? // 7.000000000000001
浮點數在運算的時候會出現精度丟失的問題,所以在作比較運算的時候,儘可能不要用小數進行比較。在第五章的時候會着重講解這個問題
數值範圍
javascript
不能表示世界上全部的數,所以在javascript
中,數值大小是有必定限制的。
Number.MIN_VALUE
:5e-324 (js
裏面能表示最小的數)Number.MAX_VALUE
:1.7976931348623157e+308 (js
裏面能表示最大的數)Infinity
:正無窮 (若是超出js
裏面最大的數,將會顯示infinity
)-Infinity
:負無窮 (若是超出js
裏面最小的數,將會顯示-infinity
)數值判斷
NaN
: 表示一個非數值
,當沒法運算或者運算錯誤的時候,會獲得一個NaN
,NaN
是number類型
,表示一個非數值。NaN
與任何值都不想等,包括它自己isNaN
: 用來判斷是不是一個數字,當返回true
的時候說明是NaN
,表示的不是一個數字,返回false
,說明不是NaN
,表示的是一個數字。示例代碼:
var str = "abc"; console.log(isNaN(str)); // true 說明不是一個數字
字面量
字符串的字面量:「abc」
、‘abc’
字符串能夠是雙引號,也能夠是單引號引發來。
無論是雙引號,仍是單引號,都是成對出現的,假如打印的字符串裏有引號怎麼辦呢?
這裏就要活學活用,若是隻有一處有引號,就能夠用單雙引號混合使用:
console.log('我是"帥哥"'); // ==> 我是"帥哥"
假如引號很是多的時候怎麼辦呢? 用轉義字符:「\」
:
console.log("我是'帥哥',\"哈哈哈\""); // ==> 我是'帥哥',"哈哈哈"
字符串拼接
拼接字符串使用
+
號
示例代碼:
console.log(11 + 11); // 22 console.log("hello" + " world"); // "hello world" console.log("100" + "100"); // "100100" console.log("11" + 11); // "1111"
總結:
+
就是字符串拼接功能字符串長度
length
屬性用來獲取字符串的長度
var str = "abcdefghij"; str.length;// 字符串的長度 10
boolean
類型只有兩個字面量,true
和false
,區分大小寫(True,False不是布爾類型,只是標識符)。
全部類型的值均可以轉化成true
或者false
NaN
、""
、undefined
、null
、alse
、0
這6
個值能夠轉換成false
,其他的都是true
。
undefined
表示一個聲明瞭沒有賦值的變量
var name ; console.log(name); // undefined
null
表示一個空的對象
var name = null; console.log(typeof name); // Object
若是定義的變量,未來是準備用於保存對象的話,最好將變量初始化爲null
var name = null;
undefined
與 null
的關係
undefined == null; // true undefined === null; // false
實際上,undefiner
值是派生自null
值的,因此判斷相等時爲true
,可是兩種用途是徹底不同的。
如何使用谷歌瀏覽器,快速的查看數據類型?
黑色
的藍色
的藍色
的undefined
和null
是灰色
的這個在調試過程當中時很是有用的。
一、String()
函數轉換
var num = 123; console.log(String(num)); // "123"
二、toString()
轉換不了undefined
和 null
var num = 123; console.log(num.toString()); // "123" console.log(undefined.toString()); // 報錯 console.log(null.toString()); // 報錯
三、+ ""
加引號
var num = 123; console.log(num + ""); // "123"
一、Number
0
;NaN
;console.log(Number("-123")); // -123 console.log(Number("")); // 0 console.log(Number("123abc")); // NaN
二、parseInt
(取整)
NaN
;console.log(parseInt("123.123")); // 123 console.log(parseInt("123.123abc")); // 123 console.log(parseInt("abc123.123")); // NaN console.log(parseInt("")); // NaN console.log(parseInt("abc")); // NaN
三、parseFloat
(取數)
NaN
;console.log(parseFloat("123.123")); // 123.123 console.log(parseFloat("123.123abc")); // 123.123 console.log(parseFloat("abc123.123")); // NaN console.log(parseFloat("")); // NaN console.log(parseFloat("abc")); // NaN
四、參與運算==> "+
" or "-0
"
var str = "-123"; console.log(+str); // -123 console.log(str-0); // -123
布爾類型只有true
和false
,可是全部類型的值均可以轉換成布爾類型
一、可以轉換成false
的只有6
種:
""
0
NaN
undefined
null
false
其他的都是true
二、!
轉換
var str = ""; // Boolean() 判斷這個參數的布爾類型 console.log(Boolean(str)); // false console.log(!str); // true
js
在使用小數進行計算的時候,會出現精度丟失的問題。不要用來跟其餘的小數作比較。
0.1 + 0.2 != 0.3 //true 0.30000000000000004 // 16位數 和 17位數相等 9999999999999999 == 10000000000000001 // true 9007199254740992 + 1 == 9007199254740992 // true
計算機的二進制實現和位數限制有些數沒法有限表示。就像一些無理數不能有限表示,如 圓周率 3.1415926...
,1.3333...
等。JS
遵循 IEEE 754
規範,採用 雙精度存儲(double precision
) ,佔用 64 bit
。如圖
意義:
1
位用來表示符號位11
位用來表示指數52
位表示尾數浮點數,好比:
0.1 >> 0.0001 1001 1001 1001…(1001無限循環) 0.2 >> 0.0011 0011 0011 0011…(0011無限循環)
此時只能模仿十進制進行四捨五入了,可是二進制只有0
和1
兩個,因而變爲0
舍1
入。這便是計算機中部分浮點數運算時出現偏差,丟失精度的根本緣由。
大整數的精度丟失和浮點數本質上是同樣的,尾數位最大是 52
位,所以 JS
中能精準表示的最大整數是 Math.pow(2, 53)
,十進制即 9007199254740992
。
大於 9007199254740992
的可能會丟失精度:
9007199254740992 >> 10000000000000...000 // 共計 53 個 0 9007199254740992 + 1 >> 10000000000000...001 // 中間 52 個 0 9007199254740992 + 2 >> 10000000000000...010 // 中間 51 個 0
實際上:
9007199254740992 + 1 // 丟失 9007199254740992 + 2 // 未丟失 9007199254740992 + 3 // 丟失 9007199254740992 + 4 // 未丟失
結果如圖:
以上,能夠知道看似有窮的數字,在計算機的二進制表示裏倒是無窮的,因爲存儲位數限制所以存在「捨去」,精度丟失就發生了。
對於整數,前端出現問題的概率可能比較低,畢竟不多有業務須要須要用到超大整數,只要運算結果不超過 Math.pow(2, 53)
就不會丟失精度。
對於小數,前端出現問題的概率仍是不少的,尤爲在一些電商網站涉及到金額等數據。解決方式:把小數放到位整數(乘倍數),再縮小回原來倍數(除倍數)
// 0.1 + 0.2 (0.1*10 + 0.2*10) / 10 == 0.3 // true
一元
運算符有1個
操做數。例如,遞增運算符"++"
,或者遞減運算符"--"
就是一元運算符。二元
運算符有2個
操做數。例如,除法運算符"/"
有2
個操做數。三元
運算符有3個
操做數。例如,條件運算符"?:"
具備3
個操做數。遞增"++"
和 遞減"--"
還分爲前自增
或後自增
,前自減
或後自減
,兩種自增自減的運算結果是不同的;
++num
前自增 --num
前自減 先+1
或-1
,再返回值num++
後自增 num--
後自減 先返回值,再+1
或-1
舉個例子,看代碼:
var num = 5; console.log(num++); // 5 console.log(++num); // 7 (由於剛剛num自增了一次,這裏打印的話就等於在6的基礎上前自增了,在計算機科學中,被稱爲副效應) console.log(num--); // 7 (這裏是後自減,因此先返回值,返回7,再運算--,此時的num實際是等於6了) console.log(--num); // 5
&&
(與運算):只要有一個值爲假
,結果就是假
。找假
值 找到假值就返回,若是都是真
,返回最後一個||
(或運算):只要有一個值爲真
,結果就是真
。找真
值 找到真值就返回,若是都是假
,返回最後一個!
(非運算):取反示例代碼:
/*細讀上面三句話,就能理解爲何會是這個打印結果了*/ console.log(true && true); //true console.log(false || false); //false console.log(null && undefined); //null console.log(null || undefined); //undefined console.log("abc" && undefined); //undefined console.log("abc" || undefined); //abc console.log(null || false || 0 || 1 || null); //1 console.log("abc" && "bcd" && "def"); //def
()
優先級最高++
--
!
*
/
%
後 +
-
>
>=
<
<=
==
!=
===
!==
&&
後||
示例代碼:
// 第一題 true && true console.log(((4 >= 6) || ("人" != "狗")) && !(((12 * 2) == 144) && true)); // true // 第二題 var num = 10; // true && true if(5 == num / 2 && (2 + 2 * num).toString() === "22") { console.log(true); // true }else{ console.log(false); }
語法:
只有一個判斷條件的時候 if..else
:
if(判斷條件){ // 當判斷條件爲true的時候執行代碼1,爲false的時候執行代碼2 代碼1; }else{ 代碼2; }
當不止一個判斷條件的時候 else
用else if
代替:
if(判斷條件1){ // 判斷條件 1 爲 true 的時候執行 代碼 1 代碼1; }else if(判斷條件2){ // 判斷條件 2 爲 true 的時候執行 代碼 2 代碼2; }else{ // 兩個條件都不知足的時候執行代碼 3 代碼3; }
思考1:
18
,告訴他能夠看電影16
,告訴他能夠在家長的陪同下觀看16
,告訴他不許看var age = 20; if(age >= 18){ console.log("沒時間解釋了,趕忙上車吧"); // 打印這條 }else if(age >= 16){ console.log("請在家長的陪同下觀看"); }else { console.log("回家學習吧"); }
思考2:
new Date().getDay()
獲取今天是星期幾var date = new Date(); // 獲取當前的時間 var week = date.getDay(); // 得到 0-6 表示周幾 0:星期日 if(week == 0){ console.log("今天是星期天"); }else if(week == 1){ console.log("今天是星期一"); }else if(week == 2){ console.log("今天是星期二"); }else if(week == 3){ console.log("今天是星期三"); }else if(week == 4){ console.log("今天是星期四"); }else if(week == 5){ console.log("今天是星期五"); }else if(week == 6){ console.log("今天是星期六"); }else{ console.log("你火星的來的吧"); }
語法:
// switch: 開關; case: 案列; switch(變量){ // 判斷變量是否全等於case的值1,或者值2, case 值1: 執行代碼1; // 全等於的時候執行代碼1 break; // 而後break;代碼跳出switch語句, 不加break,會繼續執行下面的代碼 case 值2: 執行代碼2; break; default: 執行代碼3; // 當都不知足條件的時候,會執行默認裏的執行代碼3 }
思考:素質教育(把分數變成ABCDE)
// 90-100 : A // 80-89: B // 70-79: C // 60-69: D // 0-59 : E // 這裏的等級是根據一個範圍的分數劃定的,用if..else很容易實現,可是switch..case是一個具體的條件,怎麼辦呢? // 方法:將分數除以10再用parseInt屬性取整 var score = 85; score = parseInt(score/10); // 8 switch (score) { // score = 10 或者 9 的時候 返回 A case 10: case 9: console.log("A"); break; // score = 8 的時候 返回 B case 8: console.log("B"); break; case 7: console.log("C"); break; case 6: console.log("D"); break; default: console.log("E"); }
這個運算符能夠用來代替if..else
條件判斷。可是爲何有這個運算符呢?這裏的緣由是if..else
使用兩個代碼塊,卻只有一個會執行,在講究的程序員看來是一種浪費。因此使用三元運算符,用一條語句就能夠完成功能。
語法:
判斷語句?表達式1:表達式2; 根據判斷語句返回的布爾值,true的話,返回表達式1,false的話返回表達式2
舉個例子,看代碼:
var sex = 1; sex == 1 ? "男":"女"; // 判斷sex是否等於1,若是true,返回第一個表達式:"男"
例題:判斷兩個數的大小
// 用if..else語句解決 // 這裏使用了兩個代碼塊,有點浪費 var num1 = 18; var num2 = 39; var max; if(num1>num2){ max = num1; }else{ max = num2; } console.log(max); // 用三元運算符 var num3 = 28; var num4 = 49; var max1 = num3>num4? num3:num4; console.log(max1);
注意(容易出錯的地方):
下面這個語句判斷若是是會員,費用爲2
美圓,非會員,爲10
美圓。如今設置了非會員,卻打印出了2
美圓,顯然出錯了。
var isMember = false; console.log("當前費用" + isMember ? "$2.00" : "$10.00"); // "$2.00"
出錯的緣由是?
號的優先級比+
號低,因此實際運行的語句是
// true console.log("當前費用false" ? "$2.00" : "$10.00"); // "$2.00"
語法:
true
的時候,就會執行循環體false
的時候,結束循環。// 1. 若是循環條件的結果是true的時候,就會執行循環體 // 2. 若是循環條件的結果是false的時候,結束循環。 while(循環條件){ 循環的代碼; // 循環體 自增或者自減; // 必定不要忘記自增或自減,不然就會死循環 }
例如,求0~100的和:
var num = 0; var sum = 0; while(num <= 100){ sum += num; num++; } console.log(sum); // 5050
語法:
do..while
循環和while
循環很是像,兩者常常能夠相互替代do..while
的特色是無論條件成不成立,都會執行1
次。do{ 循環的代碼; // 循環體 自增或者自減; // 必定不要忘記自增或自減,不然就會死循環 }while(循環條件);
例如,求0~100的和:
var num = 0; var sum = 0; do{ sum += num; num++; }while(num<=100); console.log(sum); // 5050
寫while
循環的常常會忘記自增,for
循環實際上是while
循環演化過來的,語法更加的簡潔明瞭,使用很是的普遍。
語法:
//主要for循環的表達式之間用的是;號分隔的,千萬不要寫成,號 for(初始化表達式;判斷表達式;自增表達式){ //循環體 }
例如:求0~100的和:
var sum = 0; for(var num = 0; num <= 100; num++){ sum += num; } console.log(sum); // 5050
break
:當即跳出整個循環,即循環結束,開始執行循環後面的內容(直接跳到大括號)
continue
:當即跳出當前循環,繼續下一次循環(跳到i++
的地方)
一、continue 示例代碼:
for(var i = 1; i <= 10; i++) { if(i == 5) { continue; } console.log(i); // 1,2,3,4,6,7,8,9,10 }
二、break 示例代碼:
for(var i = 1; i <= 10; i++) { if(i == 5) { break; } console.log(i); // 1,2,3,4 }
一、計算一個數的位數
當不知道循環次數的時候,用while
循環:
var num = 1234567; //由於不知道循環次數,因此推薦使用while循環 var count = 0; // count記錄位數 while(num != 0){ // 循環條件 num = parseInt(num/10);// 讓num縮小10倍 count++; // ,每縮小10倍就計算一次位數了 } console.log(count); // 7
二、翻轉一個數
var num = 12345678; //由於不知道循環次數,因此推薦使用while循環 var str = ""; while(num != 0){ str += num%10; // 將每一位取餘 num = parseInt(num/10);//讓num縮小10倍 } // str 是一個字符串,因此 +str將它轉回Number類型 console.log(+str); //
三、總結:
for
循環用while
循環do..while
循環。所謂數組,就是將多個元素(一般是同一類型的),按必定順序排列放到一個集合中,那麼這個集合就稱之爲數組
在javascript
中,數組是一個有序
的列表,能夠在數組中存放任意
的數據,而且數組的長度能夠動態
的調整
一、經過構造函數建立數組:
var arr = new Array();
建立了一個空數組;var arr = new Array('aa','bb','cc');
建立了一個數組,裏面存放了三個字符串var arr = new Array(11,22,33)
建立了一個數組,裏面存放了三個數字二、經過數組子面量建立數組:
var arr = [];
建立了一個空數組var arr = [11,22,33];
建立了一個數組,裏面存放了三個數字var arr = ['aa','bb','cc'];
建立了一個數組,裏面存放了三個字符串數組的下標:
數組是有序的,數組中的每個元素都對應了一個下標,下標是從
0
開始的
var arr = ['aa','bb','cc']; arr[0]; // 下標是0,對應的值是'aa' arr[2]; // 下標是2,對應的值是'cc'
數組的長度:
跟字符串同樣,數組也有一個length
的屬性,指數組中存放的元素的個數
var arr = ['aa','bb','cc']; arr.length; // 數組的長度爲3
空數組的長度爲0
數組的長度與下標的關係:
數組的最大下標
= 數組的長度
- 1
數組的取值:
數組名[下標]
undefined
var arr = ['red','blue','green']; arr[0]; // red arr[2]; // green arr[3]; // 返回undefined,由於數組最大的下標爲2
數組的賦值:
數組名[下標] = 值;
3
,但是卻給數組下標爲5
賦了一個值,則下標爲三、4
的值爲empty
(空)var arr = ["red", "green", "blue"]; arr[0] = "yellow"; // 把red替換成了yellow arr[3] = "pink"; // 給數組新增長了一個pink的值 arr[5] = "black"; // 數組輸出爲["red", "green", "blue",empty,empty,"black"]
遍歷: 對數組的每個元素都訪問一次,叫作遍歷
數組遍歷的基本語法:
var arr = [1,2,3,4,5,6,7,8,9]; for(var i = 0; i < arr.length; i++){ console.log(arr[i]); // 1 2 3 4 5 6 7 8 9 }
數組遍歷的逆向遍歷語法:
// i= arr.length-1 ==> 表示初始化表達式 從數組最後一位開始遍歷 // i>=0 表示判斷條件,下標要知足大於等於0 // i--,表示每次遍歷 初始值都是自減的 var arr = [1,2,3,4,5,6,7,8,9]; for(var i = arr.length-1; i >= 0; i--){ console.log(arr[i]); // 9 8 7 6 5 4 3 2 1 }
一、求一個數組中的最大值、最小值以及對應的下標
var arr = [298, 1, 3, 4, 6, 2, 23, -88,77,44]; var max = arr[0]; // 隨機取數組中的一個值與其餘值比較 var maxIndex = 0; // 初始化最大值的下標 var min = arr[0]; var minIndex = 0; for(var i = 0; i< arr.length; i++){ if(max < arr[i]){ // 用一開始選擇的值,與遍歷後的值進行比較 max = arr[i]; // 當後面的值比初始值大,就將後面的這個值賦值給初始值,再用這個全新的值再v 去與後面的比較 maxIndex = i; // 比較結束後,此時的索引就是最大值的索引 } if(min > arr[i]){ min = arr[i]; minIndex = i; } } console.log("最大的值是:" + max); console.log("最大值的下標是:" + maxIndex); console.log("最小的值是:" + min); console.log("最小值的下標是:" + minIndex);
二、讓數組倒序保存到一個新的數組中
須要瞭解數組的一個方法 push
,在數組的最後面
添加
var arr = ["大喬", "小喬", "甄姬", "不知火舞"]; var newArr = []; for (var i = arr.length - 1; i >= 0; i--) { newArr.push(arr[i]); } console.log(newArr); // ["不知火舞", "甄姬", "小喬", "大喬"]
三、將字符串數組用"|"或其餘符號拼成一個字符串
var arr = ["aa","bb","cc","dd"]; var str = ""; for(var i = 0; i<arr.length; i++){ if(i == arr.length-1){ str = str + arr[i]; // 判斷一下,若是是最後一個的話就不用加「|」 }else{ str = str + arr[i]+"|"; // str初始值是一個空字符串,遍歷的時候須要加上前一次的結果 } }
四、數組去重
push
到新數組中;var arr = [1, 1, 5, 7, 8, 3, 2, 5, 7, 2, 4, 6, 2, 5, 7, 2, 5]; //定義一個新數組 var newArr = []; //遍歷須要去重的數組 for (var i = 0; i < arr.length; i++) { //假設不存在 var flag = true; //須要判斷arr[i]這個值是否在新數組中存在 for(var j = 0; j < newArr.length; j++){ //進行比較便可 if(arr[i] == newArr[j]){ //若是發現了相等的數,說明存在 flag = false; } } if(flag){ //若是假設成立,說明不存在 newArr.push(arr[i]); } } console.log(newArr);
一個有
8位
元素的數組,讓它的第一位與後面每一位進行比較,前面一位小於後面的時候,位置不變,前面的大於後面的交換位置,就這樣一共要比七趟(最後一趟不要比,就剩一位,就是最小的);
實現原理以下圖:
一、冒泡排序 60分:
var arr = [3, 1, 2, 5, 4, 8, 9, 7, 6]; var tang = 0; var ci = 0; for (var i = 0; i < arr.length - 1; i++) { // 外層for循環,循環的是比較的趟數,由於只要比較8趟 因此i判斷的條件爲length-1 tang++; for (var j = 0; j < arr.length - 1; j++) { // 內層for循環,循環的是比較的次數,每趟比較8次 ci++; if (arr[j] > arr[j + 1]) { // 判斷比較的兩個數,若是前面的大於後面的一位,交換位置 var temp = arr[j]; arr[j] = arr[j + 1]; arr[j + 1] = temp; } } } console.log("趟數:" + tang); // 8趟 console.log("次數:" + ci); // 64次 console.log(arr); }
for
循環,循環的是比較的趟數
,由於只要比較8
趟(數組長度爲9
) 因此i
判斷的條件爲length-1
;for
循環,循環的是比較的次數
,每趟比較8
次,其實這裏次數多比較了,由於第一趟已經找到一個最大值了,第二趟就不須要比8
次了 應該比7
次,這裏先無論,下面會進行優化;測試代碼:
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title></title> </head> <body> <span id="demo"></span><br/> <button id="stb">從小到大</button> <button id="bts">從大到小</button> <span id="show"> </span> <script> var demo = document.getElementById("demo"); var show = document.getElementById("show"); var bts = document.getElementById("bts"); var stb = document.getElementById("stb"); var arr = [3, 1, 2, 5, 4, 8, 9, 7, 6]; demo.innerHTML = arr; bts.onclick = function() { bubbleSort(function(a, b) { return b - a; }); } stb.onclick = function() { bubbleSort(function(a, b) { return a - b; }); } function bubbleSort(fn) { var arr = [3, 1, 2, 5, 4, 8, 9, 7, 6]; var strArr = []; show.innerHTML = ""; strArr.push("<br/>"); var inner = 0; var outer = 0; for (var i = 0; i < arr.length - 1; i++) { strArr.push("第" + (i + 1) + "趟"); for (var j = 0; j < arr.length - 1; j++) { if (fn(arr[j], arr[j + 1]) > 0) { var tmp = arr[j]; arr[j] = arr[j + 1]; arr[j + 1] = tmp; } inner++; } strArr.push(arr.toString()); strArr.push("共" + j + "次" + "<br/>"); outer++; } strArr.push("外循環" + outer + "次"); strArr.push("內循環" + inner + "次"); show.innerHTML = strArr.join(" "); } </script> </body> </html>
每趟都比較8次?明顯是多餘了,下面進行優化
二、冒泡排序80分:
var arr = [3, 1, 2, 5, 4, 8, 9, 7, 6]; var tang = 0; var ci = 0; for (var i = 0; i < arr.length - 1; i++) { tang++; for (var j = 0; j < arr.length - 1 - i; j++) { // 第二趟只比了7次 依次遞減 ci++; if (arr[j] > arr[j + 1]) { var temp = arr[j]; arr[j] = arr[j + 1]; arr[j + 1] = temp; } } } console.log("趟數:" + tang); // 8趟 console.log("次數:" + ci); // 36次 console.log(arr);
i
是從下標0
開始的,第一趟的時候i=0
,比了8
次,第二趟i=1
,只須要比7
次,第三趟i=2
,只須要比6
次...依次類推,因此 比的次數應該就是arr.length - 1 -i
;
測試代碼:
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title></title> </head> <body> <span id="demo"></span><br/> <button id="stb">從小到大</button> <button id="bts">從大到小</button> <span id="show"> </span> <script> var demo = document.getElementById("demo"); var show = document.getElementById("show"); var bts = document.getElementById("bts"); var stb = document.getElementById("stb"); var arr = [3, 1, 2, 5, 4, 8, 9, 7, 6]; demo.innerHTML = arr; bts.onclick = function() { bubbleSort(function(a, b) { return b - a; }); } stb.onclick = function() { bubbleSort(function(a, b) { return a - b; }); } function bubbleSort(fn) { var arr = [3, 1, 2, 5, 4, 8, 9, 7, 6]; var strArr = []; show.innerHTML = ""; strArr.push("<br/>"); var inner = 0; var outer = 0; for (var i = 0; i < arr.length - 1; i++) { strArr.push("第" + (i + 1) + "趟"); for (var j = 0; j < arr.length - 1 - i; j++) { if (fn(arr[j], arr[j + 1]) > 0) { var tmp = arr[j]; arr[j] = arr[j + 1]; arr[j + 1] = tmp; } inner++; } strArr.push(arr.toString()); strArr.push("共" + j + "次" + "<br/>"); outer++; } strArr.push("外循環" + outer + "次"); strArr.push("內循環" + inner + "次"); show.innerHTML = strArr.join(" "); } </script> </body> </html>
還有什麼能夠優化的嗎? 假如8
個數在第3
趟的時候就排好了,還須要繼續排嗎?
三、冒泡排序100分:
假設成立法(3步):
var arr = [3, 1, 2, 5, 4, 8, 9, 7, 6]; var tang = 0; var ci = 0; for (var i = 0; i < arr.length - 1; i++) { var flag = true; // 假設每一次進來都排好了 tang++; for (var j = 0; j < arr.length - 1 - i; j++) { ci++; if (arr[j] > arr[j + 1]) { flag = false; // 若是兩位比較還知足前面的比後面的大的時候,說明假設不成立 var temp = arr[j]; arr[j] = arr[j + 1]; arr[j + 1] = temp; } } if (flag == true) { // 最後判斷一下,若是假設推翻不了,就中止運行。 break; } } console.log("趟數:" + tang); // 4 趟 console.log("次數:" + ci); // 26 次 console.log(arr);
當順序已經排好後,就不用再去執行趟數了;
測試代碼:
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title></title> </head> <body> <span id="demo"></span><br/> <button id="stb">從小到大</button> <button id="bts">從大到小</button> <span id="show"> </span> <script> var demo = document.getElementById("demo"); var show = document.getElementById("show"); var bts = document.getElementById("bts"); var stb = document.getElementById("stb"); var arr = [3, 1, 2, 5, 4, 8, 9, 7, 6]; demo.innerHTML = arr; bts.onclick = function() { bubbleSort(function(a, b) { return b - a; }); } stb.onclick = function() { bubbleSort(function(a, b) { return a - b; }); } function bubbleSort(fn) { var arr = [3, 1, 2, 5, 4, 8, 9, 7, 6]; var strArr = []; show.innerHTML = ""; strArr.push("<br/>"); var inner = 0; var outer = 0; for (var i = 0; i < arr.length - 1; i++) { var sorted = true; strArr.push("第" + (i + 1) + "趟"); for (var j = 0; j < arr.length - 1 - i; j++) { if (fn(arr[j], arr[j + 1]) > 0) { var tmp = arr[j]; arr[j] = arr[j + 1]; arr[j + 1] = tmp; sorted = false; } inner++; } strArr.push(arr.toString()); strArr.push("共" + j + "次" + "<br/>"); outer++; if (sorted) { break; } } strArr.push("外循環" + outer + "次"); strArr.push("內循環" + inner + "次"); show.innerHTML = strArr.join(" "); } </script> </body> </html>
第三趟已經排好了,爲何還要排第四趟呢? 緣由很簡單,由於第三趟的時候js是不知道你已經排好的,只有第四趟的時候,js再進行換位比較的時候,發現位置都不須要換了,說明排好了。