JavaScript 知識點

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;
    }
})();
  • 作用:
    • 避免全局變量名沖突
    • 在閉包中通過“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個
      • 返回值:被刪除的內容,以一個新數組的形式返回
      • 原數組發生改變
第二組:克隆和截?。檎?/h5>
  • 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
注釋節點 表示文檔注釋,形式為 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}):(\d{2}):(\d{2})$/;
    var ary=null;
    str.replace(reg,function(){
        ary=Array.prototype.slice.call(arguments,1,arguments.length-2)
    });
  1. split 切
    var ary=str.split(/[^\d]+/g);
  2. match 捕獲
    var ary=str.match(/\d+/g);
  • ?的用法
    1) 0或1
    2) 解決正則捕獲的貪婪性 +?
    3) 只匹配不捕獲 (?:\d+)
  • 小括號的用法:
    1)分組
    2)提高優先級
    3)只匹配不捕獲 (?:\d+)
  • var reg=new RegExp();
  • 在有全局g的情況下,能影響lastIndex的值的屬性有兩個:
    1)reg.test()
    1. 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
      聯系:功能相同,但是針對的主體不同
    • 創建元素 ('
      ')('<div></div>')

  • 運動

    • 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標簽

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

  • 哪些操作會造成內存泄漏?
    1、內存泄漏指任何對象在您不再擁有或需要它之后仍然存在
    2、垃圾回收器定期掃描對象,并計算引用了每個對象的其他對象的數量。如果一個對象的引用數量為 0(沒有其他對象引用過該對象),那么該對象的內存即可回收
    3、setTimeout 的第一個參數使用字符串而非函數的話,會引發內存泄漏。閉包、控制臺日志、循環(在兩個對象彼此引用且彼此保留時,就會產生一個循環)

  • 事件代理(Event Delegation) 即 事件委托

  • 定義:把原本需要綁定的事件委托給父元素,讓父元素擔當事件監聽的職務

  • 原理:DOM元素的事件冒泡

  • 優點:提高性能

最后編輯于
?著作權歸作者所有,轉載或內容合作請聯系作者
平臺聲明:文章內容(如有圖片或視頻亦包括在內)由作者上傳并發布,文章內容僅代表作者本人觀點,簡書系信息發布平臺,僅提供信息存儲服務。

推薦閱讀更多精彩內容