JavaScript 知識點

本文是從簡書複製的, markdown語法可能有些出入, 想看"正版"和更多內容請關注 簡書: 小賢筆記css

JS基礎

  • 頁面由三部分組成:
    • html:超文本標記語言,負責頁面結構
    • css:層疊樣式表,負責頁面樣式
    • js:輕量級的腳本語言,負責頁面的動效和數據交互
      小總結:結構,樣式和行爲,三者相分離
    • 在html頁面中寫結構
    • 經過 link標籤的href屬性,引入css樣式
    • 經過script標籤的src屬性,引入js腳本
  • css引入頁面的方式有三種
    • 行內<div style="width:200px;height:300px;"></div>
    • 內嵌:在header裏面寫一個<style>選擇器{key:value}</style>
    • 外鏈:在header裏面寫一個<link rel="stylesheet" href="css/index.css"/>
  • JS引入頁面的方式,同CSS類似
    • 內嵌:在開發過程當中,建議把script放在body底部;若是非要把script標籤對,放在head裏面的話;須要加window.onload
    window.onload=function(){
        document.body.innerHTML='XXXXXX';
    }
    • 行內:<div onclick="xxxx" onmouseover="xxxx"></div>
    • 外鏈:<script src="01.js"></script>
      注意:若是script做爲JS的外鏈,必定不要在兩個script標籤中寫代碼,寫了也沒用
  • 屬性和方法的區別:屬性沒括號,方法有括號
  • 字符串和變量的區別:字符串有引號,變量沒引號
    • 字符串通常用單引號;爲了元素身跟上的屬性值區分開來;屬性值通常是""
    • 變量,就是別名;var str; 告訴瀏覽器,定義了str這麼一個變量
    • 若是沒有定義變量,xxx is not defined
  • JS常見的輸出方式7種
    • alert('') ; 顯示帶有一條指定消息和一個 OK 按鈕的警告框
    • confirm('肯定要刪除?'); 他有兩個返回值:true 真, false假
    • console.log(''); 能夠在控制檯打印出咱們想要打印的內容
    • console.dir(); 打印出對象身上的屬性和方法
    • document.write() 向文檔寫入 HTML 表達式或 JavaScript 代碼
      若是遇到window.onload會清空頁面
    • 元素.innerHTML=xxxx 設置或返回表格行的開始和結束標籤之間的 HTML
    • console.table(); 能夠把數組和對象,以表格的形式打印出來
    var ary2=[
        {
            name:'a',
            age:1,
            sex:'gril'
        },
        {
            name:'王b',
            age:2,
            sex:'boy'
        }
    ];
    console.table(ary2);
  • chrome控制檯
    • Elements:用來調試html+css的
    • console:用來調試JS的
    • sources:能夠拿到該網站相關的資源:images ,html ,css, js

體驗JS編程思想

  • 需求:鼠標移入div1的時候,div2顯示;鼠標移出div1的時候,div2隱藏
  • 實現思路:
    1. 高度:div2的高度爲0; 移入div1後高度爲100;移出div1時div2高度0;
    2. display:block顯示,none,隱藏;
    3. 透明度:rgba(); opacity();
    4. 定位:left和top;
    5. margin:margin-left和 margin-top;
    6. overflow:hidden和visible;
  • JS獲取元素的方式:
    • document.getElementById('id名字');
      由於id是惟一的,因此拿到的是一個元素
    • document.getElementsByTagName('標籤名');
      標籤名拿到的是一個元素集合;即便只有一個元素,也是個集合
      想要取到其中的一個:aDiv[0] aDiv[2]
  • JS中的數據類型
    • 基本數據類型:
      1. 字符串string
      2. 數字 number
      3. 布爾值 boolean
      4. undefined 如今沒有,之後也沒有
      5. null 空對象,如今沒有,之後會有
    • 引用數據類型
      1. 對象數據類型
        • 數組
        • 正則
        • 對象{}
      2. 函數數據類型
        function 函數名(){};
  • 數據類型檢測的方式
    1. typeof 能夠檢測基本數據類型(全部通過typeof的都是字符串),可是對於對象數據類型,檢測出來的都是object,沒法知道具體屬於哪一種對象
    2. 對象 instanceof 類; 好比ary instanceof Array 判斷這個實例是否屬於某個類
    3. 對象.constructor: 好比ary.constructor能夠打印出對象所屬的類
    4. Object.prototype.toString.call(ary); 出來的結果 '[object Array]'
  • 基本數據類型和引用數據類型的區別:
    • 基本數據類型:是對值的操做
    • 引用數據類型:是對地址的操做
  • 操做屬性用的是"." oDiv.style.display='block'
  • 其餘數據類型轉爲number數據類型
    • 強制轉換
      • Number()
      • parseInt()
      • parseFloat()
    • 一個嚴格轉換
      • Number()
    • 兩個非嚴格轉化
      • parseInt() 只能轉化爲整數
      • parseFloat() 能夠保留小數
    若是轉換失敗的話,返回的結果是NaN:not a number 不是數字;可是NaN是number數據類型
  • 關於NaN:
    • NaN是number數據類型
    • isNaN() 判斷是否爲非有效數字; 非有效數字:true; 有效數字:false
  • 循環由4部分組成:
    • 1)定義 2)條件 3)語句 4)自增
  • 常見的循環方式:
    • for() :類數組arguments,htmlCollection,數組[],字符串
    • for in():普通對象{}
    • while(){}和for循環的區別和聯繫
      • 用while()循環也能夠實現for循環的四步
      • for循環通常用在循環次數固定; while()循環次數不固定
    • do...while() 無論條件是否成立,都會先執行一次
  • 函數由兩部分組成:
    • 函數定義3階段
      • 開闢一個內存空間
      • 把函數體內全部的JS代碼,做爲字符串存在這個空間中
      • 把空間地址賦值給函數名
    • 函數調用2階段
      • 當函數被調用的時候,會造成一個私有做用域
      • 把內存中的字符串做爲JS代碼來執行
        只定義不調用,函數不會執行
  • 閉包
    • 定義:
      • 當函數被調用的時候會造成一個私有做用域,保護裏面的變量不受外界的干擾,函數的這種保護機制叫作閉包
      • 閉包就是在提供了一個在外部訪問另外一個函數內部局部變量的方式
        ```
        var add = (function(){
        var count = 0;//外部訪問的計數器,局部變量.
        var fun = function(){
        return ++count;
        }
        return fun;
        })();
      //還能夠這樣寫
      var add2 = (function(){
      var count = 0;//外部訪問的計數器,局部變量.
      function plus(){
      return ++count;
      }
      return plus;
      })();

//還能夠這樣寫
var add3 = (function(){
var count = 0;//外部訪問的計數器,局部變量.
return function(){
return ++count;
}
})();html

+ 做用:
    + 避免全局變量名衝突
    + 在閉包中經過「window.xx」去修改全局變量;若是閉包中沒有定義此變量,也能夠直接修改變量去影響全局
    + 封裝(**閉包中封裝的方法在全局不能使用,只能經過「window.xx=封裝的函數名」把方法導出**)
    + 保存正確的i值
  + 特性:
    + 函數嵌套函數
    + 函數內部能夠引用外部的參數和變量
    + 參數和變量不會被收回
- 函數自帶的參數機制叫作arguments;
    + arguments:能拿到實參,而且以類數組的形式展示; 類數組也是對象,是對象都有屬性和方法
    + arguments.callee 拿到的是當前函數自己
    + arguments.length 拿到實參的長度/個數
- 數字經常使用的方法:
  + toFixed(要保存的位數)四捨五入的保存小數位數的
- 屬性和方法的區別:
    + 屬性沒括號,方法有括號;方法本質就是對函數的調用
    + 對象的屬性不會報錯,若是沒有,undefined; 方法不存在的話,會報錯
    + 屬性操做:. 和 []
        + 若是遇到變量,屬性名[變量名] **注:千萬不要給變量加引號**
        + 若是遇到屬性名爲數字,屬性名[1]
- 參數有兩種
    + 形參
        + 形參是私有變量
        + 若是定義了形參,但沒有賦值,拿到是undefined
        + 形參個數不肯定的話,用arguments來獲取參數
    + 函數自帶的參數機制arguments
        + arguments能夠打印出實參,以類數組的形式打印出來
        + 0,1,2能夠找到對應的屬性值
        + arguments.callee;表明當前函數自己
        + arguments.length;打印出實參的個數
- 函數返回值:
    + 函數返回值經過return;來返回
    + 獲取值的時候,須要返回值;設置值的時候,不須要返回值
- undefined出現的幾種狀況:
    + 屬性:當對象的屬性名不存在的話,拿到的是undefined
    + 參數:若是定義了形參,可是沒有傳實參,拿到的是undefined
    + 沒有設置函數返回值,即沒有寫return,拿到的函數返回值爲undefined
    + 寫了return但沒有賦值,拿到的函數返回值也是undefined
- NaN出現的幾種狀況:
  + 轉化失敗時
  + 無效運算時:null+undefined、undefined+undefined
- 運算符:
    - 算術運算符:+ - * / %
        + %(取餘):技巧-有幾種狀況就%幾
    - 比較運算符:
        **> , >= , < , <= , == ,!= ,===, !==**
    - 邏輯運算符:
        ! &&  || 
        + &&:兩邊都成立才能成立;可是也能夠用它作條件判斷; 9%3==0 && alert('能整除')
        + ||:通常成立就算成立;也能夠用它作條件判斷;9%3!=0 || alert('能整除')
    - 賦值運算符
        =; += ; -= ; *= ; /= ; %=
    - 運算符的優先級:算術》比較》邏輯》賦值
- 條件判斷:
    + if(條件1){....}else if(條件2){...}else{...}
    + 條件?語句1:語句2;
    + switch:用於多條件判斷
    ```
    switch(判斷的是可變的值){
        case a:
            語句1;
            break;
        case b:
            語句2;
            break;
        default:
            語句3;
            break;
    }
    ```
    **每一種case狀況其實都是至關於在用「===」進行比較**
    + 若是隻有一種條件,有三種寫法:
        + if(條件){語句1}
        + 條件?語句1:null;
        + if(條件) 語句1;
        + 9%3==0 && alert('能整除');
        + 9%3!=0 || alert('能整除');

## 數組經常使用的方法
##### 第一組:增長,刪除和替換
- push()
    + 做用:給數組末尾增長一項
    + 須要實參
    + 返回值:新數組的長度
    + 原數組發生改變
- pop()
    + 做用:刪除數組最後一項
    + 不須要參數
    + 返回值:被刪除的內容
    + 原數組發生改變
- unshift()
    + 做用:給數組開頭增長一項
    + 須要實參
    + 返回值:新數組的長度
    + 原數組發生改變
- shift()
    + 做用:刪除數組第一項
    + 不須要參數
    + 返回值:被刪除的內容
    + 原數組發生改變
- splice()
    1. 插入/增長 splice(index,0,要添加的內容)
        + 做用:在指定的索引前面,插入咱們要添加的內容
        + 參數:3個
        + 返回值:[]空數組,裏面沒有內容
        + 原數組發生改變
    2. 刪除 splice(index,m)
        + 做用:從指定的索引地方開始,刪除m個;若是第二個參數不寫,就從索引一直刪除到結尾
        + 參數:2個
        + 返回值:被刪除的內容,以一個新數組的形式返回
        + 原數組發生改變
    3. 替換 splice(index,m,n)
        + 做用:從指定的索引開始,刪除m個,並替換爲n的新內容
        + 參數:3個
        + 返回值:被刪除的內容,以一個新數組的形式返回
        + 原數組發生改變

##### 第二組:克隆和截取/查找
- slice(n,m)
    + 做用:從索引n開始,查找到索引m,包前不包後
    + 參數2個
    + 返回值:查找的內容
    + 原數組沒有發生改變
    + 克隆的功能:slice(0)/slice()
 **面試題:請找到數組中[n,m]項(答案:ary.slice(n-1,m))**
- concat()
    + 做用:數組拼接 / 克隆ary.concat()
    + 參數:不肯定,想拼接幾個數組,裏面參數就寫幾個數組名,也能夠寫成數組的形式
    + 返回值:拼接成的新數組
    + 原數組沒有發生改變

##### 第三組:數組轉字符串
- toString()
    + 做用:數組轉字符串
    + 參數:無
    + 返回值:以逗號分割的新字符串
    + 原數組沒有發生改變
- join(拼接形式) 拼接形式能夠爲任何運算符號
    + 做用:數組轉字符串
    + 參數:拼接形式能夠爲任何運算符號
    + 返回值:以指定的拼接形式分割的新字符串
    + 原數組沒有發生改變
    + 若是拼接形式爲+之類的,想實現運算,能夠用eval()
    + eval():把字符串做爲JS代碼來執行

##### 第四組:數組的翻轉和排序
- 數組翻轉 ary.reverse()
    + 功能:數組翻轉
    + 參數:沒有
    + 返回值:被翻轉後的數組
    + 原數組發生改變
- 數組排序

ary.sort(function(a,b){
return a-b;//從小到大排; return b-a 從大到小排
})前端

##### 第五組:數組經常使用但不兼容的方法
- indexOf()
  + 功能:查找內容
  + 參數:要查找的內容
  + 返回值:若是找到,返回內容對應的索引/位置; 若是沒找到,返回-1
  + 原數組不變
- forEach():遍歷數組的
  + 做用:遍歷數組的
  + 參數有兩個:1)callback 2)context:改變this指向的
  + callback中有三個參數:item,index,input
  + 返回值:undefined; 沒有返回值
  + 原數組不變
- map():也是遍歷數組,跟forEach()功能同樣,只是forEach()沒有返回值;map有返回值

***
## Math經常使用的方法
  + Math.round() 四捨五入
  + Math.floor() 向下取整
  + Math.ceil() 向上取整
  + Math.abs() 絕對值
  + Math.sqrt() 開平發
  + Math.pow() 冪次方
  + Math.max() 最大值
  + Math.min() 最小值
*求n-m之間的隨機整數:Math.round(Math.random()*(m-n)+n);
***
## 字符串經常使用的方法:
+ 經過下標找對應的字符
    + charAt() 返回指定位置的字符
    + charCodeAt() 返回在指定的位置的字符的 Unicode 編碼
+ 經過字符找下標
    + 從前日後找:indexOf()
    + 從後往前找:lastIndexOf()
+ 字符串截取
    + slice(n,m) 從索引n截取到索引m;不包含m;包前不包後;可是,slice能夠取負值
    + substr(n,m) 從索引n開始,截取m個
    + substring(n,m) 從索引n截取到索引m;不包含m
+ 字符串轉數組
    + split(切割形式:字符串或正則表達式)  把字符串分割爲字符串數組,返回一個字符串數組
+ 轉大小寫
    + toUpperCase() 把字符串轉換爲大寫
    + toLowerCase() 把字符串轉換爲小寫
+ 跟正則配合的字符串方法
    + split() 把一個字符串分割成字符串數組
    + match() 檢查一個字符串是否匹配一個正則表達式
    + replace('a','b') 把a替換爲b;替換與正則表達式匹配的子串
    + search() 檢索與正則表達式相匹配的值;找到的狀況下,返回對應內容的索引;找不到的返回-1

- 其餘數據類型轉爲number數據類型
    + 一個嚴格轉換Number(),兩個非嚴格轉換parseInt() parseFloat()
    + 轉換失敗是NaN
    + [] 默認經過 toString() 轉成空字符串; Number("")===0
    + null默認轉爲0;null+10=10; undefined+10=NaN
    + false===0; true===1
- 其餘數據類型轉爲布爾數據類型
    + Boolean() 
        + 假:"",0,NaN,null,undefined,false
        + 真:除了假都是真
    + if(一個值) 會轉成布爾
    + if(表達式/比較)  會默認轉成布爾
    + !
- 其餘數據類型轉成字符串數據類型
    + 對象轉字符串:toString()
    + 數字轉字符串:""+數字
- 數據類型的比較:
    + 對象==對象 比較的是地址   []==[] false
    + 字符串==對象 轉成字符串    ""==[]  true
    + 字符串==數字  轉成數字   ""==0 true
    + 字符串==布爾值 轉成數字   ""==![]  true
    + 數字==對象 轉成數字    0==[] 
    + 布爾值==對象 轉成數字    false==[]   ![]==[]
    + 數字==布爾值 轉成數字  false==![] 
    + null==undefined    true
    + null===undefined   false
    + NaN==NaN false ;NaN跟任何值都不相等,包括本身也不相等
- 給數組末尾增長一項
    + push()
    + ary[ary.length]=xxx;
    + ary.splice(ary.length,0,xxxx);
- 刪除數組最後一項
    + pop()
    + ary.length--; ary.length-=1; ary.length=ary.length-1;
    + ary.splice(ary.length-1,1);
- 如何實現克隆
    + ary.slice();/ary.slice(0)
    + ary.concat();
    + ary.splice(0) 注意:若是用splice()進行克隆,0不能省略
    + for循環也能夠實現;但for循環是循環,不是方法
- 定時器
  + 隔一段時間爆發一次:
    + setInterval(callback,毫秒數);
    + 關閉定時器 clearInterval(定時器的名字)
  + 只爆發一次:
    + setTimeout(callback,毫秒數);
    + 關閉定時器 clearTimeout(定時器的名字)
- n++ 和 ++n的區別
    + ++n  先++,再運算;累加後的結果參與了運算
    + n++  先運算,再++; 累加後的結果不參與運算
- 建立數組的兩種方式
    + var ary=[1,2,3]; 字面量方式建立
    + var ary2=new Array(1,2,3); 實例建立
***
- DOM樹:由一大堆的元素和標籤組成;因此DOM就是用來操做頁面中的標籤的
- DOM中的獲取方式有如下幾種:
    + id
    + className
    + tagName
    + name
    + 可視區的寬度:document.documentElement.clientWidth||document.body.clientWidth;
    + 可視區的高度:document.documentElement.clientHeight||document.body.clientHeight;
    + querySelector() #id  .class div   拿到的是一個元素
    + querySelectorAll() #id  .class div  拿到的是一組元素
- 節點:

|節點類型| 說明  |  值 |
|:----------:| :-----------:| :-------:| 
|元素節點|每個HTML標籤都是一個元素節點(例如:<div>、<input>等)|1|
|屬性節點|元素節點(HTML標籤)的屬性(例如:id 、class 、name 等)|2|
|文本節點|元素節點或屬性節點中的文本內容|3|
|註釋節點|表示文檔註釋,形式爲<!-- comment text -->|8|
|文檔節點|表示整個文檔(DOM 樹的根節點,即 document )|9|
- DOM動態操做
    + 建立新標籤
        + document.createElement(標籤名) 建立 
        + 克隆 obj.cloneNode(false/true);//false:只克隆表面; true:深度克隆
    + 動態插入
        + 父級.appendChild(新元素) 插入到父容器的末尾
        + 父級.insertBefore(newEle,oldEle) 插入到指定元素的前面
    + 刪除標籤
        + 父級.removeChild(獲取到的元素名)
    
- 屬性操做
    + . 和 []
    + attribute
        + setAttribute(屬性名,屬性值) 設置屬性  
        + getAttribute(屬性名) 獲取屬性
        + removeAttribute(屬性名) 移除屬性
    + 1)經過點來設置自定義屬性,看不到;可是經過setAttribute()能夠看到;
      2)經過點獲取元素身上已經定義好的的自定義屬性,獲取不到;可是經過getAttribute()能夠拿到;
    **注意:用"."都用點,用attribute,都用attribute;千萬不要混搭!**
- 判斷屬性是否存在的方法
    + in: "屬性名" in 對象    若是支持,返回true;不支持返回false
    + ".": 對象.屬性名   若是不支持,返回undefined

- 預解釋:當前做用域下,在JS代碼執行以前瀏覽器會對帶var和帶function的進行提早聲明或定義
- 帶var和帶function的聲明和定義不一樣:
    + 帶var的,只聲明不定義
    + 帶function,聲明+定義
- 函數定義三步驟:
    1. 開闢一個空間地址
    2. 把函數體內全部JS代碼做爲字符串放在這個空間中
    3. 把空間地址賦值給函數名=
- 函數調用四步驟:
    1. 造成一個私有做用域
    2. 形參賦值
    3. 預解釋
    4. 代碼從上到下的執行
- 上級做用域
    上級做用域跟函數在哪裏調用無關,只跟函數對應的堆內存在哪裏開闢有關
- 做用域鏈
  1. 當函數被調用的時候,會造成一個私有做用域;在這個做用域中查找是否有私有變量a
  2. 若是有私有變量a:那麼整個函數體內的全部a都是私有變量,跟外界沒有任何關係
  3. 若是沒有私有變量a:去上級做用域找,找不到,繼續往上級找,若是找到window尚未的話,報錯!
- 私有變量主要有兩種
    + 函數體內帶var的
    + 形參
***
- 內存包含:堆內存和棧內存
- 堆內存:用來存放數據
    + 對象數據類型的
        + 存的是鍵值對 key=value
    + 函數數據類型的
        + 代碼字符串
- 堆內存的釋放:
    var a=[1,2,3,4]
    釋放:a=null
- 棧內存:自己提供了一個供JS代碼執行的環境
    + 包含:全局做用域 和 私有做用域
- 全局做用域的造成和銷燬:
    + 造成:當一個頁面被瀏覽器加載完成的時候,全局做用域就造成了
    + 銷燬:1)關閉頁面 2)關閉瀏覽器
- 私有做用域的造成和銷燬:
    + 造成:當函數被調用的時候,會造成私有做用域
    + 銷燬:通常狀況下,當函數執行完成的時候,默認就被銷燬了;可是兩種狀況下不銷燬:
       + 不銷燬:當函數體內的東西被外面的變量或者其餘佔用的話,就不銷燬
       + 不當即銷燬:當函數執行完成的時候,會返回一個函數,被返回的函數還須要再執行一次;只有全部的調用都完成的時候,這個函數才能銷燬
***
- 預解釋無節操
  - 只對等號左邊帶var的,聲明但不定義
  - 自執行函數不會進行預解釋,只有,執行到他的時候,聲明+定義+調用同步完成
  - 已經聲明過的不會進行重複聲明,但會從新賦值
  - return下面的語句雖然不會執行,但會進行預解釋
  - 函數的聲明早於變量的聲明
  - (在IE10及10如下瀏覽器下)在條件判斷語句中,不管條件是否成立,都會進行預解釋
    **不要在條件判斷語句中寫函數的定義階段;不然,各大瀏覽器對其的兼容性不一樣**
***
  全局變量,都是window的全局屬性;
  全局函數,都是window的全局方法。
  好比:
setInterval()
setTimeout()
alert()
confirm()
***
- 關於this
- 當一個元素身上的事件被觸發的時候,會執行一個函數,函數中的this指向當前這個元素
- 自執行函數中的this,永遠都是window
- 回調函數中的this,通常都是window
  *setInterval(函數名,1000)  ; ary.sort(function(){})* ;
- 當函數被調用的時候,看前面是否有".","."前面是誰,this就是誰
- 當遇到call、apply、bind時,以上規律失效;由於他們能夠改變this指向
- 箭頭函數中的this指向父函數中的this
***
- 改變this指向的函數:
- call(arg1,arg2,arg3,arg4......)
  - call的一個參數用來改變call前面的函數中的this關鍵字
  - call從第二個參數開始,至關於給call前面的函數從左往右一個個的賦值;
  - call當改完this指向,傳完參數後,當即執行了
- apply(arg1,arg2) arg2可傳可不傳
  - arg1用來改變this指向,具體跟call同樣
  - 區別:apply的第二個參數是個數組,存放全部須要給形參的值;
  雖然apply的第二個參數是個數組,可是對於形參來講,也是從左往右一個個的賦值
- bind(預處理機制)
  - bind的傳參形式跟call同樣
  - 注:bind屬於預處理機制,當調用bind的時候,會返回一個已經改好this,傳好參數的函數,你只須要在須要的時候,調用便可
***
- 帶var和不帶var的區別:
- 帶var:
  1)會進行預解釋 
  2)若是在全局做用域下,他就是window的全局屬性
- 不帶var:
  1)不會進行預解釋 
  2)不帶var在"賦值"的時候,至關於window添加全局屬性

### 面向對象

- 對象兩大特徵:屬性 和 方法
- 面向對象(oop,oo)思想的特色:
  + 封裝:對於同一個功能,只須要封裝一次,之後再使用的時候,只須要調用便可,無需重寫;低耦合高內聚
  + 繼承:子類能夠繼承父類的屬性和方法
  + 多態:重載 和 重寫
    - 重載:JS上沒有嚴格意義上的重載;但有相似重載的功能,就是傳不一樣的參數,有不一樣的返回值
    - 重寫:子類能夠重寫父類的屬性和方法
- 面向對象的四種常見設計模式:
  + 單例模式
    - 把同一個對象上的屬性和方法,都放在同一個命名空間
    - 單例模式的本質:普通對象
    - 模塊化開發:對於一個複雜的大項目,能夠分配給不一樣的工程師同步進行開發;等項目完成的時候,合併便可
      + 各個模塊之間的相互調用:對象名.屬性名
      + 本模塊之間的相互調用:this.屬性名
** 缺點:形成大量冗餘代碼**
  + 工廠模式
    - 工廠模式有3步:
      + 引進原材料         建立一個空對象{}
      + 加工原材料         加工對象:給對象添加屬性和方法
      + 輸出產品成         輸出對象: return
    - 工廠模式,爲了讓他長的像系統的類 new Array()
    - 工廠模式和構造函數模式的區別:
      1. 在調用的時候:
        工廠模式 person()
        構造函數模式 new Person()
      2. 在函數體內
        工廠模式三步:1)建立對象 2)給對象添加屬性和方法 3)返回對象
        構造函數模式只有一步:2)給對象添加屬性和方法 ; 第一步和第三步系統幫作了,系統提供了一個對象叫this
  + 構造函數模式
    1.構造函數首字母必定大寫
    2.構造函數中放的都是私有的屬性和方法
    3.原型上放的都是公有的屬性和方法
    4.系統默認會建立一個對象,this
    5.系統默認會返回一個對象 this
    6.構造函數中的this,指向當前這個實例(構造函數new給誰,this就指向誰)
  + 原型模式
    - 原型模式基礎:
      1. 每一個函數數據類型(普通函數,類),都有一個屬性,叫作prototye,prototype是個對象
      2. prototype這個對象上,天生自帶一個屬性,叫作constructor,指向當前所屬類
      3. 每一個對象(普通對象,實例,prototype)身上,都有一個屬性,叫作`__proto__`,指向當前對象所屬類的原型
    - 原型鏈:`__proto__`
      若是要查找 對象.屬性名 好比f1.showX
      1. 先在本身的私有做用域中查找;若是找到,那麼這個屬性是私有屬性
      2. 若是沒找到,到當前實例所屬類的原型上找(f1.`__proto__`),若是找到屬於公有的屬性或方法
      3. 若是沒找到,繼續經過`__proto__`往上找,一直找到Object.prototype上尚未的話,undefined
    - 要造成的幾個條件反射:
      1. 一看到構造函數:存的都是私有的屬性和方法
      2. 一看到prototype:存的都是公有的屬性和方法
      3. `__proto__`原型鏈
- 兩大boss:Object 和Function
  1 Function  是  Object 的爹
  2 Object 是 Function 的爹
  3 Object 是 Function.prototype的爹
  4 Object.prototype 是 Function.prototype的爹
- 函數的三種角色:
  + 普通函數:造成一個私有做用域,形參賦值,預解釋,代碼執行,內存和內存釋放,做用域鏈
  + 類:實例,prototype,constructor,類,原型鏈`__proto__`
  + 普通對象:具備普通對象的特徵:屬性和方法
- 若是給原型自定義了一個對象,那麼自定義的這個對象上,沒有constructor
- 屬性判斷
- in:判斷某個屬性是否在元素上(包含了私有+公有)
- hasOwnProperty判斷某個屬性是否爲元素身上的私有屬性
使用 obj.hasOwnProperty(屬性名)
- 寫一個方法:判斷是否爲公有屬性
  - isPrototypeOf:判斷前一個對象是否在後一個對象的原型鏈上;返回的布爾值
  - propertyIsEnumerable:他的做用跟hasOwnProperty相似;返回的布爾值

- 繼承:子類繼承父類的屬性和方法
- call繼承:子類只繼承父類私有的屬性和方法;父類私有的屬性和方法,都在父類的構造函數裏
- 拷貝繼承:私有經過call來繼承,公有經過extend() 來繼承
- 原型繼承:
  + 私有繼承:call繼承
  + 公有繼承:父類原型上的屬性和方法,只有父類中的實例可使用
  + 子類原型可使用父類原型上的屬性和方法;子類原型做爲父類的實例
***
- 類數組轉數組
- 類數組有兩種:
  1. arguments 
  2. htmlCollection 元素集合
- 瀏覽器異常捕獲
  try....catch(e){}...finally{..}
  日常用的,只有 try...catch...
  使用場景:只要有報錯的狀況,建議用try...catch....
- JSON: JOSN 是系統window的屬性 
  + JSON.parse() 把JSON格式的字符串,轉成JSON格式的對象
  + JSON.stringify() 把JSON格式的對象,轉成JSON格式的字符串
  注意JSON,屬性名必定是雙引號"";屬性值,若是是數字,能夠沒有引號
- eval() 容易引發"注入攻擊"
***
- sort排序
- DOM映射:html頁面中的DOM結構,跟經過JS獲取到的元素集合htmlCollection之間,存在一一對應的關係
  + appendChild() 有相似剪切的功能
- sort排序三步驟:
  1 類數組轉數組
  2 sort排序
  3 把排好序的內容,從新插入頁面
- 把數據插入頁面的幾種方式
  1. 字符串拼接; _插入頁面用innerHTML
  2. 動態建立和插入; document.createElement()   父級.appendChild(元素)
  3. 文檔碎片:
    1)先把建立好的每一個元素,放入文檔碎片 
    2)最後把文檔碎片放入父元素中
    3)釋放文檔碎片
***
- 前端日後臺的請求方式:
  1. GET  請求數據
  2. POST 發送數據
  3. DELETE 刪除數據
  4. PUT 提交數據
- 同步和異步:
+ 同步:每次只能完成一個任務,必須等這個任務完成以後,才能開始下個任務
+ 異步:當前的任務沒完成,不用等待,繼續開始下個任務,也就是,能夠多個任務並行
  + 回調異步
  + 事件
  + 定時器
  + ajax
- http響應狀態碼
  + 2xx 成功
  + 3xx 重定向
  + 4xx 請求錯誤
      + 400 請求的參數錯誤
      + 404 文件沒找到
  + 5XX 服務器錯誤
***
- 正則(手冊:http://tool.oschina.net/uploads/apidocs/jquery/regexp.html)
- 做用:玩字符串的
- 定義:經過制定一系列的規則來操做(校驗/匹配、捕獲)字符串
  + 校驗: reg.test() ;/^2\d{2}/.test(xml.status);
  + 捕獲:1)str.match(reg)  2)reg.exec(str);  3)str.replace(reg);
  *正則的方法: reg.test()  reg.exec()*
  *字符串的方法:str.match() str.replace()  str.split() str.search();*
- 建立正則的方式:
  + var reg=/^2\d{2}/; 字面量的建立方式
  + var reg=new RegExp(); 實例建立
- 字面量建立和實例建立的區別:
  1. 字面量建立沒法拼接變量,實例建立能夠拼接變量 
  2. 字面量建立不須要轉義,實例建立須要轉義
- 正則由元字符和修飾符兩部分構成: var reg=/^2\d{2}/g;
  + 元字符:就是包含在兩個斜槓之間,陌生的字符
  + 修飾符:就是斜槓外面的
- 元子符包含:特殊含義的元字符和量詞元字符
- 特殊含義的元字符:
\ 轉義
| 或
() 分組
. 除了\n之外的其餘字符
\n 換行
\b 開頭結尾和空格
^ 開頭
$ 結尾
\s 空格         \d 數字           \w 數字,字母,下劃線
\S 非空格     \D 非數字      \W 非數字,非字母,非下劃線
[a-z] 任意一個小寫字母
[^a-z] 除了字母之外的任何一個字符
[abc] 「a,b,c」中的任意一個字母
[^abc] 除了「a,b,c」之外的任意一個字母
- 量詞元字符
  + `* ` 重複0次或屢次
  + `+` 重複1次或屢次
  + `?` 0 或1,無關緊要
  + {n} 正好n次
  + {n,} 最少n次;n次到屢次
  + {n,m} n次到m次
- 修飾符:
+ g 全局
+ m 換行
+ i 忽略大小寫;ignore
- ()小括號的用法:
  1. 提升優先級 /^(18|19)$/
  2. 分組的做用
- []中括號的用法:
  1. 中括號中不會出現兩位數
  2. 像相似於.-之類的,在中括號中都沒有特殊函數
- ?問號的做用:
  1. 無關緊要
  2. 解決正則捕獲的貪婪性

- 捕獲
- 正則中的捕獲,主要講三點:
  + exec: reg.exec(str);
  + match: str.exec(reg);
  + replace:str.replace(reg,xxxxxx)
- 正則捕獲有兩大特色:
  1. 懶惰性:
      + 解決措施:添加全局g
      + 加了全局g,會影響lastIndex(從你找到內容 的 下一項內容的 索引 開始查找)
  2. 貪婪性:
      + 解決措施:在量詞元字符後面加上?
-  exec,是正則的方法,每次只能拿到一個值;返回的結果是個數組,默認狀況下,數組有3項:
  1. 符合大正則的內容
  2. index:找到的內容所對應的索引;(位置)
  3. input:原始字符串;
  若是有小分組的狀況下,小分組從數組的第二項開始;數組的長度也會由於小分組而增長
- match:是字符串的方法,每次能到全部符合正則的內容,而且以一個新數組的形式返回
- exec和match的區別:
  1. exec每次只能拿到一個值;match能拿到全部值,並以新數組的形式返回
  2. exec能拿到小分組; match只能拿到大正則,沒法拿到小分組
- replace
- replace中的回調函數,默認接收三個參數,若是有小分組,arguments的長度會擴充
- replace回調函數中第一個參數的運用:敏感詞過濾
- replace回調函數中第2個參數的運用:把數字做爲數組的索引,找到對應的值
- 統計出現次數最多的單詞
 思路1:
  1) 利用對象不重名的特性
  2) 假設法
  3) 字符串拼接
思路2:
  1)字符串排序:字符串轉數組-數組排序-數組轉字符串
  2)假設法+重複子項 /(\w)\1+/gi;
- 解析URL地址: /([^&?=]+)=([^&?=]+)/g;
- 日期格式化:
重點,字符串轉成數組,三種思路:
1)嚴格匹配;

var reg=/^(\d{4})/-/- (\d{2}):(\d{2}):(\d{2})$/;
var ary=null;
str.replace(reg,function(){
ary=Array.prototype.slice.call(arguments,1,arguments.length-2)
});
```
2) split 切
var ary=str.split(/[^\d]+/g);
3) match 捕獲
var ary=str.match(/\d+/g);jquery

  • ?的用法
    1) 0或1
    2) 解決正則捕獲的貪婪性 +?
    3) 只匹配不捕獲 (?:\d+)
  • 小括號的用法:
    1)分組
    2)提升優先級
    3)只匹配不捕獲 (?:\d+)
  • var reg=new RegExp();
  • 在有全局g的狀況下,能影響lastIndex的值的屬性有兩個:
    1)reg.test()
    2) reg.exec()
  • 回調函數須要注意的幾點:
    1. 回調函數被調用的次數;好比,map中回調函數被調用的次數,取決於數組的長度
    2. 回調函數是否須要傳參;好比,map中回調函數接收三個參數
      1) item
      2) index
      3) input
  1. 回調函數中this默認指向window,能夠經過call來改變this指向
  2. 回調函數是否有返回值;好比 forEach()沒有返回值; map()有返回值,他是把每一個回調函數的返回值保存在一個數組中,最後返回出map
  • CSS盒子模型
    • 構成:手動設置的寬高+padding+border+margin
  • JS盒子模型
    • 主要經過元素身上提供的屬性和方法,來獲取元素身上的樣式值
  • JS中盒子模型所設計的屬性和方法,主要包含如下幾類:
    1. client系列:clientWidth clientHeight clientLeft clientTop
    • clientWidth/clientHeight: 手動設定的寬度/高度+左右/上下padding
    • clientLeft/clientTop: 左邊框的寬度 / 上邊框的寬度
    1. offset系列:offsetWidth offsetHeight offsetLeft offsetTop offsetParent
    • offsetWidth/offsetHeight:手動設定的寬度/高度+左右/上下padding+左右/上下的border寬度
      (clientWidth+左右border clientHeight+上下border)
    • offsetLeft/offsetTop:當前元素的外邊框距離他定位父級的內邊框之間的距離
    • offsetParent: 定位上的父級
  1. scroll系列:scrollWidth scrollHeight scrollLeft scrollTop
  • scrollWidth/scrollHeight:
    • 在內容沒有溢出的狀況下,
      scrollWidth/scrollHeight等於clientWidth/clientHeight;
    • 若是內容溢出的狀況下,
      scrollHeight約等於上padding+真實內容的高度
      爲何是約等於:
      1)當內容溢出的狀況下,不一樣瀏覽器拿到的值不一樣
      2)同一瀏覽器下,內容是否溢出拿到的值也不一樣
  • scrollTop:指當前頁面被瀏覽器捲去高度
  • JS盒子模型遇到的問題
    1. JS盒子模型中求出來的都是四捨五入的整數,沒法拿到小數 --不解決
    2. JS盒子模型中拿到的值都是複合值,沒法拿到單獨的寬或高; --解決:封裝getCss
    3. 關於盒子模型的偏移量,咱們只能求出當前容器的外邊框到定位父級的那邊框之間的距離,沒法求出當前定位元素到body的距離;--解決:封裝offset
    4. 求可視區的寬高或被瀏覽器捲去的高度和寬度,太麻煩了;-- 封裝win
      ***
  • 箭頭函數
    • 表達式
      1) var fn=p=>p;
      2) var fn=()=>'我沒有參數';
      3) var fn=(n,m)=>n+m;
    • 函數體
      1) var fn=p=>{return p};
      2) var fn=()=>{return '我沒有參數'};
      3) var fn=(n,m)=>{return n+m}
      注:箭頭函數中的this,指向父函數的this
  • 類的建立和繼承
    • 類的建立
    class 類名{
      constructor(){//寫私有的屬性和方法
      }
      getName(){//公有的屬性和方法
      }
      static getAge(){//類的靜態方法;也是類的私有方法,實例不能使用
      }
    }
    類.xxxx=xxxx;//類的私有屬性
    • 類的繼承
    class S extends F{
      constructor(name,age,color){
          super(name,age);
          this.color=color;
      }
      //下面正常寫子類公有的
    }
  • 解構賦值:{屬性名}=persion;//實際拿到的是對象身上該屬性名對應的值
  • let 和 const
    1) 他兩都不能進行預解釋
    2) let會造成塊級做用域
    3) const 是個常量,不能進行更改
    ***
  • $(document).ready() 和 window.onload的區別:
    • window.onload 是等頁面全部的內容(圖片,音頻,視頻,DOM結構.....)都加載完成的時候,才執行JS代碼
    • $(document).ready(function(){...代碼}) 只要DOM結構加載完成,就開始執行JS 代碼
      ***
  • jQuery選擇器
    • 基本選擇器:
      $('#div') $('.div') $('div') $('.div1,.div2');
  • JS和jquery只能共存,不能混淆
    • JS 轉成jquery:只須要被$包裹便可; $(this) $(oDiv)
    • jquery轉JS: [index] get(index)
  • jquery中DOM經常使用方法
    • append 和 appendTo
      聯繫:功能相同,可是針對的主體不一樣
    • 建立元素 $('
      ') $('
      ')
      ***
  • 運動
    • show() 顯示隱藏的元素
      hide() 隱藏顯示的元素
    • slideDown() 經過使用滑動效果,顯示隱藏的被選元素
      slideUp() 經過使用滑動效果,隱藏被選元素,若是元素已顯示出來的話
    • fadeIn() 使用淡入效果來顯示一個隱藏的元素
      fadeOut() 使用淡出效果來隱藏一個元素
    • animate(target,time,effect,callback) 執行 CSS 屬性集的自定義動畫
      stop() 中止當前正在運行的動畫
  • ajax先後端數據交互
ajax({
     type:'get/post',
     url:'xxxx?'+Math.random()*1000000+new Date().getTime(),
     async:true/false,
     dataType:'json',//解決了jsonParse()
     data:$('form').serialize()//表單序列化:就是把前端要傳後臺的數據,以k=v&k=v拼成字符串
     success:function(){//成功以後的回調
     },
     error:function(){//失敗以後的回調
     }
})

  • 事件和事件綁定
    • 事件綁定:2個
      on(type,fn) //能夠執行屢次
      one(type,fn) //只能執行一次
    • 解除綁定
      off(type,fn);//注意:只能解除有名字的函數
      ***
  • each和map
    • $().each() 和 $.each()的區別:
      • $().each() 只能遍歷jquery獲取到的元素
      • $.each() 既能夠遍歷jquery元素也能夠遍歷原生數組和原生對象
    • $().map() 和 $.map() 他們 與 each的區別
      • map的回調函數接收的參數,跟each的順序正好相反
      • map能夠返回一個新的數組;而each拿到的仍是原來的數組
        ***
  • 事件
    • 鼠標事件:
      onclick ondbclick onmouseover onmouseout onmouseenter onmouseleave
    • 系統事件:
      onload resize onscroll
    • 鍵盤事件:
      onkeydown onkeyup onkeypress
    • 表單事件:
      onfocus onblur autofocus=true/false;
  • 事件分類:DOM0級事件 和 DOM2級事件
    • DOM0級事件 和 DOM2級事件的區別:
      1. DOM0級事件:
        1)在元素的私有屬性上
        2)同一個元素,同一個行爲,只能綁定同一個方法;若是屢次綁定,後面的方法會覆蓋前面的方法
        3)只能發生在事件流的冒泡階段
      2. DOM2級事件:
        1)在元素所屬的EventTarget這個類的原型上
        2)同一個元素,同一個行爲,能夠綁定多個不一樣的方法
        3)能夠人爲的控制發生事件流的哪一個階段(捕獲,冒泡)
        ***
  • 標準瀏覽器下:
    addEventListener(type,fn,useCapture);
    • 解綁:
      removeEventListener(type,fn,useCapture);
      注意:全部的行爲,都不加on
  • IE6-8下:
    attachEvent('on'+type,fn)
    • 解綁:
      detachEvent('on'+type,fn);
      attachEvent只能發生在冒泡階段
      ***
  • 事件流
    • 由三部分構成:捕獲,target事件源,冒泡
    • 由兩部分構成:捕獲,冒泡
      注意順序:先捕獲,後冒泡
  • 一個元素的層級嵌套:
    元素本身->HTMLDivElement ->HTMLElement->Element->Node->EventTarget->Object
  • 事件對象
    • 事件對象的兼容處理:e=e||window.event
    • 事件源:e.target=e.target||e.srcElement;
    • 座標:距離當前可視區左上角的座標-兼容:e.clientX; e.clientY;
    • 座標:距離第一屏左上角的座標:e.pageX;e.pageY;
      不兼容:
      e.pageY=(document.documentElement.scrollTop||document.body.scrollTop)+ e.clientY;
      e.pageX=(document.documentElement.scrollLeft||document.body.scrollLeft)+ e.clientX;
    • 事件類型:e.type
    • 鍵碼:e.keyCode
    • 阻止默認事件: e.preventDefault?e.preventDefault():e.returnValue=false;
    • 阻止冒泡 e.stopPropagation? e.stopPropagation():e.cancelBubble=true;
  • 熟悉標準瀏覽器中的DOM2級事件綁定
    • addEventListener特色:(標準瀏覽器)
      1. 按"綁定的"前後循序執行的
      2. this指向當前被綁定事件的這個"元素"
      3. 若是給同一個元素,同一個行爲綁定屢次同一個方法,實際上只執行一次
    • attachEvent的問題:
      1. 順序不對
      2. this不對,attachEvent中的this,默認指向window
      3. 若是給同一個元素,同一個行爲綁定屢次同一個方法,執行的是屢次;也不對
        ***面試

        補充

  • null和undefined區別:
    1. 定義變量時:null如今沒有,之後會有;undefined:如今沒有,之後也沒有
    2. null轉爲數值爲0,undefined轉爲數值爲NaN
    3. 報錯時:undefined表示「缺乏值」,即 此處應該有一個值,但沒定義;null表示「沒有對象」,即 此處不應有值
  • 性能優化
    • 網頁內容
      • 減小 http請求次數
      • 減小 DNS查詢次數
      • 避免頁面跳轉
      • 緩存 Ajax
      • 延遲加載
      • 提早加載
      • 減小 DOM元素數量
      • 避免 404
    • 服務器
      • 使用CDN(內容分發網絡)
      • 添加Expires或Cache-Control報文頭
      • Gzip壓縮傳輸文件
    • CSS
      • 將樣式表置頂
      • 用代替@import
    • JavaScript
      • 把腳本置於頁面底部
      • 使用外部JavaScript和CSS
      • 精簡JavaScript和CSS
      • 去除重複腳本
      • 減小DOM訪問
    • 圖片
      • 優化圖像
      • 優化CSS Spirite
      • 不要在HTML中縮放圖片
      • favicon.ico要小並且可緩存
  • 如何解決跨域問題
    jsonp 原理:動態插入script標籤ajax

  • JavaScript同源策略
    這裏的同源策略指的是:協議,域名,端口相同。同源策略是一種安全協議,指一段腳本只能讀取來自同一來源的窗口和文檔的屬性。正則表達式

  • 哪些操做會形成內存泄漏?
    一、內存泄漏指任何對象在您再也不擁有或須要它以後仍然存在
    二、垃圾回收器按期掃描對象,並計算引用了每一個對象的其餘對象的數量。若是一個對象的引用數量爲 0(沒有其餘對象引用過該對象),那麼該對象的內存便可回收
    三、setTimeout 的第一個參數使用字符串而非函數的話,會引起內存泄漏。閉包、控制檯日誌、循環(在兩個對象彼此引用且彼此保留時,就會產生一個循環)chrome

  • 事件代理(Event Delegation) 即 事件委託
  • 定義:把本來須要綁定的事件委託給父元素,讓父元素擔當事件監聽的職務
  • 原理:DOM元素的事件冒泡
  • 優勢:提升性能編程

相關文章
相關標籤/搜索