文章目錄
瀏覽器內核
IE trident
Chorm blink
firefox Gecko
Opera webkit
Safari webkit
解釋型語言:解釋一行執行一行,將代碼轉換成機械碼。執行速度相對較慢,可以跨平臺。
編譯型語言:先將代碼翻譯成系統可以識別文件,再將文件轉換成機械碼,執行速度相對快, 不能跨平臺。
js是解釋型語言並且是單線程的。
script 標籤不能同時外部引用和內部引用,(內部引用不會生效)
變量
變量 b變量的名字必須以字母、_、$開頭 變量名可以包含數字 不可以用系統的關鍵字保留字做爲變量名
var a = 0,
b= 1,
c= 3;
數據類型:
1、原始值 Number,Boolean,String, undefinde, null steck(棧):first in last out
undefinde:變量聲明瞭沒有賦值。
null:佔位
2、引用值
array, Object, function , 。。。 data , RegExp heap(堆)
唯一區別: 複製形式不同
3.typeof 返回的六個值爲:number、string、boolean、undefined、object、function。
書寫規範
for ,function , if 後面不用加很分號
錯誤類型
錯誤分兩種:
1、低級錯誤:(語法解析錯誤) SyntaxError 語法解析錯誤
2、邏輯錯誤:(標準錯誤) ReferenceError 引用錯誤。
js語法錯誤會引發後續代碼終止,但不會影響其他js代碼塊。
js運算符
+
數學運算、字符串拼接
任何數據類型加字符串都等於字符串。
0/0 //NaN 1/0 //infinity
// ++ -- += -= /=
var a = 10;
document.write(a++); // 10 document.write(a); 11
document.write(++a); // 11
先計算,後賦值
賦值的順序,自右向左。 計算的順序,自左向右
var a = b = 10;
var a = 10;
var b = ++a - 1 + a++; ++a時,a的值爲11 , -1 爲 10 , 加 a 此時a的值爲11,所以結果爲10 + 11 得 21.
document.write(b + " " + a); // a = 12 b = 21;
a += 1 相當於 a = a +1;
a %= 1 相當於 a = a%1;
1.比較運算符
var a = 2 > 1; // true
>,<,>= ,<=,==,!=都是比較運算符,他們的返回結果是true或false。
當兩個字符串相比較時,比較的時對應的ascII碼的值。
var a = '10' > '8' // false
undefined == undefined // true
Infinity == Infinity // true
NaN == NaN // false
比較的是字符串‘1’,‘0’與‘8’的asccII碼。1的ascII小於8的ascII,0的ascII小於8的ascII,所以‘10‘ < ’8‘.
如果一個不是字符串,並且兩個都是原始類型,將他們都轉換爲數字進行比較。
NaN與任何數字比較得到的結果都是false。
Infinity 比任何數字都大。
-infinity 比任何數字都小。
NaN < Infinty // false
如果其中一個是對象,將對象轉換爲原始類型。
相等比較
== 、 !=
一、兩端的數據類型相同,直接比較兩個數據本身是否相同(兩個對象比較地址)。
二、兩端的類型不同
1). null 和 undefined, 他們之間相等,和其他原始類型比較則不相等。
null == undefined // true
null == 0 // false
undefined == 0 //false
2). 其他原始類型,比較時先轉換爲數字,再進行比較。
3). NaN與任何數字比較都是false,包括自身。
4).Infinity和-Infinity,只能自身和自身相等。
5). 對象比較時,要先轉換成原始類型再進行比較
=== !==
1.兩端類型相同,規則和相等比較一致。
2.兩端類型不同爲false。
null === undefined //false
null == undefined // true
2. 邏輯運算符 && || !
只有 undefined, null, NaN, “”, 0, false 轉換成boolean值以後爲false,其他值都會轉爲真。
var a = 1 && 2; // 2
var num = 1 || 3;
var n = !123;
與運算符會先看與運算符前面的表達式轉換成boolean是否爲真,如果爲真,那麼它會看第二個表達式轉換爲布爾值的結果。如果只有兩個表達式,會直接返回第二個表達式的值。
當第一個表達式的值爲false時,直接返回第一個表達式的值。
或運算符當第一個表達式結果爲真時,返回第一個表達式。如果第一個表達是爲假直接返回第二個表達式的值。
非運算符會將表達式轉換成布爾值後取反。
算數運算符
其他數據類型使用算數運算
1.除加號之外的算數運算符。
將原始值轉換爲數類型(自動完成轉換),然後進行運算。
bollean:true =》 1, false =》 0.
string:如果字符串內部是一個正確的數字,直接變爲數字,如果是一個非數字,則得到NaN(能識別Infinity,不能把字符串內部的東西當作表達式)。
null:+ null =》 +0 ; - null =》 - 0。
undefined:undefined =》 NaN;
2.加號運算符
-加號運算符一邊有字符串,含義變爲字符串拼接。
將另一邊的其他類型,轉換爲字符串。
數字 -》 數字字符串。
boolean =》 boolean字符串
null =》 “null”
undefined =》 ”undefined“。
+”“ =》0.
字符串轉換時會忽略前後空格。
自增和自減
基本功能
一元運算符
++:將某個變量的值自增1
–:將某個變量的值自減1
細節
自增自減表達式
x++: 將變量x自增1,得到的表達式的值是自增之前的值。
++x: 將變量x自增1,得到的表達式的值是自增之後的值。
x–: 將變量x自減1,得到的表達式的值是自減之前的值。
–x: 將變量x自減1,得到的表達式的值是自減之後的值。
優先級
從高到底依次是:
++ --
* / %
+ -
優先級的運算細節:
- 從左到右依次查看
- 如果遇到操作數,將數據的值直接取出
- 如果遇到相鄰的兩個運算符,並且左邊的運算符優先級大於等於右邊的運算符,則直接運行左邊的運算符
for循環
for(var i = 0;i < 10; i++) {
document.write('a');
}
/*
1.先執行var i = 0;
2.if(i < 10) {
document.write('a');
}
3.i++
4.然後重複執行步驟2和步驟3.
*/
var i = 0;
for(; i < 10; ) {
document.write('a');
i++;
}
/*
與第一種for循環的寫法意思相同,for循環的執行順序沒變。
*/
if 判斷
包裝類
var num = 4;
num.len = 3;
console.log(num.len); // undefined
/* num 作爲原始值是不會有屬性和方法的。系統會隱式的將num轉化爲new Number(4).len = 3,然後執行delete方法將該屬性刪除。當再次訪問num.len時,又重新將num.len 轉換爲new Number(4).len,此時得到的值爲undefined。
*/
var arr = [1,2,3];
arr.length = 2;
console.log(arr); // [1,2]
/* 當修改數組的length 屬性時,會將數組截斷。此時將arr的 length屬性變爲2,則arr爲[1,2]。
*/
var str = 'abc';
str.length = 2;
//new String('abc).length = 2 delete
//new String('abc').length 原本new String()上就有length屬性,返回的就是字符串的長度
console.log(str.length) //3
Date構造函數
UTC和GMT
GMT:格林威治時間。太陽時,精確到毫秒。
UTC:世界協調時。以原子時間爲即使標準,精確到納秒。
UTC和GMT之間誤差不會超過0.9秒
GMT +0800 東8區
時間戳
數字
GMT時間 1970-1-1 凌晨 到某個時間 所經過的毫秒數
var d = new Date(2015, 5 , 1, 13, 14, 15 ,200); //Mon Jun 01 2015 13:14:15 GMT+0800 (中國標準時間)
d.toISOString() // "2015-06-01T05:14:15.200Z" 零時區的時間
new Date 裏的參數分別爲年、月、日、時、分、秒、毫秒,如果new Date裏有1個參數時參數類型爲數字,表示傳入的是時間戳(從1970-1-1凌晨+/-時間戳,有時間戳的正負決定+/-)。如果不傳參數,表示當前時間。
注意:月份是從零開始記錄的。
如果參數缺失,日期部分默認爲1,時分秒毫秒默認爲0.
月、日、時、分、秒/毫秒,均可以傳遞負數, 會根據指定日期進行計算。
new Date(2015, -1); //Mon Dec 01 2014 00:00:00 GMT+0800 (中國標準時間)
new Date(2015, 2, -1); //Fri Feb 27 2015 00:00:00 GMT+0800 (中國標準時間) 日期是從1開始計算的,所以傳入-1相當於減了兩天。
日期的運算
日期對象的valueOf方法返回的是數字類型的時間戳。因此日期對象可以進行數學運算。當作+法運算時會調用對象的toString方法,所以變成了字符串拼接。
Math四捨五入的方法:
方法 | 註釋 |
---|---|
Math.floor | 將數值進行向下取整 例如:Math.floor(123.456) //123 |
Math.ceil | 將數值進行向上取整 例如:Math.floor(123.456) //124 |
Math.round | 將數值四捨五入成整數 例如:Math.round(123.666) //124 |
parseInt | 將數值捨棄小數部分轉換成整數 例如:parseInt (123.666) //123 |
toFixed() | 將數值四捨五入成整數 例如:143.666.toFixed(2) // '143.67 ’ 注意toFixed的返回值爲string類型 |
因此我們需要寫一個能返回數字類型的值還並且能夠四捨五入的方法:
function round (num,d){
num *= Math.pow(10,d);
num = Math.round(num);
return num/Math.pow(10,d);
}
console.log(round(123.456,2)) //傳2爲保留兩位小數四捨五入
console.log(round(234.567,0)) //傳0 爲數字本身四捨五入
console.log(round(161,-1)) //傳-1爲整數部分四捨五入
console.log(round(168,-1))
輸出結果如下:
思路:首先要進行四捨五入就會用到Math.round() 的方法。觀察Math.round 的行爲:Math.round的返回值爲整數,並不能對小數進行保留。
因此我們可以通過擴大倍數(小學數學思想)來進行四捨五入,小數每擴大10倍小數點就會向後移動一位。比如求161.25四捨五入並保留一位有效數字:
var a = 161.25*10; //a 1612.5
a = Math.round(a); //a 1613
a/10 = 161.3 //因爲前面將數字擴大了10倍,爲保持數值不變最後的結果應除以原來擴大的倍數。
對於Date對象的小技巧
new Date().getMounth()的返回值爲 0 -11;
如果 new Date(year,mouth,0).getDate();此時的返回結果爲當前月最後一天。
如果當傳入的日期爲0時,則查詢的getDate的值會返回上個月最後一天的值。
適用場景:日曆。
看下面代碼:
console.log(1 + undefined) //NaN
console.log(1 + null); //1
console.log(null + undefined); //NaN
console.log(true + false); //1
console.log(3 +'6'); //'36'
console.log(2 +[]); //'2'
console.log(2 +{a:2}); //'2[object Object]'
console.log([] + {}); //'[object Object]'
console.log({} + []); //['object Object]'
console.log(3 + {}); //'3[object Object]'
console.log({} + 3); // '[object Object]3'
console.log(1 * []); //0
console.log(1 * [2]); //2
console.log(1 * [2,3]); //NaN
console.log(1 * {}); //NaN
當進行加法運算時會進行隱式類型轉換,如果加號兩邊的值不是引用類型且不爲字符串類型,加號兩邊的值會先進行數值類型的轉換。
Number(undefined) 的 值爲 NaN,因此 1 + undefined 的值爲NaN,Number(null) 的值爲0。true 和 false 分別轉換成0和1。當+號遇見字符串時會按照字符串拼接的規則執行。當+號遇見數組時,會將數組的兩個中括號去掉,裏面的值加上“”,因此2 + [] 的值爲’2’。當*遇見[]時,會將[]的值轉換爲“”,“”轉換爲0。當+號遇見對象時會調用Object的toString方法將對象轉換爲字符串,對象轉換的結果爲’[object Object]’,所以3 + {}的值爲 ‘3[object Object]’。
正則
匹配輸入漢字:js /^[\u4e00-\u9fa5]{2,6}$/
字符集:
[字符範圍 ]
[^字符範圍] 對字符範圍取反
量詞:
* 匹配0個或多個
+ 匹配1個或多個
? 匹配0個或1個
{n} 匹配n個
{n,} 匹配>=n個
{n,m} 匹配n-m個
//test方法
var reg = /abc/g;
console.log(reg.lastIndex, reg.test("111abc111abc111"));//0 true
console.log(reg.lastIndex, reg.test("111abc111abc111"));//6 true
console.log(reg.lastIndex, reg.test("111abc111abc111"));//12 false
console.log(reg.lastIndex, reg.test("111abc111abc111"));//0 true
console.log(reg.lastIndex, reg.test("111abc111abc111"));//6 true
console.log(reg.lastIndex, reg.test("111abc111abc111"));//12 false
正則匹配爲全局匹配多次調用test方法會出現上面的情形,當匹配成功以後他會從上次匹配成功的地方繼續往後匹配,直到返回false纔會復位。
如果沒有開啓全局匹配每次匹配都會從0的位置開始。
貪婪匹配
正則表達式會盡可能多的匹配滿足表達式內容的字符串。
var reg = /\d+/g;
console.log(reg.lastIndex, reg.test("111abc111abc111"), reg.lastIndex);//0 true 3
正則會找到"111"而不是"1"或者"11"。
正則默認使用貪婪模式匹配。
var reg = /\d+?/g;
在正則的量詞符號後面加上"?"表示開啓非貪婪匹配模式。即儘可能少的匹配符合規則的字符串。
字符串的split方法也可以將正則作爲參數傳入。
var s = "sfsdfdsfd,fgdfdfgdf fdgdfgdg-dfgfdgdf\tgfdgdgffg";
var result = s.split(/[,\-\t]/);
console.log(result); //["sfsdfdsfd", "fgdfdfgdf fdgdfgdg", "dfgfdgdf", "gfdgdgffg"]
字符串的replace方法
replace方法並不會修改原來的字符串會返回一個新的字符串。
replace的第二個參數可以傳一個函數。
捕獲組
var s = "2015-5-1, 2019-6-19, 2000-04-28";
var reg = /(?<year>\d{4})-(?<mounth>\d{1,2})-(?<day>\d{1,2})/g;
while(result = reg.exec(s)) {
console.log(result)
}
會得到如下結果:
正則表達式reg
中每一個小括號表示一個捕獲組,exec
方法返回一個數組,數組裏的第一個元素表示匹配到的字符串,後面的元素依次(按照捕獲組的書寫順序從左到右)表示每個捕獲組匹配到的內容。
在捕獲組前面加上?<捕獲組名稱>
來給每一個捕獲組命名。exec
方法返回的
數組中groups
屬性可以查看。如果沒有給捕獲組命名則groups
屬性的值爲undefined
。
非捕獲組
/(?:\d)/
由於捕獲組佔用執行效率,所以當我們不需要捕獲組時只要在正則表達式中的小括號開頭部分加上?:
就可以了。
str.replace(reg, function(match,g1,g2,g3){
})
s.replace(reg,"$1/$2/$3");
上面字符串的replace方法中,g1,g2,g3 和 $1,$2,$3就是捕獲組。
反向引用
var s = "aaabbbccccc"
//找出該字符串中連續的字符
var reg = /(\w)\1+/g;
while(result = reg.exec(s)) {
console.log(result[1];
}
\1
表示匹配和第一個捕獲組一模一樣的內容。
正向預查
檢查某個字符後面的字符是否滿足某個規則,該規則匹配的結果不會在整個表達式的匹配結果中返回。
var s = "dffsdf544543dsfsdf543553dfdsdf"
//匹配所有後面是數字的字母
var reg = /[a-zA-Z](?=\d+)/g;
while(result = reg.exec(s)){
console.log(result)
}
當在小括號開頭部分加上?=
時表示正向預查,此時\d+
匹配的數字並不會在result中出現,並且這裏的小括號不是 捕獲組。
var s ="3345678";
var reg = /\B(?=(\d{3})+$)/g;
s.replace(reg,function(match,$1){
console.log(match,$1);
})
負向預查
檢查某個字符後面的字符是否不滿足某個規則,該規則匹配的結果不會在整個表達式的匹配結果中返回。
var reg = /(?!\d+)/g;
當在小括號開頭部分加上?!
時表示負向預查。
瀏覽器dom操作
- 父元素.appendChild(元素):在某個元素末尾追加一個子元素。
- 父元素.appendBefore( 待插入的元素, 哪個元素之前) 第二個參數爲null會將元素添加到最後。
- 關於insertAfter:父元素.insertBefore(待插入的元素, 哪個元素之前.nextElementSilbing)
- 父元素.replaceChild(替換的元素, 被替換的元素)
創建和刪除元素
創建元素
document.creatElement("元素名")
克隆元素
- dom對象.cloneNode(是否深度克隆): 複製一個新的dom對象並返回。
- 如果是深度克隆會將要克隆元素的innerHtml部分一起克隆,否則只會克隆元素本身,元素裏面的內容並不會被克隆。
- 元素.children() 會返回實時的所有子元素集合。
刪除元素
- removeChild: 父元素調用, 傳入子元素 通過父元素刪除子元素
- remove: 元素.remove() 把自己刪除
控制dom元素的類樣式
- className: 獲取或設置元素的類名
- classList:dom4的新屬性,是一個用於控制元素類名的對象。
- add:用於判斷一個類名是否存在
- remove:用於移除一個類名
- contains:用於判斷一個類名是否存在
- toggle:用於添加/刪除一個類名
獲取樣式
- dom.style:得到行內樣式對象。
- window.getComputedStyle(dom 元素): 得到某個元素最終計算的樣式。
- 可以有第二個參數,用於得到某個元素的某個僞元素樣式。
設置樣式
- dom.style.樣式名 = 值;
事件
mouseenter 和 mouseover的區別(mouseleave與mouseout):
- mouseover 和 mouseout 不考慮子元素,從父元素移動到子元素,對於父元素而言,仍然算作離開。
- mouseenter 和 mouseleave , 考慮子元素, 子元素仍是父元素的一部分。
- mouseenter 和 mouseleave 不會冒泡。
事件對象
- e.button 0 : 左鍵 1 : 滑輪 2 : 右鍵
- e.ctrlKey 當觸發事件時是否按下了ctrl鍵
- e.altKey 當觸發事件時是否按下了alt鍵
- e.shiftKey 當觸發事件時是否按下了shift鍵
位置:
- page: pageX、pageY,當前鼠標距離頁面的橫縱座標。
- client:clientX、clientY ,當前鼠標距離視口的橫縱座標。
- offset: offsetX、offsetY, 鼠標相對於事件源內邊距(內容 + padding )的座標。
- screen:screenX、screenY, 鼠標相對於屏幕-
- x、y,等同於clientX、clientY
- movement:movementX、movementY,只在鼠標移動事件中有效,相對於上一次鼠標位置,偏移的距離。
KeyboardEvent - code: 得到按鍵字符串,適配鍵盤佈局。
- key: 得到按鍵字符串,不適配鍵盤佈局。 能得到打印字符。
window和document裏的事件 - load、DomContentLoaded、readystatechange
- load:頁面中所有資源全部加載完畢的事件。
瀏覽器渲染頁面的過程:
1.得到頁面源代碼
2.創建document節點
3.從上到下依次執行代碼
4.將元素依次添加到dom樹中,每添加一個元素,進行預渲染
document.DomContentLoaded事件:dom樹構建完成後發生。
readyState: loading、interactive、complete
interactive:觸發DomContentLoaded
complete:觸發window的load事件。
console.log(document.readyState);
document.onreadystatechange = function(){} //當html狀態發生改變時觸發
beforeunload: window的事件,關閉窗口時運行,可以阻止關閉窗口 高版本的谷歌瀏覽器不支持
unload:window的關閉事件,關閉窗口時運行。
scroll
窗口發生滾動時運行的事件
通過scrollTop和scrollLeft,可以獲取和設置滾動距離。
獲取整個網頁的滾動高度:
document.documentElement.scrollTop + document.body.scrollTop;
resize
監聽視口尺寸變化的事件。
window.screen.height:獲取整個屏幕的高度。
window.outerHeight:獲取瀏覽器的整體高度。
window.innerWidth:獲取瀏覽器窗口的寬度(包含滾動條)。
document.documentElement.clientWidth:獲取瀏覽器視口的寬度(不包含滾動條)。
某個元素的offsetWidth:獲取元素(包含邊框和滾動條)的寬度。
某個元素的clientWidth:獲取元素(不包含邊框和滾動條)的寬度。
某個元素的scrollHeight:獲取元素裏實際內容的高度。
contextmenu: 右鍵菜單事件
paste 粘貼事件
copy 複製事件
cut 剪切事件
inp.onpaste = function(e) {
var txt = e.cli
pboardData.getData("text/plain); //獲取剪切板裏類型爲text/plain的數據。
if(txt && /\d+/.test(txt)){
}
}
元素位置
- offsetParent
獲取某個元素的第一個定位的祖先元素,如果沒有, 則得到body。
body的offsetParent爲null。
- offsetLeft、offsetTop
相對於該元素的offsetParent的座標
如果offsetParent是body,則將其當作是整個網頁(會有額外8px的空隙 ) - getBoundingClientRect
該方法得到一個對象,該方法記錄了該元素相對於視口的距離。
window
open
打開一個新窗口 window.open()返回一個window對象
<iframe name="myiframe" src="" frameborder="0"></iframe>
window.open("https://ww.js.com","_blank");
window.open("https://ww.js.com","myiframe");
location
屬性 | 描述 |
---|---|
hash | 返回一個url的錨部分 |
host | 返回一個url的主機名和端口 |
hostname | 返回url的主機名 |
href | 返回完整的url |
pathname | 返回url路徑名 |
port | 返回一個url服務器使用的端口號 |
protocol | 返回一個url協議 |
search | 返回一個url的查詢部分 |
reload方法:刷新當前頁面。
history
go方法
back方法
forword方法
console
log方法:打印對象的valueOf的返回值。
dir方法:打印對象結構