1. 程式人生 > >JS(一)基本知識

JS(一)基本知識

一 JS的匯入以及常用的輸出方式

1、匯入方式

(1)行內匯入JS(不推薦使用)
<body>
    <div onclick="alert('hello')">HELLO WORLD</div>  /*當點選HELLO WORLD文字時,會彈出彈窗,顯示hello*/
</body>
</html>
捕獲.PNG

注意:慎重使用行內匯入JS,因為不安全,所以不建議使用行內匯入JS。

(2)內嵌式匯入JS
<script type="text/javascript">
        alert('hello')    /*彈窗自動彈出hello*/
    </script>
(3)外鏈式匯入JS
<script src="1.js">  </script> /*從外部檔案鏈入*/

注意:內嵌匯入和外鏈匯入不能合併在一起,如果當前是外鏈匯入的,那麼在<script>指令碼塊中編寫的所有程式碼都不會被執行。

2、

  • 真實專案中,我們一般都會把CSS放在<body>的上面,把JS放在<body>的末尾(約定俗成的規範)
  • <body>中編寫的都是HTML標籤,JS很多時候需要操作這些元素,首先我們要保證元素載入成功,才可以在JS中獲取到(所以JS要放在結構之後載入,所以把JS放在<body>末尾)

如果把JS放在HTML標籤前面了,如何等到結構載入完成再載入JS?
JS:window.onload=function() {} 頁面中所有資原始檔都載入完成執行操作
JQ:$(document).ready(function() {} ) 頁面中的結構載入完成就會執行操作

3、 瀏覽器彈框

    <script>
        //JS中提供的瀏覽器彈框
//1、alert:在瀏覽器中彈出一個提示框(提供確定按鈕,點選確定彈框消失 alert( {name: 'zzh'} ); //“ [object object]” alert( [12,23] ); //“ 12,23“ alert( 1+1); //“2” //使用alert彈框提示資訊,提示的內容最後都會被轉換為字串輸出(呼叫了toString這個方法)
    <span class="hljs-comment">//2、confirm:在alert基礎上增加了讓使用者選擇性的操作(提供兩個按鈕:確定和取消)</span>
    <span class="hljs-comment">//當用戶點選確定按鈕的時候。我們接收到的結果是TRUE,點選的是取消按鈕我們接收到的結果是FALSE,此後我們可以根據接收的結果做不同的處理即可。</span>

    <span class="hljs-comment">//3、prompt:在confirm基礎上讓使用者輸入的效果</span>
    <span class="hljs-comment">//當用戶點選確定按鈕的時候,我們將會獲取到使用者輸入的內容,(如果使用者沒有輸入任何內容,獲取的結果是空字串),點選的是取消按鈕我們接收到的結果是null</span>
</span><span class="hljs-tag">&lt;/<span class="hljs-name">script</span>&gt;</span>

4、控制檯輸出

控制檯輸出:方便開發人員進行除錯的 (F12開啟瀏覽器的控制檯)
(1)console.log:在控制檯輸出,優勢是不會轉換資料型別,輸出什麼格式的資料都可以
(2)console.dir:比log輸出的更詳細一些
(3)console.table:把JSON資料展示成一個表格
(4)document.write:向頁面中列印輸出內容

二 JS中的變數/常量及資料型別

>ECMAScript(ES):規定了JS的一些基礎核心的知識(變數、資料型別、語法規範、操作語句等)
>DOM:document object model 文件物件模型,裡面提供了一些屬性和方法,可以讓我們操作頁面中的元素
>BOM:browser object model 瀏覽器物件模型,裡面提供了一些屬性和方法,可以讓我們操作瀏覽器

1、JS定義變數的方式

  • var 變數 = 值;(ES5) (ES6中定義變數使用let)
var num = 12;
var str = 'zzh';

2、JS定義常量的方式

  • const 常量 = 值;

3、JS中的命名規範

(1)JS中嚴格區分大小寫

var test = ‘zzh’;
var Test = 'sxz';     //test和Test是兩個不同的變數

(2)遵循國際命名規則-“駝峰命名法”
第一個單詞首字母小寫,其餘每一個有意義的單詞首字母大寫

var studentInfo = 'zzh';

(3)命名的時候可以使用 $ _ 數字 字母 ,但是數字不能作為名字的第一位

var $xxx;  //一般都是應用JQ獲取到的值
var _xxx;  //一般這樣的情況代表變數是一個全域性變數或者公用的變數

(4)JS中很多的詞都是有特殊含義的,我們把這些詞叫做關鍵字;現在沒有特殊含義,以後可能會作為關鍵詞的,我們叫做保留字,保留字和關鍵字都不可以隨便用來命名

4、JS中的資料型別

  • (1)基本資料型別(值型別)
    number:數字
    string:字串 //單雙引號包裹起來的都是字串,單雙引號沒有區別
    boolean:布林 //只有兩個值 true和false
    null:空物件指標
    undefined:未定義

  • (2)引用資料型別
    object物件資料型別 {name:'zzh',age:18} 、[12,23,34]
    function函式資料型別 function fn() { }
    object可分為 {}普通物件、[]陣列、/^$/正則......
    物件資料型別的作用:把描述同一個事物(同一個物件)的屬性和方法放在一個記憶體空間下,起到了分組的作用,這樣不同的事物之間的屬性即使屬性名相同,相互也不會發生衝突。
    我們把這種分組編寫程式碼的模式叫做“單例模式”。單例模式是一種專案開發中經常使用的模式,因為專案中我們可以使用單例模式來進行“模組化開發”。

檢測資料型別的四種方法:
typeof:檢測資料型別的運算子
instanceof:檢測某個例項是否屬於這個類
constructor:獲取當前例項的構造器
Object.prototype.toString.call(最常用、最難):獲取當前例項的所屬類資訊

(3)typeof:

  • 使用typeof檢測,返回結果是一個字串,字串中包含的內容證明了值是屬於什麼型別的。
  • 侷限性:
    1、typeof null不是‘null’而是‘object’,因為null雖然是單獨的一個數據型別,但是他原本意思是空物件指標,瀏覽器使用typeof檢測的時候會把他按照物件來檢測。
    2、使用typeof無法具體細分出到底是陣列還是正則,因為返回的結果都是‘object’。
    (4)布林 Boolean():
  • 把其他資料型別的值轉換為布林型別
  • 只有0 、NaN 、 空字串 、null 、undefined這五個資料值轉換為布林型別的false,其餘的都會變為true。
    (5)歎號!:
    JS中的歎號還有一個作用:“取反”,先把值轉換為布林型別,然後再去取反。
    (6)兩個歎號!!:
    在一個歎號取反的基礎上再取反,取兩次反相當於沒有做操作,但是卻已經把其他型別值轉換為布林型別了,和Boolean是相同的效果。
    (7)字串:
    在JS中單引號和雙引號包起來的都是字串。
    常用方法:charAt charCodeAt、
    substr substring slice、
    toUpperCase toLowerCase、
    indexOf lastIndexOf、
    split、
    replace
    (8)Number()方法
    把其他資料型別值轉換為number型別的值
Number('12') -> 12
Number('12px') -> NaN
在使用Number轉換的時候只要字串中出現任何一個非有效數字字元,最後的結果都是NaN 

Numbertrue) -> 1
Numberfalse) -> 0
Numbernull) -> 0
Numberundefined) -> NaN
Number([]) -> 0 把引用資料型別轉換為number,首先需要把引用資料型別轉換為字串(用到toString方法),再把字串轉換為number即可
Number([]) => [ ] -> ’ ’ ’ ’ -> 0
Number([12]) => [12] -> ‘12’ ‘12’ -> 12
Number([12,23]) => [12,23] -> ‘12,23’ ‘12,23’ -> NaN 因為12,23中出現了一個非有效數字字元
Number({name:‘zzh’}) -> NaN
Number({}) -> NaN

(9)數字number:
JS中多增加了一個number型別的資料:NaN
NaN: not a number ,不是一個數,但是屬於number型別
NaN == NaN :false ,NaN和任何其他值都不相等

isNaN() ;  用來檢測當前這個值是否是非有效數字,如果不是有效數字檢測的結果是true,反之是有效數字則為false

isNaN0) -> false
isNaN(NaN) -> true
isNaN(‘12’) ->false 當我們使用isNaN檢測值的時候,檢測的值不是number型別的,瀏覽器會預設的把值轉換為number型別,然後再去檢測
isNaN( [] ) -> false

(10)parseInt()
也是把其他資料型別值轉換為number,和Number方法在處理字串的時候有區別

Number('12px') -> NaN
parseInt('12px') -> 12
parseInt('12px13') -> 12
提取規則:從左到右依次查詢有效數字字元,直到遇見非有效數字字元為止(不管後面是否還有數字,都不找了),把找到的轉換為數字。
parseInt('px12') -> NaN

(11)parseFloat()
在parseInt的基礎上可以識別小數點

parseInt('12.5px') -> 12
parseFloat('12.5px') -> 12.5

(12)null和undefined
空字串和null的區別:
空字串相對於null來說開闢了記憶體,消耗了一點點的效能,就像是種樹,空字串屬於挖了個坑,但是沒有種任何東西,null是連坑都沒挖。
null和undefined的區別:
null一般都是暫時沒有,預期中以後會有的(可能以後也沒有達到預期),在JS中,null一般都是手動先賦值為null,後期我們在給其賦具體值。
undefined:完全沒在預料之內的。
(13)物件資料型別object

var obj = {name:'zzh',age:18} ;
每一個物件都是有零到多組 屬性名( key值):屬性值(value值)組成的,或者說有多組鍵值對組成的,每一組鍵值對中間用逗號分隔,物件的屬性名是字串或者數字格式的,儲存的屬性值可以是任何的資料型別。
var obj = {name:'zzh',age:18} ;

獲取某個屬性名對應的屬性值:
1、物件名.屬性名 :忽略了屬性名的單雙引號
2、物件名[屬性名] :不能忽略單雙引號
obj.name 、obj['name']
如果屬性名是數字:
obj.0語法不支援 obj[0] 或者 obj['0'] 兩種都可以支援
如果操作的屬性名在物件中不存在,獲取的結果是undefined。
設定/修改:obj.sex = 'man' ; obj['age'] = 9;

  • 刪除:
    1、假刪除:讓其屬性值賦值為null,但是屬性還在物件中 ,obj.sex = null ;
    2、真刪除:把整個屬性都在物件中暴力移除 delete obj.sex 。

三 基本資料型別和引用資料型別的區別

JS是執行在瀏覽器(核心、引擎)中的,瀏覽器會為JS提供賴以生存的環境(提供給JS程式碼執行的環境),稱之為全域性作用域。
基本資料型別:是按值操作的,基本資料型別在賦值的時候,是直接的把值賦給變數既可。
引用資料型別:是按照空間地址(引用地址)來操作的。

var n={name:'zzh'};
1、先建立一個變數n;
2、瀏覽器首先會開闢一個新的儲存空間(記憶體空間),目的是把物件中需要儲存的內容(鍵值對)分別的儲存在這個空間中,為了方便後期找到這個空間,瀏覽器給空間設定一個地址(16進位制)。
3、把空間的地址賦值給了變數

四 函式資料型別

函式是引用資料型別,所以函式資料型別也是按照引用地址來操作的。

function 函式名() {
   函式體:實現某一個功能的具體JS程式碼
}
  • 建立函式時,也會開闢一個新的記憶體空間,空間中儲存的是函式體中的程式碼,但是此時的程式碼都是字串裡的字元而已。函式只建立不執行沒有意義,因為空間中儲存的都是毫無意義的字串。
  • 函式執行時,瀏覽器會建立一個供函式中程式碼執行的私有環境,稱之為私有作用域。

五 for in 迴圈

1、for in:用來遍歷(迴圈)物件鍵值對的。
2、物件中有多少組鍵值對,for in迴圈就遍歷多少次(不一定)。
3、每一次迴圈KEY這個變數儲存的都是當前迴圈這組鍵值對的屬性名。
4、KEY儲存的值都是字串格式的(不管屬性名是否為數字)。
5、在for in迴圈遍歷的時候,大部分瀏覽器都是先把物件中的鍵值對進行排序(把數字屬性名的排在前面,並且排列的時候按照數字由小到大排列)(小數不算做數字,算作字母,),其次在把非數字的屬性名按照之前編寫的順序排列,迴圈的時候按照重新排列的順序依次遍歷。

console.log(obj[key]); 
每一次迴圈把key變數儲存的值(當前遍歷的屬性名)獲取到放在中括號中,獲取obj中對應屬性的屬性值
obj['key']  obj.key  : 都代表同一個意思,屬性名是key
obj[key]  :屬性名不是key,而是key變數儲存的值

六 資料型別轉換

把其他資料型別轉換為number型別
1、isNaN、Number、parseInt、parseFloat
2、在進行加減乘除數學運算的時候

' ' -> 0   '12' -> 12   '12px'->12/NaN    null -> 0  undefined -> NaN
{}  /^$/  function() {}  -> NaN

引用資料型別轉換為數字
通過toString方法把陣列轉換為字串,然後在呼叫Number把字串轉換為數字

[]  ->  ' '  ->  0
[12] -> '12' -> 12
[12,23] -> '12,23' -> NaN

JS中的數學運算
加+ 減- 乘* 除/
1、除了加法有特殊性,其餘的運算子都是數學運算,也就是遇到非數字型別,需要把其轉換為number在進行運算。
2、加法的特殊性:在遇到字串的時候,+不是數學運算,而是字串拼接,只要不遇到字串就是數學運算。
3、字串拼接:是把其他的值轉換為字串然後再拼接。其他資料型別的toString是直接的把值用單雙引號包起來即可,只有物件有特殊性,物件.toString() === ' [Object Object]'

1- '1' = 0
10 * null = 0 
10 / undefined = NaN
10 * [10] = 100
1 + ‘1’ = ‘11null + ‘1’ = ‘null1’

將其他型別轉換為布林型別
Boolean 、!、 !!
1、在條件判斷的時候,也是轉換為布林型別,然後驗證條件的真假。
2、只有0、NaN、空字串、null、undefined五個轉換為false,其餘的都是轉換為true。

if(box) {
}
首先是把box變數儲存的值獲取到,轉換為布林型別,如果為true條件成立,反之不成立。

在使用==進行比較的時候
在使用==進行比較的時候,如果左右兩邊資料型別不相同,瀏覽器會預設轉換為相同的型別,然後在比較(===不會這樣操作)。

1、物件和物件:比較的是空間地址,不是相同的空間,結果肯定是false
[] == [] -> false
var a = { } ;
var b = a ;
a == b ;  ->true
2、物件和數字:把物件轉換為數字
[] ==  0 ; -> true 
{} == NaN ; -> false     // NaN和自己不相等和其他任何值都不相等
3、物件和字串:把兩邊都轉換為數字在進行比較
[] == ' ' ;    ->true 
4、物件和布林:把兩邊都轉換為數字在進行比較
[] == true  -> false
[] == false -> true
![] == false -> true   因為![]是把陣列變為布林在取反 所有false == false -> true

5、字串和數字:字串轉換為數字
6、字串和布林:都轉為數字
7、布林和數字:布林轉換為數字
規律:兩個等於號比較,左右兩邊資料值的型別不一樣,瀏覽器會把兩邊的型別都轉換為數字然後在比較。但是null和undefined除外。

null == undefined -> true 
null === undefined ->false 
null == 0 ->false 
null以及undefined和其他任何值都不相等

七 Math中常用的方法

數學函式:但是他是物件資料型別的。
Math物件中給我們提供了很多常用的運算元字的方法。
1、abs :
Math.abs :取絕對值
2、ceil && floor:
Math.ceil:向上取整
Math.floor:向下取整

Math.ceil(12.1) -> 13 
Math.ceil(-12.1) -> -12
Math.floor(12.9) -> 12 
Math.floor(-12.9) -> -13

3、round:
Math.round:四捨五入

Math.round(12.5) -> 13  正數中5包含在向上
Math.round(-12.5) -> -12   負數中5包含在向下
Math.round(-12.51) -> -13

4、random:
Math.random : 獲取 (0,1)之間的隨機小數
獲取[0,10]之間的隨機整數
Math.round(Math.random()10)
獲取[3,15]之間的隨機整數
Math.round(Math.random()
12+3)
獲取[n,m]之間的隨機整數
Math.round(Math.random()*(m-n)+n)
5、max && min:
Math.max:獲取一組值中的最大值
Math.min:獲取一組值中的最小值
6、PI :
Math.PI :獲取圓周率π
7、pow && sqrt :
Math.pow : 獲取一個值的多少次冪
Math.sqrt : 開平方

八 字串中常用的方法

在JS中用單雙引號包裹起來的都是字串。
1、字串就是由零到多個字元組成的。第一個字元索引為0,第二個字元索引為1...以數字作為索引,從零開始的。
2、有一個叫做length的屬性,儲存的是當前字串中字元的個數(字串的長度)。如果指定的索引不存在,則獲取的結果是undefined。
字串操作方法:

  • 1、charAt && charCodeAt
    str.charAt(索引):返回指定索引位置的字元,和str[索引]的區別在於,當指定的索引不存在的時候,中括號的方式獲取的是undefined,而charAt獲取的是空字串。
    str.charCodeAt(索引):在charAt基礎上,把獲取的字元變為Unicode編碼值(對於ASCII碼錶),48-57是0-9 , 65-90是A-Z , 97-122是a-z
    String,fromCharCode(十進位制的Unicode值):把值按照ASCII碼錶中的資訊,轉化為原有的字元,和charCodeAt正好對應。
  • 2、substr && substring && slice
    實現字串擷取的三個方法:
    str.substr(n,m):從索引n開始,擷取m個字元。
    str.substring(n,m):從索引n開始,擷取到索引為m處(不包含m),把找到的部分擷取。
    str.slice(n,m):和substring語法一樣,區別在於slice支援以負數做索引。當索引為負數的時候,瀏覽器在處理的時候,是用字串的總長度加上負數索引,然後按照正數處理操作。

1、如果只傳遞了n,(str.substr(n)/str.substring(n)),相當於從索引n開始一直擷取到字串的末尾。
2、如果傳遞的索引超出最大限制,也是把能擷取的部分擷取掉即可。
3、如果一個引數都不傳遞,相當於把整個字串都擷取(字串的克隆)。

  • 3、toUpperCase && toLowerCase
    str.toUpperCase:把字母全部大寫
    str.toLowerCase:把字母全部大寫
  • 4、indexOf && lastIndexOf
    str.indexOf:獲取當前字元在字串中第一次出現位置的索引。
    str.lastIndexOf:獲取的是最後一次出現位置的索引。

如果當前字元在字串中沒有出現過,結果是-1,我們根據這個規律可以驗證一下當前字串中是否包含某個字元。

  • 5、split
    str.split:按照某一個字元把字串拆分成陣列中的某一項,和陣列中的join方法是對應的。
  • 6、replace
    str.replace:實現字元的替換。執行一次replace只能替換一次,如果有好幾個都需要替換,在不使用正則的情況下我們需要執行很多次replace。有些需求即使執行很多次replace也實現不了,此時需要使用正則處理,真實專案中replace一般都是和正則搭配使用的。
  • trim && trimLeft && trimRight
    str.trimLeft:去除字串開始的空格。
    str.trimRight:去除字串結尾的空格。
    str.trim:去除字串首尾的空格。

九 DOM基礎

DOM:document object model文件物件模型,提供一些屬性和方法可以讓我們去操作DOM元素。
1、獲取DOM元素的方法

  • document.getElementById 一個元素
  • [context].getElementsByTagName 元素集合
  • [context].getElementsByClassName 元素集合
  • document.getElementsByName 節點集合
  • document.documentElement 獲取整個HTML物件
  • document.body 獲取整個body物件
  • document.head 獲取整個head物件
  • [context].querySelector 一個元素物件
  • [context].querySelectorAll 獲取元素集合
    getElementById
    此方法的上下文只能是document。一個HTML頁面中元素的ID理論上是不能重複的。
  • 1、如果頁面中的ID重複了,我們獲取的結果是第一個ID對應的元素物件。
  • 2、在IE7及更低版本的瀏覽器中,會把表單元素的name值當做 ID來識別使用(專案中儘量不要讓表單的name和其他元素的ID相同)。
  • 3、如果我們把JS放在結構的下面,我們可以直接使用ID值來獲取這個元素(不需要通過getElementById獲取)而且這種方式會把頁面中所有ID是它的元素都獲取到(元素物件/元素集合)。 這種方式不推薦。
    getElementsByTagName
  • 1、上下文是可以自己來指定。
  • 2、獲取到的結果是一個元素集合(類陣列集合)。獲取的結果是集合,哪怕集合中只有一項,我們想要操作這一項(元素物件),需要先從集合中獲取出來,然後再操作。
  • 3、在指定的上下文中,獲取所有子子孫孫元素中標籤名叫做這個的(後代篩選)
    getElementsByClassName
  • 1、上下文也可以隨意指定,獲取的結果也是一個元素集合(類陣列集合)
  • 2、真實專案中我們經常會通過樣式類名來獲取元素,但是getElementsByClassName 這個方法在IE6-8是不相容的。
    getElementsByName
  • 1、通過元素的NAME屬性值獲取一組元素(類陣列:節點結合NodeList)
  • 2、他的上下文也只能是document
  • 3、IE瀏覽器只能識別表單元素的name屬性值,所以這個方法一般都是用來操作表單元素的。
    documentdocumentElement / documentbody
    獲取HTML或者BODY(一個元素物件)
    querySelector / querySelectorAll
  • 1、在IE6-8不相容,而且也沒什麼特別好的方法處理他的相容,所以這兩個方法一般多用於移動端開發使用。
    querySelector:獲取一個元素物件
    querySelectorAll:獲取一個元素組合

2、DOM節點
node:節點,瀏覽器認為在一個HTML頁面中的所有內容都是節點(包括標籤、註釋、文字文字等)

  • 元素節點:HTML標籤
  • 文字節點:文字內容(高版本瀏覽器會把空格和換行也當做文字節點)
  • 註釋節點:註釋內容
  • document文件節點
  • ......
    元素節點
    nodeType:1
    nodeName:大寫標籤名(在部分瀏覽器的怪異模式下,我們寫的標籤名是小寫,他獲取的就是小寫)
    nodeValue:null
    [curEle].tagName:獲取當前元素的標籤名(獲取的標籤名一般都是大寫)
    文字節點
    nodeType:3
    nodeName:#text
    nodeValue:文字內容
    註釋節點
    nodeType:8
    nodeName:#comment
    nodeValue:註釋內容
    文件節點
    nodeType:9
    nodeName:#document
    nodeValue:null
    3、DOM節點關係屬性
    節點是用來描述頁面中每一部分之間關係的,只要可以獲取頁面中的一個節點,那麼就可以通過相關的屬性和方法獲取頁面中所有的節點。
    childNodes
  • 1、獲取當前元素所有的子節點(節點集合:類陣列)。注:不僅僅是元素子節點,文字、註釋等都會包含在內,子節點說明只是在兒子輩分中查詢;
    children
  • 1、獲取所有的元素子節點(元素集合)
  • 2、在IE6-8下獲取的結果和標準瀏覽器中有區別(IE6-8中會把註釋節點當做元素節點獲取到)
    parentNode
  • 1、獲取當前元素的父節點(元素物件)
    previousSibling / nextSibling
  • 1、previousSibling :獲取當前節點的上一個哥哥節點(不一定是元素節點也可能是文字或者註釋)
  • 2、nextSibling:獲取當前節點的下一個弟弟節點
    previousElementSibling / nextElementSibling
  • 1、previousElementSibling :獲取當前節點的上一個哥哥元素節點
  • 2、 nextElementSibling :獲取當前節點的下一個弟弟元素節點
    IE6-8下不相容
    firstChild / lastChild
  • 1、firstChild :當前元素所有子節點中的第一個(也不一定是元素節點,可能是文字和註釋)
  • 2、lastChild :當前元素所有子節點中的最後一個

十 DOM的增刪改

真實專案中,我們偶爾會在JS中動態建立一些HTML標籤,然後把其增加到頁面中。
documentcreateElement:在JS中動態建立一個HTML標籤
appendChild

  • 1、容器.appendChild(新元素)
  • 2、把當前建立的新元素新增到容器的末尾位置
    inserBefore
  • 1、容器.inserBefore(新元素,老元素)
  • 2、在當前容器中,把新建立的元素增加到老元素之前
    真實專案中很多需求都是通過動態建立元素來完成的,其中有一個需求:解析一個URL地址每一部分的資訊(包含問號傳遞的引數值)
  • 1、純字串拆分擷取
  • 2、編寫強大的正則,捕獲到需要的結果
  • 3、通過動態建立一個a標籤,利用a標籤的一些內建屬性來分別獲取每一部分的內容
    QQ圖片20180731172808.png
    QQ圖片20180731173924.png
    removeChild
  • 1、容器.removeChild(元素)
  • 2、在當前容器中把某一個元素移除掉
    replaceChild
  • 1、容器.replaceChild(新元素,老元素)
  • 2、在當前容器中,拿新元素替換老元素
    cloneNode
  • 1、元素.cloneNode(false/true)
  • 2、把原有的元素克隆一份一模一樣的,false:只克隆當前元素本身,true:深度克隆,把當前元素本身以及元素的所有後代都進行克隆
    set/get/removeAttribute
    給當前元素設定/獲取/移除屬性的(一般操作的都是他的自定義屬性)
box.setAttribute('myIndex',0); 設定
box.getAttribute(myIndex);   獲取
box.removeAttribute(myIndex);  移除

使用xxx.index=0和xxx.setAttribute('index',0)這兩種設定自定義屬性的區別?
xxx.index :是把當前操作的元素當做一個普通物件,為其設定一個屬性名(和頁面中的HTML標籤沒關係)
xxx.setAttribute:把元素當做特殊的元素物件來處理,設定的自定義屬性是和頁面結構中的DOM元素對映在一起的。

JS中獲取的元素物件,可以理解為兩種角色:

  • 與頁面HTML結構無關的普通物件
  • 與頁面HTML結構存在對映關係的元素物件
    元素物件中的內建屬性,大部分都和頁面的標籤存在對映關係:
    1、xxx.style.backgroundColor = 'xxx'此時不僅把JS中物件對應的屬性值改變了,而且也會對映到頁面的HTML標籤上(標籤中有一個style行內樣式、元素的樣式改變了)
    2、xxx.className = 'xxx':此時不僅是把JS物件中的屬性值改了,而且頁面中的標籤增加了class樣式類(可以看見的)
    3、元素物件中的自定義屬性xxx.index=0僅僅是把JS物件中增加了一個屬性名(自定義的),和頁面中的HTML沒啥關係(在結構上看不見)
    4、xxx.setSttribute:通過這種方式設定的自定義屬性和之前提到的內建屬性差不多,都是和HTML結構存在對映關係的(設定的自定義屬性可以呈現在結構上)

十一 Date日期操作

Date是日期類,通過它可以對時間進行處理。
獲取當前客戶端本機時間:獲取的結果是一個日期格式的物件。

var time = new Date() ;
當前獲取的時間不能作為重要的參考依據。
new Date();
->  Wed Aug 01 2018 09:21:53 GMT+0800 (中國標準時間)
typeof new Date();
->  "object"
  • time.getFullYear() 獲取四位整數年
  • time.getMonth() 獲取的月是0-11,代表1-12月
  • time.getDate() 獲取日
  • time.getDay() 獲取星期是0-6,代表週日-週六
  • time.getHours() 獲取小時
  • time.getMinutes() 獲取分鐘
  • time.getSeconds() 獲取秒
  • time.getMilliseconds() 獲取毫秒
  • time.getTime() 獲取當前日期距離‘1970-01-01 00:00:00’ 的毫秒差
var time = new Date('2017-10-21'); 
當new Date中傳遞一個時間格式的字串,相當於把這個字串轉換為標準的時間物件格式(轉換完成後,就可以調取上面的方法了)

十二 陣列的基礎結構

  • 陣列是物件資料型別的。 typeof [] = 'object' 。
  • 陣列也有屬性名,只不過是數字,我們把數字屬性名稱之為他的索引:陣列是以數字作為索引,索引從零開始,有一個length屬性代表陣列的長度。
  • 類陣列:類似於陣列,但是不是陣列。
    (1)、通過getElementsByTagName獲取的元素集合是類陣列。
    (2)、函式中的實參集合arguments也是類陣列。

十三 陣列中的常用方法

可以通過console.dir(Array.prototype)看陣列的常用方法。
實現陣列的增加、修改、刪除:

var ary = [12,23,34] ;

增加
1、push :向陣列的末尾追加新內容。

  • 引數:一到多個,並且任何資料型別都可以追加。
  • 返回值:新增後陣列的長度。
  • 原有陣列改變了。
    2、unshift:向陣列開頭追加新內容。
  • 引數:需要追加的內容,可以是多個任何資料型別的值。
  • 返回值:新增後陣列的長度。
  • 原有陣列改變了。
    3、把陣列當做一個普通的物件,使用物件鍵值對的操作,給其設定新的屬性(索引)。
ary[ary.length] = xxx ; 
向陣列的末尾追加了新內容

刪除
1、pop:刪除陣列最後一項。

  • 引數:無
  • 返回值:被刪除的那一項的內容。
  • 原有陣列變了。
    2、shift:刪除陣列第一項。
  • 引數:無
  • 返回值:被刪除的那一項的內容。
  • 原有陣列變了。
  • 使用shift刪除第一項之後,後面每一項的索引都要向前進一位,導致後面項的索引發生改變。
    3、delete:把陣列當做普通物件操作。(不推薦使用)
delete ary[索引];
  • 當前項被刪除後,原有陣列的其他項的索引不會改變,當前陣列的length也不會改變。
  • ary.length-- ; 刪除陣列最後一項。
    splice
    1、splice實現刪除:
    splice(n,m) :從索引n開始刪除m個(不寫m是刪除到陣列的末尾,不寫n和m,一項都不刪除,返回的是一個新的空陣列)
  • 返回值:被刪除的內容(以一個新陣列儲存)。
  • 原有陣列改變了。
    2、splice實現修改
    splice(n,m,x):在原有刪除的基礎上,用x代替刪除的內容。
    3、splice實現增加
    splice(n,0,x):在修改的基礎上,我們一項都不刪除,把x插入到索引n的前面。
ary.splice(0,0,x)  向陣列開頭追加新的內容
ary.splice(ary.length,0,x)  向陣列末尾追加新的內容

陣列查詢
1、slice:陣列的查詢。

  • 引數:slice(n,m)從索引n開始找到索引為m處(不包含m)。
  • 返回值:把找到的部分以一個新陣列返回。
  • 原有陣列不變。
  • slice(n):從索引n開始找到末尾
    slice(n)和slice() :陣列克隆,克隆一份和原來陣列一模一樣的新陣列。
  • slice支援負數索引,如果傳遞的索引為負數,瀏覽器解析的時候是按照 總長度+負數索引 來處理的。
    將兩個陣列進行拼接
    concat:將多個數組拼接在一起。
  • 引數:要拼接的內容(把內容放在原陣列的後面),可以是一個數組,也可以是一些資料值。
  • 返回值:拼接後的新陣列。
  • 原有陣列沒有改變。
    concat()什麼都沒有拼接,相當於把原有陣列克隆了一份一模一樣的新陣列出來。
    把陣列轉換為字串
    1、toString:實現把陣列轉換為字串(轉換後的字串以逗號分隔每一項)。
  • 引數:無
  • 返回值:轉換的字串。
  • 原有陣列不改變。
    2、join:把陣列按照指定的分隔符轉換為字串,和字串中的split相對應。
  • 引數:指定的連線符。
  • 返回值: 轉換後的字串。
  • 原有陣列不改變。


    QQ圖片20180801113451.png

已知陣列中的每一項都是數字,想實現陣列求和,如何實現?

1、迴圈實現
var total = null ;
for(var i=0;i<ary.length;i++) {
  total+=ary[i];
}
2、利用join
var total = eval(ary.join('+'))  
eval:把字串變為JS表示式執行。

實現陣列中每一項的排序和排列
1、reverse:把陣列中的每一項倒過來排列。

  • 引數:無
  • 返回值:排序後的陣列。
  • 原有陣列改變。
    2、sort:實現陣列的排序。
  • 引數:無或者回調函式
  • 返回值:排序後的陣列
  • 原有陣列改變。

1、不傳遞引數的情況下:可以給10以內的數字進行升序排列,但是超過10的就無法處理了(多位數只識別第一位)。
2、傳遞引數:ary.sort(function(a,b) { return a-b; 升序 return b-a; 降序 } );

驗證陣列中是否包含某一項
indexOf / lastIndexOf :獲取當前項在陣列中第一次或者最後一次出現位置的索引。

  • 陣列中的這兩個方法在IE6-8下不相容
  • 字串中的這兩個方法相容所有的瀏覽器
  • 如果當前陣列中並沒有這一項,返回的索引是-1,我們根據這一點可以驗證陣列中是否包含這一項。
    遍歷陣列中的每一項的方法
    以下方法在IE6-8中都不相容:
  • 1、forEach:遍歷陣列中的每一項
ary.forEach(function(value,index)  {
    陣列中有多少項,當前回撥函式執行多少次,每一次傳遞進來的value就是當前遍歷陣列這一項的值,index就是遍歷這一項的索引
} );
  • 2、map:遍歷陣列中的每一項,在forEach的基礎上,可以修改每一項的值。
ary.map(function(value,index)  {
    陣列中有多少項,當前回撥函式執行多少次,每一次傳遞進來的value就是當前遍歷陣列這一項的值,index就是遍歷這一項的索引。
   return xxx;  return後面返回的結果就是把當前遍歷的這一項修改為xxx
} );
  • filter、find、reduce、every......
    陣列去重
    1、雙for迴圈遍歷法:遍歷陣列中的每一項,拿每一項和他後面的項依次比較,如果相同了,則把相同的這一項在原來陣列中刪除即可。
    1.png
    2.png
    3.png
    2、利用indexOf來驗證當前陣列中是否包含某一項,包含把當前項刪除掉。
    4.png
    3、物件去重法:遍歷陣列每一項,把每一項作為新物件的屬性名和屬性值儲存起來。在每一次向物件中儲存之前,首先看一下原有物件中是否包含了這個屬性,用typeof obj[xxx] = 'undefined' 說明當前物件中沒有xxx這個屬性,如果已經存在這個屬性說明陣列中的當前項是重複的,所以在原有陣列中刪除這一項,不在向物件中儲存這個結果,如果不存在,則把當前項作為物件的屬性名和屬性值儲存進去即可。
    5.png
    6.png
    陣列排序
    1、氣泡排序
  • 原理:讓陣列中的當前項和後一項進行比較,如果當前項大於後一項,我們讓兩者交換位置(小->大)。具體比較的論數:ary.length-1。
    7.png
    2、遞迴:函式自己呼叫自己
    3、快速排序
function quick(ary) {
    if (ary.length <= 1) {
        return ary;
    } 
    var centerIndex = Math.floor(ary.length/2),
        centerValue = ary.splice(centerIndex,1)[0];
    var aryLeft = [],
        aryRight = [];
    for (var i = 0; i < ary.length; i++) {
        var cur = ary[i];
        cur < centerValue ? aryLeft.push(cur) : aryRight.push(cur);
    }
    return quick(aryLeft).concat(centerValue,quick(aryRight));
}

4、插入排序


function insert(ary) {
    var handAry = [];
    handAry.push(ary[0]);
    for (var i = 1; i < ary.length; i++) {
        var item = ary[i];
        for (var j = handAry.length-1; j >= 0; j--) {
            if (item > handAry[j]) {
                handAry.splice(j+1, 0, item);
                break;
            }
            if (j===0) {
                handAry.unshift(item);
            }
        }
    }
    return handAry;
}