一:淺聊前端發展史 第一階段:C/S(client server) -> B/S(browser server) 網頁製做 技術棧:PhotoShop、HTML、CSSjavascript
第二階段:從靜態到動態,從後端到前端 前端開發工程師 先後端分離 後臺:完成數據的分析和業務邏輯編寫(包含API接口編寫) 前端:網頁製做、JS交互效果、數據的交互和綁定前端
技術棧:JavaScript、AJAX(跨域技巧)、jQuery...java
第三階段:從前端到全端(從PC端到移動端) 技術棧:H五、CSS三、響應式佈局開發、Zepto、Hybrid(混合APP開發)、微信小程序...webpack
第四階段:從全端到全棧 全棧開發:先後端均可以開發(嚴格意義講,一種語言完成先後端開發) 技術棧:NODE(基於JS編程語言開發服務器端程序)、Express/Koa...web
爲了迎合日益發展的前端開發,JS中誕生不少有助於開發、維護、提升性能的框架:Vue、React、Angular、webpack...面試
展望WEB4.0時代,VR/AR元年,前端須要Canvas/webGL...編程
2、關於瀏覽器的內核和引擎 webkit(v8引擎):大部分瀏覽器 gecko:火狐 trident:IE ...小程序
W3C:萬維網聯盟,制定編程語言的規範與標準 開發者按照規範編寫代碼,瀏覽器開發商也會開發一套按照規範把代碼渲染成頁面的東西(這個東西就是內核或者引擎)後端
瀏覽器內核做用:按照必定的規範,把代碼基於GPU(顯卡)繪製出對應的圖形和頁面等微信小程序
爲啥會出現瀏覽器兼容: 1.部分瀏覽器會提早開發一些更好的功能,後期這些功能會被收錄到W3C規範中,可是在收錄以前,會存在必定的兼容性 2.各個瀏覽器廠商,爲了突出本身的獨特性,用其它方法實現了W3C規範中的功能 ...
3、JavaScript JS:輕量級的客戶端腳本編程語言
目前的JS已經不只僅是客戶端語言了,基於NODE能夠作服務器端程序,因此JS是全棧編程語言
學習JS,咱們學習它的幾部分組成
四:ESMAScript 它是JS的語法規劃,JS中的變量、數據類型、語法規範、操做語句、設計模式等等都是ES規定的
五:變量(variable) 它不是具體的值,只是一個用來存儲具體值的容器或者代名詞,由於它存儲的值能夠改變,因此稱爲變量
基於ES語法規範,在JS中建立變量有如下方式
/* * 語法: * var [變量名]=值 * let [變量名]=值 * const [變量名]=值 * function 函數名(){ * * } * ... */
var n = 13;
n = 15;
alert(n+10);//=>彈出來25 此時的N表明15
const m = 100;
m = 200;//=>Uncaught TypeError: Assignment to constant variable. 不能給一個常量從新的賦值(常量存儲的值不能被修改,可以修改就是變量了)
複製代碼
建立變量,命名的時候要遵循一些規範
var n=12;
var N=13; //=>兩個n不是同一個變量
var studentInfo / student_info / _studentInfo(下劃線在前的,都是公共變量) / $studentInfo(通常存儲的是JQ元素)...
語義化強一些
add / create / insert
del(delete)/ update / remove(rm)
info / detail
log
...
複製代碼
六:數據值是一門編程語言進行生產的材料,JS中包含的值有如下這些類型
[基本數據類型]
var n = 13; //=>0 -13 13.2 數字類型中有一個特殊的值NaN(not a number表明不是一個有效的數字,可是屬於number類型的)
var s = '';//=>"" '13' "{}" JS中全部用單引號或者雙引號包裹起來的都是字符串,裏面的內容是當前字符串中的字符(一個字符串由零到多個字符組成)
var b = true;//=>布爾類型只有兩個值 true真 false假
[引用數據類型]
var o = {name:'南飛雁培訓',age:9};//=>普通的對象:由大括號包裹起來,裏面包含多組屬性名和屬性值(包含多組鍵值對) {}空對象
var ary = [12,23,34,45]; //=>中括號包裹起來,包含零到多項內容,這種是數組對象 []空數組
var reg = /-?(\d|([1-9]\d+))(\.\d+)?/g; //=>由元字符組成一個完整的正則 //不是空正則是單行註釋
function fn(){
}
[Symbol]
建立出來的是一個惟一的值
var a = Symbol('南飛雁');
var b = Symbol('南飛雁');
a==b =>false
複製代碼
擴展:JS代碼如何被運行以及運行後如何輸出結果 [如何被運行]
[如何輸出結果]
var num=12;
alert(num); //=>window.alert
var str='南飛雁';
alert(str);
基於alert輸出的結果都會轉換爲字符串:把值(若是是表達式先計算出結果)經過toString這個方法轉換爲字符串,而後再輸出
alert(1+1); =>'2'
alert(true); =>'true'
alert([12,23]); =>'12,23'
alert({name:'xxx'}); =>'[object Object]' 對象toString後的結果就是object object,爲啥?
複製代碼
var flag = confirm('肯定要退出嗎?');
if(flag){
//=>flag:true 用戶點擊的是肯定按鈕
}else{
//=>flag:false 用戶點擊的是取消按鈕
}
複製代碼
prompt:在confirm的基礎上增長輸入框
console.log:在瀏覽器控制檯輸出日誌(按F12(FN+F12)打開瀏覽器的控制檯)
console.dir:比log輸出的更加詳細一些(尤爲是輸出對象數據值的時候)
console.table:把一個JSON數據按照表格的方式輸出
... (本身回去擴展更多console輸出方法)
7、數據類型的詳細剖析
//=>語法:isNaN([value])
var num=12;
isNaN(num); //->檢測num變量存儲的值是否爲非有效數字 false
isNaN('13') =>false
isNaN('南飛雁') =>true
isNaN(true) =>false
isNaN(false) =>false
isNaN(null) =>false
isNaN(undefined) =>true
isNaN({age:9}) =>true
isNaN([12,23]) =>true
isNaN([12]) =>false
isNaN(/^$/) =>true
isNaN(function(){}) =>true
重要:isNaN檢測的機制
一、首先驗證當前要檢測的值是否爲數字類型的,若是不是,瀏覽器會默認的把值轉換爲數字類型
把非數字類型的值轉換爲數字
- 其它基本類型轉換爲數字:直接使用Number這個方法轉換的
[字符串轉數字]
Number('13') ->13
Number('13px') ->NaN 若是當前字符串中出現任意一個非有效數字字符,結果則爲NaN
Number('13.5') ->13.5 能夠識別小數
[布爾轉數字]
Number(true) ->1
Number(false) ->0
[其它]
Number(null) ->0
Number(undefined) ->NaN
- 把引用數據類型值轉換爲數字:先把引用值調取toString轉換爲字符串,而後再把字符串調取Number轉換爲數字
[對象]
({}).toString() ->'[object Object]' ->NaN
[數組]
[12,23].toString() ->'12,23' ->NaN
[12].toString() ->'12' ->12
[正則]
/^$/.toString() ->'/^$/' ->NaN
Number('') ->0
[].toString() ->''
=> isNaN([]):false
二、當前檢測的值已是數字類型,是有效數字返回false,不是返回true(數字類型中只有NaN不是有效數字,其他都是有效數字)
複製代碼
等同於Number,也是爲了把其它類型的值轉換爲數字類型
和Number的區別在於字符串轉換分析上
Number:出現任意非有效數字字符,結果就是NaN
parseInt:把一個字符串中的整數部分解析出來,parseFloat是把一個字符串中小數(浮點數)部分解析出來
parseInt('13.5px') =>13
parseFloat('13.5px') =>13.5
parseInt('width:13.5px') =>NaN 從字符串最左邊字符開始查找有效數字字符,而且轉換爲數字,可是一但遇到一個非有效數字字符,查找結束
複製代碼
NaN==NaN:false NaN和誰都不相等,包括本身
複製代碼
思考題:有一個變量num,存儲的值不知道,我想檢測它是否爲一個有效數字,下面方案是否能夠
if(Number(num)==NaN){
alert('num不是有效數字!');
}
NaN和誰都不相等,條件永遠不成立(即便num確實不是有效數字,轉換的結果確實是NaN,可是NaN!=NaN的)
if(isNaN(num)){
//=>檢測是否爲有效數字,只有這一種方案
alert('num不是有效數字!')
}
複製代碼
只有兩個值:true / false
如何把其它數據類型轉換爲布爾類型?
Boolean(1) =>true
!'南飛雁培訓' =>先把其它數據類型轉換爲布爾類型,而後取反
!!null =>去兩次反,等價於沒取反,也就剩下轉換爲布爾類型了
複製代碼
規律:在JS中只有「0/NaN/空字符串/null/undefined」這五個值轉換爲布爾類型的false,其他都轉換爲true
都表明空或者沒有
- null:空對象指針
- undefined:未定義
null通常都是意料之中的沒有(通俗理解:通常都是人爲手動的先賦值爲null,後面的程序中咱們會再次給他賦值)
var num = null; //=>null是手動賦值,預示着後面我會把num變量的值進行修改
...
num = 12;
複製代碼
undefined表明的沒有通常都不是人爲手動控制的,大部分都是瀏覽器自主爲空(後面能夠賦值也能夠不賦值)
var num; //=>此時變量的值瀏覽器給分配的就是undefined
...
後面能夠賦值也能夠不賦值
複製代碼
劉天瑞(BOY)的女友是null,他的男友是undefined
普通對象
- 由大括號包裹起來的
- 由零到多組屬性名和屬性值(鍵值對)組成
屬性是用來描述當前對象特徵的,屬性名是當前具有這個特徵,屬性值是對這個特徵的描述(專業語法,屬性名稱爲鍵[key],屬性值稱爲值[value],一組屬性名和屬性值稱爲一組鍵值對)
var obj = {
name:'南飛雁培訓',
age:9
};
//=>對象的操做:對鍵值對的增刪改查
語法:對象.屬性 / 對象[屬性]
[獲取]
obj.name
obj['name'] 通常來講,對象的屬性名都是字符串格式的(屬性值不固定,任何格式均可以)
[增/改]
JS對象中屬性名是不容許重複的,是惟一的
obj.name='周嘯天'; //=>原有對象中存在NAME屬性,此處屬於修改屬性值
obj.sex='男'; //=>原有對象中不存在SEX,此處至關於給當前對象新增長一個屬性SEX
obj['age']=28;
[刪]
完全刪除:對象中不存在這個屬性了
delete obj['age'];
假刪除:並無移除這個屬性,只是讓當前屬性的值爲空
obj.sex=null;
----
在獲取屬性值的時候,若是當前對象有這個屬性名,則能夠正常獲取到值(哪怕是null),可是若是沒有這個屬性名,則獲取的結果是undefined
obj['friends'] =>undefined
複製代碼
思考題:
var obj = {
name:'南飛雁培訓',
age:9
};
var name = 'zhufeng';
obj.name =>'南飛雁培訓' 獲取的是NAME屬性的值
obj['name'] =>'南飛雁培訓' 獲取的是NAME屬性的值
obj[name] =>此處的NAME是一個變量,咱們要獲取的屬性名不叫作NAME,是NAME存儲的值'zhufeng' =>obj['zhufeng'] =>沒有這個屬性,屬性值是undefined
----
'name' 和 name 的區別?
=> 'name'是一個字符串值,它表明的是自己
=> name是一個變量,它表明的是自己存儲的這個值
複製代碼
一個對象中的屬性名不只僅是字符串格式的,還有多是數字格式的
var obj = {
name:'南飛雁培訓',
0:100
};
obj[0] =>100
obj['0'] =>100
obj.0 =>Uncaught SyntaxError: Unexpected number
----
當咱們存儲的屬性名不是字符串也不是數字的時候,瀏覽器會把這個值轉換爲字符串(toString),而後再進行存儲
obj[{}]=300; =>先把({}).toString()後的結果做爲對象的屬性名存儲進來 obj['[object Object]']=300
obj[{}] =>獲取的時候也是先把對象轉換爲字符串'[object Object]',而後獲取以前存儲的300
----
數組對象(對象由鍵值對組成的)
var oo = {
a:12
};
var ary = [12,23]; //=>12和23都是屬性值,屬性名呢?
經過觀察結果,咱們發現數組對象的屬性名是數字(咱們把數字屬性名稱爲當前對象的索引)
ary[0]
ary['0']
ary.0 =>報錯
複製代碼
一、if / else if / else
var num = -6;
if(num>10){
num++; //=>num=num+1 num+=1 在自身的基礎上累加1
}else if(num>=0 && num<=10){
num--;
}else{
num+=2;
}
console.log(num);
複製代碼
只要有一個條件成立,後面無論是否還有成立的條件,都不在判斷執行了
var num = 10;
if(num>5){
num+=2;
}else if(num>8){
num+=3;
}else{
num+=4;
}
console.log(num); //=>12
複製代碼
關於條件能夠怎麼寫?
// >= / <= / == 常規比較
if(0){
//=>無論你在條件判斷中寫什麼,最後總要把其計算出TRUE/FALSE來判斷條件是否成立(把其它類型的值轉換爲布爾類型,只有 0/NaN/''/null/undefined 是false,其他都是true)
}
if('3px'+3){
//=>在JS中,+ - * / % 都是數學運算,除 + 之外,其他運算符在運算的時候,若是遇到了非數字類型的值,首先會轉換爲數字類型(Number),而後再進行運算
//=>+ 在JS中除了數學相加,還有字符串拼接的做用(若是運算中遇到了字符串,則爲字符串拼接,而不是數學相加)
'3px'+3 =>'3px3'
}
if('3px'-3){
'3px'-3 =>NaN
}
複製代碼
BAT面試題:
var num = parseInt('width:35.5px');
if(num==35.5){
alert(0);
}else if(num==35){
alert(1);
}else if(num==NaN){
alert(2);
}else if(typeof num=='number'){
//=>先算typeof num
//=>在作比較
alert(3);//=>alert輸出的都是字符串格式的 '3'
}else{
alert(4);
}
複製代碼
在JS中用來檢測數據類型的方式之一,除了它之外,還有:
- instanceof
- constructor
- Object.prototype.toString.call()
語法:typeof [value] =>檢測value的數據類型
返回值:使用typeof檢測出來的結果是一個字符串,字符串中包含着對應的數據類型,例如:"number"/"string"/"boolen"/"undefined"/"object"/"function"
typeof null =>"object" 由於null表明空對象指針(沒有指向任何的內存空間)
typeof檢測數組/正則/對象,最後返回的都是"object",也就是基於這種方式沒法細分對象
面試題:
console.log(typeof []);
//=>"object"
console.log(typeof typeof []);
//=>typeof "object"
//=>"string"
複製代碼
二、三元運算符
語法:條件?成立作的事情:不成立作的事情; <=>至關於簡單的if/else判斷
var num=12;
if(num>10){
num++;
}else{
num--;
}
//=>改寫成三元運算符
num>10?num++:num--;
複製代碼
特殊狀況
//=>若是三元運算符中的某一部分不須要作任何的處理,咱們用 null/undeifned/void 0... 佔位便可
var num = 12;
num>10?num++:null;
//=>若是須要執行多項操做,咱們把其用小括號包裹起來,每條操做語句用逗號分隔
num=10;
num>=10?(num++,num*=10):null;
複製代碼
思考題
var num = 12;
if(num>0){
if(num<10){
num++;
}else{
num--;
}
}else{
if(num==0){
num++;
num=num/10;
}
}
改寫成三元運算符!
複製代碼
三、switch case
JS中的一種判斷方式
var num = 12;
if(num==10){
num++;
}else if(num==5){
num--;
}else{
num=0;
}
//=>改爲switch case
switch(num){
case 10:
num++;
break;
case 5:
num--;
break;
default:
num=0;
}
//=>switch case 應用於變量(或者表達式等)在不一樣值狀況下的不一樣操做,每一種case結束後都要加break(結束整個判斷)
複製代碼
switch case中每一種case狀況的比較都是基於"==="絕對相等來完成的
'10'==10
=>true 相等比較,若是等號左右兩邊的類型不同,首先會轉換爲同樣的數據類型,而後再進行比較
=>當前案例中,就是把字符串'10'轉換爲數字了,而後再比較的
'10'===10 絕對比較,若是兩邊的數據類型不同,則直接不相等,它要求類型和值都徹底同樣纔會相等(真實項目中爲了保證代碼的嚴謹性,咱們應該更多使用絕對比較)
複製代碼
做用:按照必定的規律,重複去作某件事情,此時咱們就須要使用循環來處理了
document.getElementById
在整個文檔中,同過元素的ID屬性值,獲取到這個元素對象
getElementById是獲取元素的方法,而document限定了獲取元素的範圍,咱們把這個範圍稱之爲:「上下文 [context]」
var oBox = document.getElementById('box');
1. 同過getElementById獲取的元素是一個對象數據類型的值(裏面包含不少內置的屬性)
typeof oBox =>"object"
2. 分析包含的屬性
className:存儲的是一個字符串,表明當前元素的樣式類名
id:存儲的是當前元素ID值(字符串)
innerHTML:存儲當前元素中全部的內容(包含HTML標籤)
innerText:存儲當前元素中全部的文本內容(沒有元素標籤)
onclick:元素的一個事件屬性,基於這個屬性,能夠給當前元素綁定點擊事件
onmouseover:鼠標滑過事件
onmouseout:鼠標離開事件
style:存儲當前元素全部的 "行內樣式" 值(獲取和操做的都只能是寫在標籤上的行內樣式,寫在樣式表中的樣式,沒法基於這個屬性獲取到)
...
複製代碼
[context].getElementsByTagName
在指定的上下文中,經過元素的標籤名獲取一組元素集合
上下文是咱們本身來指定的
var boxList = oBox.getElementsByTagName('li');
1. 獲取的結果是一個元素集合(HTMLCollection),首先它也是對象數據類型的,結構和數組很是類似(數字做爲索引,length表明長度),可是不是數組,咱們把它叫作「類數組」
boxList[0] 獲取當前集合中的第一個LI(經過索引獲取到具體的某一個LI便可)
boxList.length 獲取集合中LI的數量
2. 集合中的每一項存儲的值又是一個元素對象(對象數據類型,包含不少的內置屬性,例如:id/className...)
boxList[1].style.color='red'; 修改集合中第二個LI的文字顏色
複製代碼
在JS中,函數就是一個方法(一個功能體),基於函數通常都是爲了實現某個功能
var total=10;
total+=10;
total=total/2;
total=total.toFixed(2);//=>保留小數點後邊兩位(數字由一個方法toFixed用來保留小數點後面的位數)
....
在後續的代碼中,咱們依然想實現相同的操做(加10除以2),咱們須要從新編寫代碼
var total=10;
total+=10;
total=total/2;
total=total.toFixed(2);
...
這樣的方式會致使頁面中存在大量冗餘的代碼,也下降了開發的效率,若是咱們能把實現這個功能的代碼進行「封裝」,後期須要這個功能執行便可,這樣就行了!
複製代碼
函數誕生的目的就是爲了實現封裝
:把實現一個功能的代碼封裝到一個函數中,後期想要實現這個功能,只須要把函數執行便可,沒必要要再次編寫重複的代碼,起到了**低耦合高內聚(減小頁面中的冗餘代碼,提升代碼的重複使用率)
**的做用
function fn(){
var total=10;
total+=10;
total/=2;
total=total.toFixed(2);
console.log(total);
}
fn();
fn();
...
想用多少次,咱們就執行多少次函數便可
=====
ES3標準中:
//=>建立函數
function 函數名([參數]){
函數體:實現功能的JS代碼
}
//=>函數執行
函數名();
=====
ES6標準中建立箭頭函數:
let 函數名(變量名)=([參數])=>{
函數體
}
函數名();
let fn=()=>{
let total=10;
...
};
fn();
複製代碼
函數做爲引用數據類型中的一種,它也是按照引用地址來操做的,接下來咱們學習一下函數的運行機制
function fn(){
var total=10;
total+=10;
total=total.toFixed(2);
console.log(total);
}
fn();
【建立函數】
1. 函數也是引用類型,首先會開闢一個新的堆內存,把函數體中的代碼當作「字符串」存儲到內存中(對象向內存中存儲的是鍵值對)
2. 把開闢的堆內存地址賦值給函數名(變量名)
此時咱們輸出fn(切記不是fn())表明當前函數自己
若是咱們執行fn(),這是把函數執行
因此是否加小括號是兩種不一樣本質的操做
【函數執行】
目的:把以前存儲到堆內存中的代碼字符串變爲真正的JS代碼自上而下執行,從而實現應有的功能
1.函數執行,首先會造成一個私有的做用域(一個供代碼執行的環境,也是一個棧內存)
2.把以前在堆內存中存儲的字符串複製一份過來,變爲真正的JS代碼,在新開闢的做用域中自上而下執行
複製代碼
參數是函數的入口:當咱們在函數中封裝一個功能,發現一些原材料不肯定,須要執行函數的時候用戶傳遞進來才能夠,此時咱們就基於參數的機制,提供出入口便可
//=>此處的參數叫作形參:入口,形參是變量(n/m就是變量)
function sum(n,m){
//=>n和m分別對應要求和的兩個數字
var total = 0;
total = n + m;
console.log(total);
}
//=>此處函數執行傳遞的值是實參:實參是具體的數據值
sum(10,20); //=>n=10 m=20
sum(10); //=>n=10 m=undefined
sum(); //=>n和m都是undefined
sum(10,20,30); //=>n=10 m=20 30沒有形參變量接收
複製代碼
JS中檢測數據類型的方式
console.log(Number(null)); // 0
null==undefined:true
null===undefined:false
null&&undefined和其它值都不相等
NaN==NaN:false NaN和誰都不相等包括本身 ===========================>以上須要特殊記憶
1==true =>true
1==false =>false
2==true =>false 規律不要混淆,這裏是把true變爲數字1
[]==true:false 都轉換爲數字 0==1
![]==true:false
[]==false:true 都轉換爲數字 0==0
![]==false:true 先算![],把數組轉換爲布爾取反=>false =>false==false
複製代碼