JS基礎 頁面由三部分組成: + html:超文本標記語言,負責頁面結構 + css:層疊樣式表,負責頁面樣式 + js:輕量級的腳本語言,負責頁面的動效和數據交互 小總結:結構,樣式和行為,三者相分離 + 在html頁面中寫結構 + 通過 link標簽的href屬性,引入css樣式 + 通過scr ...
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隱藏
- 實現思路:
- 高度:div2的高度為0; 移入div1後高度為100;移出div1時div2高度0;
- display:block顯示,none,隱藏;
- 透明度:rgba(); opacity();
- 定位:left和top;
- margin:margin-left和 margin-top;
- overflow:hidden和visible;
- JS獲取元素的方式:
- document.getElementById('id名字');
因為id是唯一的,所以拿到的是一個元素 - document.getElementsByTagName('標簽名');
標簽名拿到的是一個元素集合;即使只有一個元素,也是個集合
想要取到其中的一個:aDiv[0] aDiv[2]
- document.getElementById('id名字');
- JS中的數據類型
- 基本數據類型:
- 字元串string
- 數字 number
- 布爾值 boolean
- undefined 現在沒有,以後也沒有
- null 空對象,現在沒有,以後會有
- 引用數據類型
- 對象數據類型
- 數組
- 正則
- 對象{}
- 函數數據類型
function 函數名(){};
- 對象數據類型
- 基本數據類型:
- 數據類型檢測的方式
- typeof 可以檢測基本數據類型(所有經過typeof的都是字元串),但是對於對象數據類型,檢測出來的都是object,無法知道具體屬於哪種對象
- 對象 instanceof 類; 比如
ary instanceof Array
判斷這個實例是否屬於某個類 - 對象.constructor: 比如
ary.constructor
可以列印出對象所屬的類 - Object.prototype.toString.call(ary); 出來的結果 '[object Array]'
- 基本數據類型和引用數據類型的區別:
- 基本數據類型:是對值的操作
- 引用數據類型:是對地址的操作
- 操作屬性用的是"." oDiv.style.display='block'
- 其他數據類型轉為number數據類型
- 強制轉換
- Number()
- parseInt()
- parseFloat()
- 一個嚴格轉換
- Number()
- 兩個非嚴格轉化
- parseInt() 只能轉化為整數
- parseFloat() 可以保留小數
- 關於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代碼來執行
只定義不調用,函數不會執行
- 函數定義3階段
- 閉包
- 定義:
- 當函數被調用的時候會形成一個私有作用域,保護裡面的變數不受外界的干擾,函數的這種保護機制叫做閉包
- 作用:
- 避免全局變數名衝突
- 在閉包中通過“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:用於多條件判斷
每一種case情況其實都是相當於在用“===”進行比較switch(判斷的是可變的值){ case a: 語句1; break; case b: 語句2; break; default: 語句3; break; }
- 如果只有一種條件,有三種寫法:
- if(條件){語句1}
- 條件?語句1:null;
- if(條件) 語句1;
- 9%3==0 && alert('能整除');
- 9%3!=0 || alert('能整除');
數組常用的方法
第一組:增加,刪除和替換
- push()
- 作用:給數組末尾增加一項
- 需要實參
- 返回值:新數組的長度
- 原數組發生改變
- pop()
- 作用:刪除數組最後一項
- 不需要參數
- 返回值:被刪除的內容
- 原數組發生改變
- unshift()
- 作用:給數組開頭增加一項
- 需要實參
- 返回值:新數組的長度
- 原數組發生改變
- shift()
- 作用:刪除數組第一項
- 不需要參數
- 返回值:被刪除的內容
- 原數組發生改變
- splice()
- 插入/增加 splice(index,0,要添加的內容)
- 作用:在指定的索引前面,插入我們要添加的內容
- 參數:3個
- 返回值:[]空數組,裡面沒有內容
- 原數組發生改變
- 刪除 splice(index,m)
- 作用:從指定的索引地方開始,刪除m個;如果第二個參數不寫,就從索引一直刪除到結尾
- 參數:2個
- 返回值:被刪除的內容,以一個新數組的形式返回
- 原數組發生改變
- 替換 splice(index,m,n)
- 作用:從指定的索引開始,刪除m個,並替換為n的新內容
- 參數:3個
- 返回值:被刪除的內容,以一個新數組的形式返回
- 原數組發生改變
- 插入/增加 splice(index,0,要添加的內容)
第二組:克隆和截取/查找
- 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() 通過下標找對應的字元編碼
- 通過字元找下標
- 從前往後找: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() 找到的情況下,把你要找的內容拎出來;找不到返回null
- 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(表達式/比較) 會預設轉成布爾
- !
- Boolean()
- 其他數據類型轉成字元串數據類型
- 對象轉字元串: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(屬性名) 移除屬性
- setAttribute(屬性名,屬性值) 設置屬性
- 1)通過點來設置自定義屬性,看不到;但是通過setAttribute()可以看到;
2)通過點獲取元素身上已經定義好的的自定義屬性,獲取不到;但是通過getAttribute()可以拿到;
註意:用"."都用點,用attribute,都用attribute;千萬不要混搭!
- 判斷屬性是否存在的方法
- in: "屬性名" in 對象 如果支持,返回true;不支持返回false
- ".": 對象.屬性名 如果不支持,返回undefined
- 預解釋:當前作用域下,在JS代碼執行之前瀏覽器會對帶var和帶function的進行提前聲明或定義
- 帶var和帶function的聲明和定義不同:
- 帶var的,只聲明不定義
- 帶function,聲明+定義
- 函數定義三步驟:
- 開闢一個空間地址
- 把函數體內所有JS代碼作為字元串放在這個空間中
- 把空間地址賦值給函數名=
- 函數調用四步驟:
- 形成一個私有作用域
- 形參賦值
- 預解釋
- 代碼從上到下的執行
- 上級作用域
上級作用域跟函數在哪裡調用無關,只跟函數對應的堆記憶體在哪裡開闢有關 - 作用域鏈
- 當函數被調用的時候,會形成一個私有作用域;在這個作用域中查找是否有私有變數a
- 如果有私有變數a:那麼整個函數體內的所有a都是私有變數,跟外界沒有任何關係
- 如果沒有私有變數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()
- 工廠模式和構造函數模式的區別:
- 在調用的時候:
工廠模式 person()
構造函數模式 new Person() - 在函數體內
工廠模式三步:1)創建對象 2)給對象添加屬性和方法 3)返回對象
構造函數模式只有一步:2)給對象添加屬性和方法 ; 第一步和第三步系統幫做了,系統提供了一個對象叫this
- 在調用的時候:
- 構造函數模式
1.構造函數首字母一定大寫
2.構造函數中放的都是私有的屬性和方法
3.原型上放的都是公有的屬性和方法
4.系統預設會創建一個對象,this
5.系統預設會返回一個對象 this
6.構造函數中的this,指向當前這個實例(構造函數new給誰,this就指向誰) - 原型模式
- 原型模式基礎:
- 每個函數數據類型(普通函數,類),都有一個屬性,叫做prototye,prototype是個對象
- prototype這個對象上,天生自帶一個屬性,叫做constructor,指向當前所屬類
- 每個對象(普通對象,實例,prototype)身上,都有一個屬性,叫做
__proto__
,指向當前對象所屬類的原型
- 原型鏈:
__proto__
如果要查找 對象.屬性名 比如f1.showX- 先在自己的私有作用域中查找;如果找到,那麼這個屬性是私有屬性
- 如果沒找到,到當前實例所屬類的原型上找(f1.
__proto__
),如果找到屬於公有的屬性或方法 - 如果沒找到,繼續通過
__proto__
往上找,一直找到Object.prototype上還沒有的話,undefined
- 要形成的幾個條件反射:
- 一看到構造函數:存的都是私有的屬性和方法
- 一看到prototype:存的都是公有的屬性和方法
__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繼承
- 公有繼承:父類原型上的屬性和方法,只有父類中的實例可以使用
- 子類原型可以使用父類原型上的屬性和方法;子類原型作為父類的實例
***
- 類數組轉數組
- 類數組有兩種:
- arguments
- 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 把排好序的內容,重新插入頁面 - 把數據插入頁面的幾種方式
- 字元串拼接; _插入頁面用innerHTML
- 動態創建和插入; document.createElement() 父級.appendChild(元素)
- 文檔碎片:
1)先把創建好的每個元素,放入文檔碎片
2)最後把文檔碎片放入父元素中
3)釋放文檔碎片
***
- 前端往後臺的請求方式:
- GET 請求數據
- POST 發送數據
- DELETE 刪除數據
- PUT 提交數據
- 同步和非同步:
- 同步:每次只能完成一個任務,必須等這個任務完成之後,才能開始下個任務
- 非同步:當前的任務沒完成,不用等待,繼續開始下個任務,也就是,可以多個任務並行
- 回調非同步
- 事件
- 定時器
- ajax
- http響應狀態碼
- 2xx 成功
- 3xx 重定向
- 4xx 請求錯誤
- 400 請求的參數錯誤
- 404 文件沒找到
- 5XX 伺服器錯誤
***
- 正則
- 作用:玩字元串的
- 定義:通過制定一系列的規則來操作(校驗/匹配、捕獲)字元串
- 校驗: 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(); 實例創建
- 字面量創建和實例創建的區別:
- 字面量創建無法拼接變數,實例創建可以拼接變數
- 字面量創建不需要轉義,實例創建需要轉義
- 正則由元字元和修飾符兩部分構成: 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
- ()小括弧的用法:
- 提高優先順序 /^(18|19)$/
- 分組的作用
- []中括弧的用法:
- 中括弧中不會出現兩位數
- 像類似於.-之類的,在中括弧中都沒有特殊函數
- ?問號的作用:
- 可有可無
- 解決正則捕獲的貪婪性
- 捕獲
- 正則中的捕獲,主要講三點:
- exec: reg.exec(str);
- match: str.exec(reg);
- replace:str.replace(reg,xxxxxx)
- 正則捕獲有兩大特點:
- 懶惰性:
- 解決措施:添加全局g
- 加了全局g,會影響lastIndex(從你找到內容 的 下一項內容的 索引 開始查找)
- 貪婪性:
- 解決措施:在量詞元字元後面加上?
- 懶惰性:
- exec,是正則的方法,每次只能拿到一個值;返回的結果是個數組,預設情況下,數組有3項:
- 符合大正則的內容
- index:找到的內容所對應的索引;(位置)
- input:原始字元串;
如果有小分組的情況下,小分組從數組的第二項開始;數組的長度也會因為小分組而增加
- match:是字元串的方法,每次能到所有符合正則的內容,並且以一個新數組的形式返回
- exec和match的區別:
- exec每次只能拿到一個值;match能拿到所有值,並以新數組的形式返回
- 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) });
2) split 切
var ary=str.split(/[^\d]+/g);
3) 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()
2) reg.exec() - 回調函數需要註意的幾點:
- 回調函數被調用的次數;比如,map中回調函數被調用的次數,取決於數組的長度
- 回調函數是否需要傳參;比如,map中回調函數接收三個參數
1) item
2) index
3) input - 回調函數中this預設指向window,可以通過call來改變this指向
- 回調函數是否有返回值;比如 forEach()沒有返回值; map()有返回值,他是把每個回調函數的返回值保存在一個數組中,最後返回出map
- CSS盒子模型
- 構成:手動設置的寬高+padding+border+margin
- JS盒子模型
- 主要通過元素身上提供的屬性和方法,來獲取元素身上的樣式值
- JS中盒子模型所設計的屬性和方法,主要包含以下幾類:
- client系列:clientWidth clientHeight clientLeft clientTop
- clientWidth/clientHeight: 手動設定的寬度/高度+左右/上下padding
- clientLeft/clientTop: 左邊框的寬度 / 上邊框的寬度
- offset系列:offsetWidth offsetHeight offsetLeft offsetTop offsetParent
- offsetWidth/offsetHeight:手動設定的寬度/高度+左右/上下padding+左右/上下的border寬度
(clientWidth+左右border clientHeight+上下border) - offsetLeft/offsetTop:當前元素的外邊框距離他定位父級的內邊框之間的距離
- offsetParent: 定位上的父級
- offsetWidth/offsetHeight:手動設定的寬度/高度+左右/上下padding+左右/上下的border寬度
- scroll系列:scrollWidth scrollHeight scrollLeft scrollTop
- scrollWidth/scrollHeight:
- 在內容沒有溢出的情況下,
scrollWidth/scrollHeight等於clientWidth/clientHeight; - 如果內容溢出的情況下,
scrollHeight約等於上padding+真實內容的高度
為什麼是約等於:
1)當內容溢出的情況下,不同瀏覽器拿到的值不同
2)同一瀏覽器下,內容是否溢出拿到的值也不同
- 在內容沒有溢出的情況下,
- scrollTop:指當前頁面被瀏覽器捲去高度
- JS盒子模型遇到的問題
- JS盒子模型中求出來的都是四捨五入的整數,無法拿到小數 --不解決
- JS盒子模型中拿到的值都是複合值,無法拿到單獨的寬或高; --解決:封裝getCss
- 關於盒子模型的偏移量,我們只能求出當前容器的外邊框到定位父級的那邊框之間的距離,無法求出當前定位元素到body的距離;--解決:封裝offset
- 求可視區的寬高或被瀏覽器捲去的高度和寬度,太麻煩了;-- 封裝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級事件的區別:
- DOM0級事件:
1)在元素的私有屬性上
2)同一個元素,同一個行為,只能綁定同一個方法;如果多次綁定,後面的方法會覆蓋前面的方法
3)只能發生在事件流的冒泡階段 - DOM2級事件:
1)在元素所屬的EventTarget這個類的原型上
2)同一個元素,同一個行為,可以綁定多個不同的方法
3)可以人為的控制發生事件流的哪個階段(捕獲,冒泡)
***
- DOM0級事件:
- 標準瀏覽器下:
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特點:(標準瀏覽器)
- 按"綁定的"先後循序執行的
- this指向當前被綁定事件的這個"元素"
- 如果給同一個元素,同一個行為綁定多次同一個方法,實際上只執行一次
- attachEvent的問題:
- 順序不對
- this不對,attachEvent中的this,預設指向window
如果給同一個元素,同一個行為綁定多次同一個方法,執行的是多次;也不對
***補充
- null和undefined區別:
- 定義變數時:null現在沒有,以後會有;undefined:現在沒有,以後也沒有
- null轉為數值為0,undefined轉為數值為NaN
- 報錯時: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元素的事件冒泡
優點:提高性能