ECMA-262 的第 5 版是 JS 的第一個穩定版本,獲得了各瀏覽器廠商的支持。
javascript
文檔對象模型是針對 XML 但通過擴展用於 HTML 的 API 。DOM 把整個頁面映射爲一個多層次節點結構。HTML 或 XML 頁面中的每一個組成部分都是某種類型的節點,這些節點又包含着不一樣類型的數據。
document object model 文檔對象模型,裏面提供了一些屬性和方法,可讓咱們操做頁面的元素css
原則上講,BOM只處理瀏覽器窗口和框架,但下面一些針對瀏覽器的 JS 擴展也被看作是BOM的一部分。
browser object model 瀏覽器對象模型,裏面提供了一些屬性和方法,可讓咱們操做瀏覽器。html
<div onclick="alert('hello world')"></div>
複製代碼
<script> alert('hello world') </script>
複製代碼
// 新建一個js文件
<script src="./js/demo.js"></script>
// or
<script src="./js/demo.js" type="text/javascript"></script>
複製代碼
內嵌導入和外鏈導入不能合併在一塊兒,若是當前是外鏈導入的,那麼在script腳本塊找那個編寫的全部代碼都不會被執行。java
<script src="./js/demo.js">
alert('hello world')
</script>
複製代碼
咱們通常性會把css放在body的上面,把js放在body末尾(約定速成的規範)node
可是若是放在了標籤前面那麼將如何處理?面試
頁面加載完全部資源以後執行操做編程
在js中json
window.onload=function(){
}
複製代碼
在jq中後端
$(document).ready(function(){
})
window.addEventListener('load',function(){},false);
// ie8如下
window.attachEvent('onreadystatechange',function(){
})
複製代碼
alert(1)
alert({name:'wjw'}) //=> '[object Object]'
alert([13,14]) //=> '12,13'
複製代碼
var wjw = confirm("are you sure");
alert(wjw);
複製代碼
var flag = prompt("are you sure");
alert(flag)
複製代碼
控制檯輸出,方便開發調試數組
console.log({name:'wjw'});
console.dir() //比log輸出更加詳細一些
console.table //把json數據展現成一個表格
複製代碼
語法 ECMAScript 的語法大量借鑑了 C 及其餘類 C 語言(如 Perl 和 Java)的語法。 區分大小寫
// 單行註釋
/* * 這是一個多行 * (塊級)註釋 */
複製代碼
嚴格模式 ES5 引入了嚴格模式的概念,在嚴格模式下,ES3 中的一些不肯定行爲將獲得處理,並且隊某些不安全的操做也會拋出錯誤。要在整個腳本中啓用嚴格模式,能夠在頂部添加以下代碼:
這行代碼看起來像是字符串,並且也沒有賦值給任何變量,但其實它是一個編譯指 示(pragma),用於告訴支持的JavaScript引擎切換到嚴格模式。在函數內部的上方包含這條編譯指示,也能夠指定函數在嚴格模式下執行:
function doSomething(){
"use strict"; //函數體
}
複製代碼
變量是能夠變得 常量是不可變的
js定義變量的方法
// var 變量名 = 值;
var num = 12;
var name = 'wjw'
複製代碼
const num = 12;
複製代碼
var test = 'wjw';
var Test = 'wjh';
console.log(test);
// 輸出test
複製代碼
第一個單詞首字母小寫,其他每個有意義單詞首字母大寫
var studentInfo; // 學生信息
// 所見即所得
// 例子:
/* * info : information 信息 * init : initlization 初始化 * add/insert/create 增長插入建立 * remove/rm/clear/del/delete 刪除 * update 修改 * get/query/select : 查詢獲取 */
複製代碼
var student_info;
var $xxx; //=> 通常都是應用jq得到到的值
var _xxx; //=> 通常這樣的狀況表明變量是一個局或者公共的變量
複製代碼
操做符 typeof 是用來檢測給定變量的數據類型的操做符。對一個值使用 typeof 操做符可能返回下列某個字符串:
"undefined"
"boolean"
"string"
"number"
"object" // 若是這個值是對象或者null "function"
複製代碼
Boolean()
歎號在JS中海油一個做用:取反,先把值轉換爲布爾類型,而後再去取反
!!
在歎號取反的基礎上取反,取反兩次至關於沒有操做,可是卻已經其餘類型值轉化爲布爾類型了,和Boolean是相同的效果
在JS中單引號和雙引號包起來的都是字符串
12 - > number
'12' -> string
'[12,23]' -> string
複製代碼
第一種是使用幾乎每一個值都有的 toString()方法。多數狀況下,調用 toString() 方法沒必要傳遞參數,但在調用數值的 toString()方法時,能夠傳遞一個參數:輸出數值的基數。默認狀況下,toString() 方法以十進制格式返回數值的字符串表示。而經過傳遞基數,toString() 能夠輸出二進制、八進制、十六進制等。
var num = 10;
alert(num.toString()); // "10"
alert(num.toString(2)); // "1010"
alert(num.toString(8)); // "12"
alert(num.toString(10)); // "10"
alert(num.toString(16)); // "A"
複製代碼
經常使用方法
0 12-22 12.5 js中多增長了一個number類型的數據NaN typeof NaN -> Number
var intNum = 55; // 十進制整數 var octalNum1 = 070; // 八進制的56
var octalNum1 = 079; // 無效的八進制數值——解析爲79
var octalNum1 = 08; // 無效的八進制數值——解析爲8
var hexNum1 = 0xA; // 十六進制的10
var hexNum2 = 0x1F; // 十六進制的31
複製代碼
注意,八進制字面量在嚴格模式下是無效的,會致使拋出錯誤。
ECMAScript 可以表示的最小數值保存在 Number.MIN_VALUE 中——在多數瀏覽器中,這個值是 5e-324;可以 Number.MAX_VALUE 中——在大多數瀏覽器中,這個值是1.7976931348623157e+308。若是某次計算的結果獲得了一個超過JavaScript 數值範圍的值,那麼這個數值將會自動轉換爲 Infinity 值,若是這個數值是負數,則會轉換成 -Infinity(負無窮),若是這個數值是正數,則會轉換成Infinity(正無窮)。要肯定一個數值是否是有窮的,可使用 isFinite() 函數。
isNaN(0) // ->false
isNaN(NaN) // ->true
複製代碼
isNaN('12') //->false
複製代碼
Number('12') // -> 12
Number('12px') // ->NaN
// 在使用Number轉換的時候只要字符串中出現任何一個非有效數字字符,最後的結果都是NaN
Number(true) //-> 1
Number(false) //-> 0
Number(null) // -> 0
Number(undefined) //->NaN
複製代碼
Number([]) // -> ""
Number([12]) // -> 12
Number([12,13]) // -> 12,13 (,是非有效字符) -> NaN
Number({age:12}) // ->NaN
Number({}) // -> NaN
複製代碼
Number('12px') // -> NaN
parseInt('12px') // -> 12
複製代碼
parseInt('12px13') // -> 12
複製代碼
處理整數最經常使用的仍是 parseInt() ,它會忽略字符前面的空格,直到找到第一個非空格字符。若是第一個字符不是數字字符或者負號,parseInt() 就會返回 NaN;也就是說,用 parseInt() 轉換空字符串會返回 NaN 。若是第一個字符是數字字符, parseInt() 會繼續解析第二個字符,直到解析完全部後續字符或者遇到了一個非數字字符。若是字符以「0x」開頭且後面跟數字字符,會被解析爲 16 進制整數;
以「0」開頭且後面跟數字字符,會被解析爲 8 進制整數。下面給出一些例子:
var num1 = parseInt("1234blue"); // 1234
var num2 = parseInt(""); // NaN
var num3 = parseInt("0xA"); // 10(十六進制)
var num4 = parseInt(22.5); // 22
var num5 = parseInt("70"); // 70
var num6 = parseInt("0xf"); // 15(十六進制)
複製代碼
pareInt('12.5px') -> 12
pareFloat('12.5px') -> 12.5
複製代碼
ECMAScript 中的對象其實就是一組數據和功能的集合。對象能夠經過執行 new 操做符後跟要建立的對象類型的名稱來建立。而建立 Object 類型的實例併爲其添加屬性和(或)方法,就能夠建立自定義對象,以下所示:
var o = new Object();
複製代碼
每個對象都是由零到多組 屬性名(key鍵):屬性值(value值) 組成的,或者說有多組鍵值對組成的,每一組鍵值對中間用逗號分隔
描述這個對象特色特徵的
var obj ={name:'wjw',age:8};
複製代碼
某個屬性名對應的屬性值或者數字格式的
obj.name
obj['name']
複製代碼
屬性值能夠是任何數據類型
// 若是屬性名是數字如何操做
obj.0 語法不支持
obj[0] / obj['0'] 兩種都支持
複製代碼
若是操做的屬性名在對象中不存在,獲取的結果是undefined
obj.sex // ->undefined
複製代碼
一個對象的屬性名是不能重複的(惟一性),若是以前存在就是修改屬性值的操做,反之不存在就是新的設置屬性的操做
obj.sex = '男';
obj['age'] = 9;
複製代碼
obj.sex = null;
複製代碼
delete obj.sex
複製代碼
JS是運行在瀏覽器中的(內核引擎),瀏覽器會爲JS提供賴以生存的環境(提供給js代碼執行的環境)=> 全局做用域window(global)
var a = 12;
var b = a; // 把A變量存儲的值賦值給B
b = 13;
console.log(a);
var n ={name:'wjh'};
var m = n;
m.name = 'wjw'
console.log(n.name)
複製代碼
函數數據類型也要按照引用地址來操做的
函數:具有必定功能的方法
// => 建立函數:
function 函數名(){
//=> 函數體:實現某一個功能的具體JS代碼
}
// => 執行函數:至關於使用洗衣機洗衣服(若是函數只建立了,可是沒有去執行,函數沒有任何的意義)
// 函數名()
複製代碼
function fn(){
console.log(1+1);
}
fn; // => 輸出函數自己
fn(); // => 把函數執行(吧函數體重實現功能的代碼執行)
複製代碼
形參:形式參數(變量),函數的入口
當咱們建立一個函數想要實現個功能的時候,發現有一些材料不清楚,只有當函數運行的時候,別人傳遞給我,我才知道,此時咱們就須要設定入口,讓用戶執行的時候經過入口把值把咱們
function fn(num1,num2){
console.log(num1+num2)
}
// 實參:函數執行傳遞給函數的具體值就是實參
fn(1,2);
fn(10,20);
複製代碼
把其餘數據類型轉換爲number類型
-> isNaN、Number、pareInt、parseFloat
-> 在進行數據加減乘除數學運算的時候
// true -> 1 false->0
// ''->0 '12'->12 '12px'->NaN/12
// '小夥子'->NaN
// null -> 0
// undefined-> NaN
{} /^$/ function() ->NaN
[]
[12]->'12'->12
['12,13']->'12,23'->NaN
// => 引用數據類型轉換爲數字
// 經過toString方法把數組轉換爲字符串,而後在調用Number轉換爲數字
複製代碼
1-'1' -> 0
10*null -> 0
10/undefined -> NaN
10*[10]->100
複製代碼
1+'1' -> '11'
null+'1' -> ‘null1’
複製代碼
[] -> true
-1 -> true
if(box){
// => 首先把box變量存儲的值獲取到,轉化爲布爾類型,若是爲true條件成立,反之不成立
}
if(3+'3px'){
// 條件成立: 3 + '3px' = '33px'
}
if(3-'3px'){
// 條件不成立: 3-'3px' = NaN
}
複製代碼
在使用==進行比較的時候,若是左右兩邊的數據不相同,瀏覽器默認轉換爲相同的類型,而後在比較('==='不會這樣操做)
// 對象和對象: 應用數據類型比較的空間地址不同,不是一個空間
[] == [] -> false
var a ={}
var b = a;
a==b -> true
複製代碼
[]== 0 -> true
({})=== NaN -> false
NaN和本身不相等和其它任何值都不相等
複製代碼
[]==='' -> true
複製代碼
[]==true -> 0==1 ->false
[]==false -> 0==0 ->true
![]==false -> ![] ->把數組變成爲布爾在取反=false
false=false -> true
複製代碼
字符串和數字:字符串轉換爲數字
字符串和布爾:都轉爲數字
布爾和數字:布爾轉換爲數字
規律:兩個等於號比較,左右兩邊數字值的類型不同,瀏覽器會吧兩邊的類型都轉換爲數字而後再比較,可是null和undefined除外
null==undefined -> true
null===undefined -> false
null 和 undefined 和其它任何都不相等
null==0 -> false null以及undefined和其它任何值都不相等
判斷操做語句
if(條件1){
//=>條件1成立執行的操做
}else if(條件2){
//=>上面條件不成立,條件2成立,執行的操做
}
...
else{
// => 以上條件都不成立執行的操做
}
複製代碼
若是好幾個條件都成立了,只吧第一個成立的條件執行,後面成立的條件忽略無論
條件:
A==B、A!=B、A>B、A<B
if(A){} // 先把A轉換爲布爾類型,判斷真假以此來決定是否成立
//否成立
if(A>B&&A<10){} //只有兩個小條件都是真,總體條件爲真
if(A>B||A<10){} // 只要其中一個小條件成立,總體條件是真
複製代碼
BAT 面試題
var num = parseFloat('width:12.5px');
if(num==12.5){ // =>NaN
alert(12.5);
}else if(num==NaN){ // NaN!=NaN
alert(NaN);
}else if(typeof num=='number'){ //
alert(0)
}else{
alert("啥也不是")
}
複製代碼
條件?條件成立執行:條件不成立執行
if(條件){}else : 三元運算符就是這種簡單if..else..的另外一種寫法
var num = 10;
if(num>5&&num<10){
num++;//累加1
}else{
num--;
}
// 修改爲爲三元運算符,若是條件成立或者不成立的某一種狀況並不須要什麼處理
// 咱們空着語法不符合,咱們使用null、undefined、void 0(就是undefined)佔位就能夠
num>5&&num<10?num++:num--;
複製代碼
var num = 10;
if(num>5 && num<10){
num++;
break;/continue;/return;
}
// => 修改爲爲三元運算符
// 在三元運算符的操做中不能出現break、continue、return這樣的關鍵詞,因此咱們沒法用三目代替if、else
num>5 && num<10?
(num++,return):null;
複製代碼
swith case應用於if、else中一個變量在不一樣值狀況下的不一樣操做
var num =10;
switch(num){
//switch後面小括號中存放的是一個值(通常咱們都寫變量;把變量存儲的值拿來用,有時候也多是一個計算)
case 1:
// case後面放的都是值,目的驗證switch後面的值和哪種case後面的值相等,相等的進行對應的處理
...
break;
// 每一種case借宿後都要加break借宿當前的判斷
case 10:
...
break;
default:
// switch後面的值和每一種case狀況對應的值都不相等,執行最後的default,相似於false
...
}
複製代碼
案例分析
var num = 5;
switch(num%2){//=>先把取餘操做進行運算,拿運算結果case比較
case 0:
num++;
break; //不加break,無論後面的條件是夠成立,都會繼續向下執行,知道遇到break爲止
// 不加break,就能夠實現||這樣的操做
case: 2-1: //case後面也應該是值,此處先把2-1計算,把計算的結果和switch值比較
num--;
// 最後一項能夠不加break,不加也能跳出判斷
break;
}
num%2:讓num存儲的值除以2去餘數(0或者1)
複製代碼
swich case 中的比較實用的"==="
循環,重複作一件事情
for(設置循環起始值;設置循環執行的條件;步長累加){
// 循環體:重複作的事情都是在循環體重
}
複製代碼
for(;i<5;;){
consloe.log(i);
//沒有步長累加,咱們的i永遠是0,循環條件永遠成立「死循環」;
//項目中不能出現死循環,一旦出現,循環下面的事情都作不了
}
複製代碼
結束本輪循環,繼續執行下一輪:循環體重continue後面的代碼都不會在執行,它會直接的去執行步長,而後進行下一輪
for(var i=0;i<5;i+=2){
console.log(i)
continue;
}
複製代碼
結束整個循環:循環體重一旦遇到break首前後面代碼不執行了,並且步長累加也不執行了,循環都結束了
for(var i=0;i<5;i+=2){
console.log(i)
break;
}
複製代碼
BAT面試題
for(var i=1;i<10;i+=2){
if(i<5){
i++;
continue;
}else{
i+=3;
break;
}
console.log(i)
}
console.log(i) // =>10
複製代碼
用來遍歷(循環)對象鍵值對的
var obj = {name:wjw,age:8,0:'wjh',3:'ylp',1:'cx'}
for(var key in obj){
console.log('ok')
// key 屬性名 string
console.log(obj.key)
//獲取obj中key這個屬性對應的值 ->undefined <=> obj['key']
console.log(obj[key]);
//->每一次循環把key變臉存儲的值(當前遍歷的屬性名)獲取到放在中括號中,獲取obj對應的屬性值
}
for(var key in obj){
if(obj.hasOwnProperty(key)){
}
}
複製代碼
DOM:document object model 文檔對象模型,提供一些屬性和方法可讓咱們去操做DOM元素
node 節點,瀏覽器默認在一個html頁面中的全部內容都是節點(包括標籤、註解、文字文本等)
元素節點
[curEle].tagName:獲取當前元素的標籤名(獲取的標籤名通常都是大寫)
文本節點
nodeType:3
nodeName:#text
nodeValue:文本內容
註釋節點
nodeType:8
nodeName:#comment
nodeValue:註釋內容
文檔節點
nodeType:9
nodeName:#document
nodeValue:null
<-- div#box>(ul>li{0$}*3)+div{內容$}*3-->
<div id="box">
<ul>
<li>01</li>
<li>02</li>
<li>03</li>
</ul>
<div>內容1</div>
<div>內容2</div>
<div>內容3</div>
</div>
複製代碼
<div id="box1"></div><div id="box2"></div><div id="box1"></div>
<script>
console.log(box1) // -> [div#box1, div#box1, box1: div#box1]
</script>
複製代碼
<input id="myInput" type="text" size="20"/><br />
<script> var x=document.getElementsByName("myInput"); </script>
複製代碼
<input name="myInput" type="text" size="20"/><br /> <script> var x=document.getElementsByName("input"); </script> var bodyBox = document.getElementsByTagName('body'); bodyBox[0].getElementsByTagName('div'); 複製代碼
<input name="myInput" type="text" size="20"/><br />
<script> var x=document.getElementsByName("input"); </script>
複製代碼
經過元素的NAME屬性值獲取一組元素(類數組:節點集合NodeList) 他的上下文只能是document
<input name="myInput" type="text" size="20"/><br />
<script> var x=document.getElementsByName("myInput"); </script>
複製代碼
document.documentElement.clientWidth||document.body.clientWidth
// 獲取當前瀏覽器可視區域的寬度(當前頁面一個屏幕的寬度)
// =>clientHieght 獲取高度
複製代碼
querySelector 獲取一個元素對象
querySelectorAll 獲取的一個元素集合
只要css支持的選擇器,這裏大部分都支持
document.querySelector('#box1');
document.querySelectorAll('.box1');
document.querySelectorAll('div');
document.querySelectorAll('body>div');
document.querySelectorAll('#box1 li');
複製代碼
節點是用來描述頁面中每一部門之間關係的,只要我能夠獲取頁面中的一個頁面,那麼我就能夠經過相關的屬性和方法獲取頁面中全部的節點
獲取當前元素全部的子節點(節點集合:類數組) 注:不只僅是元素子節點,文本、註釋等都會包含在內:子節點說明只是在兒子輩分中查找
獲取全部的元素子節點(元素集合) 在IE6-8下獲取的結果和標準瀏覽器中有區別(IE6-8中會把註釋點當作元素節點獲取到)
獲取當前元素的父節點(元素對象)
獲取當前節點的上一個各個節點上一個哥哥節點(不必定是元素節點也多是文本或者註釋)
獲取當前節點的下一個弟弟節點
獲取當前節點的上一個哥哥元素節點
獲取當前節點下一個弟弟元素節點 IE6-8不兼容
當前元素全部子節點中的第一個(也不必定是元素節點,多是文本和註釋)
當前元素多有子節點中的最後一個 fistElementChild lastElementChild(IE6-8兼容)
真實項目中,咱們偶爾會在js中動態建立html標籤,而後把其增長到頁面中
在js中動態建立一個html標籤
容器.appendChild(新元素) 把當前建立的新元素添加到容器的末尾位置
容器.inserBefore(新元素、老元素) 在當前容器中,把新建立的元素增長到老元素以前
// 建立
var oDiv = document.createElement('div');
oDiv.id='div1';
oDiv.className = 'box';
// 添加到頁面中
document.body.appendChild(oDiv);
document.body.inserBefore(oDiv,box2);
複製代碼
var link = document.createElement('a');
link.href = 'http://www.baidu.com?name=1&age=2#haha'
consloe.dir(link);
// hash:存儲餓哈希值 '#haha'
// hostname:域名 'www.baidu.com'
// pathname:路徑 '/stu/'
// protocol:協議 'http:'
// search:問號傳遞參數值 '?nname=1&age=2'
複製代碼
真實項目中不少須要經過動態建立元素來完成的,其中有一個需求:解析一個url地址每一部分的信息(包括問號傳值的參數值)
function queryURLParameter(url){
var link = document.createElement('a');
link.href=url;
var search = link.search,
obj = {}'
if(search.length===0) return;
search = search.substr(1).split(/&|=/g);
for(var i=0;i<search.length;i+=2){
var key = search[i],
value = search[i+1];
obj[key]=value;
}
link = null;
return obj;
}
複製代碼
給當前元素設置/獲取/移出屬性的(通常操做的都是它的自定義屬性)
box.setAttribute('myIndex',0)
box.getAttribute('myIndex')
box.removeAttribute('myIndex')
複製代碼
使用xxx.index=0 和xxx.setAttribute('index',0)這兩種設置自定義屬性的區別
xxx.index : 是吧當前操做的元素當作一個普通對象,爲其設置一個屬性名
xxx.setAttribute:把元素當作特殊的元素對象來處理,設置的自定義屬性是和頁面結構中的DOM元素映射在一塊兒的
JS中獲取的元素對象,咱們能夠把他理解爲兩種角色:
元素對象中的內置屬性,大部分都和頁面的標籤存在映射關係:
xxx.style.backgroundColor = 'xxx' 此時不只把js中對象對應的屬性值改變了,並且也會映射到頁面的html標籤上(標籤中有一個style行內樣式,元素的樣式改變了)
xxx.className = 'xxx'此時不只是吧js對象中的屬性值改變了,並且頁面中的標籤增長了class樣式類(能夠看見的)
元素對象中的自定義屬性: xxx.index=0
僅僅是吧js對象中增長了一個屬性名(自定義的),和頁面中的html沒啥關係(在結構上看不見)
xxx.setAttribute:經過這種方式設置的自定義屬性和以前提到的內置屬性差很少,都是和html結構存在映射關係的(設置的自定屬性能夠呈如今結構上)
把當前頁面中全部id叫作box1的都獲取到
var allList = document.getElementsByTagName(*);
var result = []
for(var i=0;i<allList.length;i++){
var item = allList[i];
item.id === 'box1'?result.push(item)
}
console.log(result)
複製代碼
獲取當前元素的上一個哥哥元素節點(兼容全部的瀏覽器) curEle:current element
// 首先獲取當前元素的上一個哥哥節點,判斷當前獲取的節點是否爲元素節點(nodeType===1)
// 若是不是基於當前獲取的節點,找他的上一個哥哥節點..(找幾回不知道)一直到找到的節點是元素節點爲止
// 若是在查找過程當中,發現沒有上一個哥哥節點,找到頭了,則再也不繼續查找
function prev(curEle){
var p = curEle.previousSibling; // 屬性返回同一樹層級中指定節點的前一個節點。
while(p&&p.nodeType!==1){ //p:p!=null
p = p.previousSibling;
}
return p;
}
// 擴展
// next: 獲取下一個弟弟元素節點
// prevAll:獲取全部的哥哥元素節點
// nextAll:獲取全部的弟弟元素節點
// siblings:獲取全部的兄弟元素節點
// index:獲取當前元素的兄弟中排名索引
複製代碼
可是他是對象數據類型的
abs
Math.abs 取絕對值
cell / floor
cell: 向上取整 floor: 向下取整
round
round: 四捨五入
random
random: 獲取一個[0,1]之間的一個隨機小數
max/minx
max 獲取一組值中的最大值 minx 獲取一組值中的最小值
PI
Math.PI 獲取圓周率
pow / sqrt
pow 獲取一個值的多少冪 sqrt 獲取一個值的開平方
在js中用單(雙)引號包裹起來的都是字符串
var str = 'welcome to credan!'
複製代碼
字符串就是由零到多個字符串組成的
第一個字符索引0
第二個字符索引1
...
有length的屬性,存儲的是當前字符串中字符的個數(字符串的長度)
以數字做爲索引,從零開始的
str[0] -> 'w' 第一個字符
strlength-> 46
str[str.length-1] -> '!' 最後一個字符
str[100] -> undefined 若是指定的索引不存在獲取的結果是undefined
真實項目中,咱們常常操做字符串,此時咱們須要掌握經常使用的一些字符牀操做方法
console.dir(String.prototype)
charAt && charCodeAt
在charAt 基礎上,把獲取的字符變爲Unicode編碼值(對應ASCll碼錶)
String.fromCharCode(十進制的Unicode值),把值按照ascll碼錶中的信息,轉爲原有字符,charCodeAt正好對應
當索引是負數的時候,瀏覽器在處理的時候,是用字符串的總長度加上負數索引,而後按照正數處理操做
細節:
indexOf && lastIndexOf
若是當前字符在字符串中沒有出現過,結果是-1:咱們根據這個規律可言驗證一下當前字符串中是否包含某個字符
if(str.indexOf('?')===-1){
// => 沒有出現過
}
if(str.indexOf('?')>=-1){
// => 出現過
}
複製代碼
str.split 按照某個字符串分紅數組中的某一項,和數組中的join方法是對應
str.replace 實現字符的替換 執行一次replace 只能替換一次,若是有好幾個都須要替換,在不適用正則的狀況下,咱們須要執行不少次replace
有些需求及時執行不少次repalce也實現不了,此時須要使用正則處理,真實項目中replace通常都是和正則搭配使用的
獲取地址欄的值
function queryURLPrameter(url){
// => url 傳遞的參數
var quesIndex = url.indexOf('?'),
obj = {}
if(quesIndex === -1){ // url中沒有問號傳參 直接返回空
retrun obj;
}
url = url.substr(quesIndex + 1);
var ary = url.split('&');
for(var i =0;i<ary.length;i++){
var curAry = ary[i].split('=');
obj[curAry[0]] = curAry[i];
}
return obj
}
複製代碼
String.prototype.myQueryURLParameter = function myQueryURLParamter(){
var obj = /([^=?&]+)=([^=?&]+)/g;
this.replace(reg,function(){
var arg = argments;
obj[arg[1]] = arg[2]
})
return obj;
}
var str = 'https://www/baidu.com/s?wd=1233213&issp=1';
console.log(str.myQueryURLParameter());
複製代碼
經過它能夠對時間進行處理
var time = new Date();
// 獲取當前客戶端本機時間(當前獲取的時間不能做爲重要的參考依據)
// 獲取結果是一個日期格式的對象
// Wed Mar 20 2019 17:37:16 GMT+0800 (中國標準時間)
typeof new Date() -> object
time.getFullYear() 獲取四位數全年
time.getMonth() 獲取月份
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-22');
// 當new Date 中傳遞一個時間格式的字符串,至關於把這個字符串換位標準時間對象
// (轉換完成後,就能夠調取上面咱們講的那些方法)
複製代碼
// 時間格式的字符串
'2017-10-22' (IE下識別不了)
'2017/10/22 16:15:34'
'1508659621314'(若是傳遞的是距離1970年那個毫秒查,也能夠識別轉換的,可是隻能是數字,不能是字符串)
類數組:相似於數組,可是不是數組
// for 循環操做
for(var i =0;i<ary.length;i++){
console.log(ary[i])
}
// for in 循環操做
for(var key in ary){
// key:屬性名(數組中的屬性名是索引)
console.log(ary[key]);
}
// for 循環只能遍歷到數組私有的一些屬性,而for in 循環能夠吧一些自定義的公共屬性也能遍歷到
複製代碼
數組中有不少方法
console.dir(Array.prototype)
複製代碼
實現數組的增長、修改、刪除
參數:一到多個,任何數據類型均可以,想要給數組末尾追加什麼,直接傳遞到push方法中極客,傳遞多個逗號隔開
返回值:新增後數組的長度
原有數組改變了
參數:須要追加的內容(能夠是多個任何數據類型的值)
返回值:新增後 數組的長度
原來數組改變了
把數組當作一個普通的對象,使用對象鍵值對的操做,給其設置新的屬性(索引)
ary[ary.length]=xxx 向數組的末尾追加了新的內容
參數:無
返回值:被刪除的那一項內容
原有數組改變了
參數:無
返回值:被刪除那一項的內容
原有數組改變了
使用shift刪除第一項以後,後面每一項的索引都要向前進一位(致使後面項的索引起生了改變)
把數組當作一個普通對象操做
delete刪除:delete ary[索引]刪除指定索引這一項(當前項被刪除後),原有數組其它項的索引不會改變:當前數組的length也不會改變
ary.length--:刪除數組最後一項
splice實現刪除
splice(n,m):從索引n開始刪除m個(m不寫是個刪除列數組的末尾,n也不寫)
返回值:被刪除的內容(以一個新數組保存)
原有數組改變了
splice(0) 清空數組
splice() 一項都不刪除,返回一個新的空數組
splice(0,1)刪除第一項
splice(n,m,x):在原有刪除的基礎上,用x代替刪除的內容
splice實現增長
splice(n,0,x):在修改的基礎上,咱們一項都不刪除,把x插入到索引n的前面
ary.splice(0,0,x) 向數組末尾追加新元素
數組的查詢
slice(n) 從索引n開始找到末尾
slice(0) /slice() 數組克隆,克隆一份和原來數組如出一轍的的新數組
slice支持負載索引,若是傳遞的索引爲負數,瀏覽器解析的時候是按照總長度+負數索引 來處理的
concat:將多個數組拼接在一塊兒
原有數組不變
slice: 數組的查詢
參數: slice(n,m) 從索引n開始找到索引爲m處(不包含m)
返回值:把找到的部分已一個新數組返回
原來的數組不變
slice(n) 從索引n開始找到末尾
slice(0) / slice() 數組克隆,克隆一份和原來數組如出一轍的新數組
slice 支持負數索引,若是傳遞的索引爲負數,瀏覽器解析的時候是按照,總長度+負數索引 來處理的
複製代碼
concat:將多個數組拼接在一塊兒
參數:要拼接的內容(把內容放在原數組的後面),能夠是一個數組,也能夠是一些數據值
返回:拼接後的新數組
原有的數組不變
let arr = [0,100]
arr.concat([100,200],[200,300],12)
複製代碼
concat() 什麼都沒有拼接,至關於吧原有數組克隆一份如出一轍的出來
實現吧數組轉化爲字符串(轉換後的字符串逗號分隔每一項)
把數組按照指定的分隔符轉換爲字符串,和字符串中的split相對應
已知數組的每一項都是數字,想事先數組求和,咱們如何實現?
循環實現
var total = null;
for(var i=0;i<ary.length;i++){
total+=ary[i];
}
複製代碼
利用join
var total = eval(ary.join('+')) // evel:把字符串變爲js表達式執行
複製代碼
把數組中每一項倒過來排序
實現數組的排序
參數:無或者回調函數
返回值:排序後的數組
原有數組改變
不傳遞參數的狀況下:能夠給10之內的數字進行升序排列,可是超過10的就沒法處理(多位數值識別第一位)
ary.sort(function(a,b){
return a-b; //升序
return b-a; //降序
})
複製代碼
獲取當前如今數組中第一次或者最後一次出現的位置索引
if(ary.indexOf(12)>-1){
// 數組中包含12
}
複製代碼
Array.prototype.myIndexOf = function myIndexOf(value){
var result = -1;
for(var i =0;i<this.length;i++){
if(value===this[i]){
result = i;
break;
}
}
return result;
}
複製代碼
如下方法ie6-8下都不兼容
遍歷數組中的每一項
ary.forEach(function(value,index){
/* 數組中有多少項,當前回調函數執行多少次,妹妹一次傳進來的value就是當前遍歷數組這一項的值,index 就是遍歷這一項的索引 */
})
複製代碼
遍歷數組中的每一項,在forEach的基礎上,能夠修改每一項的值
ary.map(function(value,index){
/* 數組中有多少項,當前回調函數執行多少次,妹妹一次傳進來的value就是當前遍歷數組這一項的值,index 就是遍歷這一項的索引 */
return xxx;
// return 後面返回的結果就是當前遍歷的這一項修改成xxx
})
複製代碼
filter
find
reduce
every
...
var ary = [1,2,3,4,5,6,7,1,3,4,5];
遍歷數組的每一項,拿每一項和它後面的項依次比較,若是相同了,則把相同的這一項在原來數組中刪除便可
/* * 新建一新數組,遍歷傳入數組,值不在新數組就push進該新數組中 * IE8如下不支持數組的indexOf方法 * */
function uniq(array){
var temp = []; //一個新的臨時數組
for(var i = 0; i < array.length; i++){
if(temp.indexOf(array[i]) == -1){
temp.push(array[i]);
}
}
return temp;
}
var aa = [1,2,2,4,9,6,7,5,2,3,5,6,5];
console.log(uniq(aa));
複製代碼
/* * 速度最快, 佔空間最多(空間換時間) * * 該方法執行的速度比其餘任何方法都快, 就是佔用的內存大一些。 * 現思路:新建一js對象以及新數組,遍歷傳入數組時,判斷值是否爲js對象的鍵, * 不是的話給對象新增該鍵並放入新數組。 * 注意點:判斷是否爲js對象鍵時,會自動對傳入的鍵執行「toString()」, * 不一樣的鍵可能會被誤認爲同樣,例如n[val]-- n[1]、n["1"]; * 解決上述問題仍是得調用「indexOf」。*/
function uniq(array){
var temp = {}, r = [], len = array.length, val, type;
for (var i = 0; i < len; i++) {
val = array[i];
type = typeof val;
if (!temp[val]) {
temp[val] = [type];
r.push(val);
} else if (temp[val].indexOf(type) < 0) {
temp[val].push(type);
r.push(val);
}
}
return r;
}
var aa = [1,2,"2",4,9,"a","a",2,3,5,6,5];
console.log(uniq(aa));
複製代碼
/* * 給傳入數組排序,排序後相同值相鄰, * 而後遍歷時,新數組只加入不與前一值重複的值。 * 會打亂原來數組的順序 * */
function uniq(array){
array.sort();
var temp=[array[0]];
for(var i = 1; i < array.length; i++){
if( array[i] !== temp[temp.length-1]){
temp.push(array[i]);
}
}
return temp;
}
var aa = [1,2,"2",4,9,"a","a",2,3,5,6,5];
console.log(uniq(aa));
複製代碼
/* * * 仍是得調用「indexOf」性能跟方法1差很少, * 實現思路:若是當前數組的第i項在當前數組中第一次出現的位置不是i, * 那麼表示第i項是重複的,忽略掉。不然存入結果數組。 * */
function uniq(array){
var temp = [];
for(var i = 0; i < array.length; i++) {
//若是當前數組的第i項在當前數組中第一次出現的位置是i,才存入數組;不然表明是重複的
if(array.indexOf(array[i]) == i){
temp.push(array[i])
}
}
return temp;
}
var aa = [1,2,"2",4,9,"a","a",2,3,5,6,5];
console.log(uniq(aa));
複製代碼
// 思路:獲取沒重複的最右一值放入新數組
/* * 推薦的方法 * * 方法的實現代碼至關酷炫, * 實現思路:獲取沒重複的最右一值放入新數組。 * (檢測到有重複值時終止當前循環同時進入頂層循環的下一輪判斷)*/
function uniq(array){
var temp = [];
var index = [];
var l = array.length;
for(var i = 0; i < l; i++) {
for(var j = i + 1; j < l; j++){
if (array[i] === array[j]){
i++;
j = i;
}
}
temp.push(array[i]);
index.push(i);
}
console.log(index);
return temp;
}
var aa = [1,2,2,3,5,3,6,5];
console.log(uniq(aa));
複製代碼
functoin [函數名](){
// => [函數體]
// 實現功能的具體js代碼
}
複製代碼
函數名(); // 建立的函數執行,並且這個函數能夠執行不少次
函數名();
複製代碼
每一次執行都至關於把函數體重實現功能的js代碼重複執行了一遍
在真實的項目中,咱們通常都會把實現一個具體功能的代碼封裝到函數中
低耦合高內聚
咱們把以上的特色成爲函數封裝 (OOP面向對象編程思想,須要咱們掌握的就是類的繼承、封裝、多態)
函數做爲js中引用數據類型中的一種,也是按照引用地址操做的
function sum(){
var total = 1+1;
total *= 20;
console.log(total.toFixed(2));
}
sum();
複製代碼
私有做用域
(只能執行函數中以前編寫的js代碼)函數執行會造成一個私有的做用域,讓裏面的私有變量和外界互不影響(相互干擾、外面的沒法直接獲取裏面的變量值),此時咱們能夠理解爲私有做用域把私有變量保護起來,咱們把這種保護機制稱爲爲
閉包
做用域(全局做用域/私有做用域):提供一個供js代碼執行的環境
全部的引用數據類型,他們須要存儲的內容都是堆內存中(至關於一個倉庫,目的是存儲信息)
// 隨便求出兩個數的和
function sum(num1,num2){ //num1/num2就是形參變量(相似於var了一下)
var total = num1 + num2;
total*=10;
total=total.toFixed(2);
console.log(total);
}
sum(10,20);//10/20是實參 num1=10 num2=20
sum(10); // num1=10 num2=undefined 定義了形參可是執行的時候,沒有傳遞實參,默認實參就是undefined
複製代碼
當咱們不知道用戶具體要傳遞幾個值的時候(傳遞幾個值都行),此時咱們沒法設置形參的個數:遇到此類須要,須要使用函數內置的實參集合:arguments
function sum(){
console.log(arguments)
}
sum(10,20,'wjh',{name:'wjw'});
複製代碼
function sum(){
console.log(arguments.callee.caller);//f
}
function fn(){
sum(10,20,'wjh',{name:'wjw'});
}
fn();
複製代碼
// arguments.call或者arguments.call.caller通常真正項目中不多使用,由於是在嚴格js模式下不容許咱們直接使用這兩個屬性,然而現有項目大部分都是基於嚴格模式來的
// 任意數求和
function sum(){
var total = null;
for(var i =0;i<arguments.length;i++){
var cur = Number(arguments[i]);
!isNaN(cur)?total += cur : null
}
consloe.log(total);
return total;
// return 後面跟着的都是值(返回的都是值):此處很多TOTAL變量返回,而是吧total存儲到值返回而已
// return 60;
}
sum(10,20,20);
sum();
sum(10,20,30,'wjw')
// console.log(total);
//=>Uncaught ReferenceError: total is not defined 閉包的保護機制致使做用域會保護裏面的私有變量
複製代碼
返回值是函數提供的一個出口:咱們若是想在外面使用函數私有的一些信息,那麼就須要經過return,把這些信息返回出來供外面使用
sum:表明的是函數自己
sum() 讓函數先執行,表明的是當前函數返回的結果(return)後面是啥,至關於函數返回的是啥
function sum(){
var total = 0;
renturn
}
console.log(sum());
// 若是函數中沒有return或者return後面啥也沒有,默認返回的結果是undefined
複製代碼
function sum(){
var total = 0;
renturn;
console.log(sum());
// 函數體重遇到return後,return後面的代碼都不在執行了
}
複製代碼
沒有名字的函數
oBox.onclick = function(){
// 把一個碼雲名字的函數(有名字的也無所謂)做爲值賦值給一個變量或者一個元素的某一個事件等,函數表達式
}
複製代碼
(function(n){
// 建立函數和執行函數放在一塊兒,穿件完成立馬之執行:自執行函數
// n 形參 n=10
})(10)
// 如下都是自執行函數,符號只有控制語法規範
~function(){}(10)
-function(){}(10)
+function(){}(10)
!function(){}(10)
複製代碼