學習資源來自於js高程,有一部分參考犀牛。基本上是按照js高程的目錄來學的。筆記記了些重點和引伸。還有一些參考網站。javascript
Javascript是ecma-262的一種實現。它由三部分組成:ecmascript、bom、dom。ecmascript自己是ecma-262定義的標準,不依賴於具體環境,也不包含輸入輸出定義。宿主環境提供ecmascript的具體實現和交互的擴展。好比瀏覽器、node、flash等。html
你們能夠百度一下ecma發展的時間線。vue
es4夭折是由於部份內容太過激進等於從新定義一門語言,缺少實踐檢驗,微軟和雅虎反對方話語權很大。不過當年如日中天的adobe仍是本身用as3.0實現了es4。es4的部份內容將在es6中體現。從es3到es6至關於15年的沉澱。html5
es5實際就是es3.1版本。是一個溫和過分版本。java
能解析並能運行js代碼的解釋器node
瀏覽器一般會有js引擎,js剛出來時就是運行在瀏覽器中,做爲客戶端語言使用。常見的js引擎有:es6
dom0不算標準chrome
1998年成爲W3C的推薦標準。同ecma262相似,dom並不止針對js。包含dom core、dom html兩個模塊編程
2000年底發佈,包含dom views、dom events、dom style、dom traversal and rangejson
2004年發佈包含dom load and save、dom validation、dom style核心擴展
Dom級別本質上說是版本。
瀏覽器對象模型bom。由於做爲javascript實現的一部分,沒有相關標準。原來比較看宿主環境。可是html5致力於把不少bom功能寫入標準,有望能改變這種現象。
<script>標籤,屬性src, async,defer,這三個屬性都只針對外部文檔,延遲或異步執行。其餘的屬性基本沒什麼用。
在<script>嵌入的代碼中,使用</script>會報錯。須要用轉義字符<\/script>
引用外部js儘可能用標籤對,別用省略寫法。當瀏覽器遇到<script>時,便會解釋運行js內容,當其中內容都解釋運行完畢,纔會繼續呈現html中的其餘內容。所以<script>的位置很重要。若是把<script>放入,有時候加載外部文件,好比被牆的google會阻塞頁面的呈現。若是把<script>放入頁面最末尾,當頁面其餘內容渲染完畢,再執行js也未必OK,由於有可能js當中也有渲染頁面的代碼,這樣會形成閃爍。 <script>內容放置的位置要看具體狀況。
須要注意的defer延遲運行,對嵌入的腳步無效。同時,多個延遲腳本不必定能按順序執行。建議這類腳本仍是放在文檔的最末尾比較保險。
defer和async都是針對外部腳本。 使用defer延遲運行,多個延遲腳本不必定能按順序執行。設置爲async異步腳本,不會阻塞頁面內容。要保證與其餘腳本沒有依賴關係,由於他們不保證執行順序。建議異步腳本不要在加載期間修改dom。
提到<script>就須要說明一下跨域問題。<script>和均可以跨域。
能夠加載其餘域的圖片資源。<script>則能夠調用外部的js。同時能夠經過get方式傳遞參數。遠程代碼能夠返回任意內容。
轉載:跨域問題實際測過的方法:jsonp,iframe+document.domain,cors跨域資源共享。
js區分大小寫。首字符必須爲字母、下劃線、$。非首字符可用數字。
標識符駝峯寫法,或者$開頭,或者下劃線分隔寫法。
"use strict"
可寫在函數體內。
複製代碼
關鍵字是控制語句的開始和結束,用來執行特定操做。關鍵字不能用做標識符。都是如今語句裏用的。
break do while this function var newcontinue typeof instanceof return void
if else case switch with try catch finallythrow for delete debugger default
保留字是一些保留下來不能做爲標識符的,未來有可能做爲關鍵字。
好比class interface longchar public private……
第5版對於以上有些變化。但儘可能編程時避免雷區。
Js的變量是鬆散類型的。Js聲明變量時,分配給標識符 存儲區域,並將標識符和做用域進行綁定。
Ecmascript有五種簡單數據類型:
一種複雜數據類型:
只聲明未初始化和未聲明過的變量都會顯示undefined.
學過as和js,有時候會把變量聲明的方式搞混。actionscript裏有一種寫法。A:array=new Array();在js裏不適用。js就是弱類型。不必用冒號加類型。若是這麼寫會報錯。
var a;
// var b; 未聲明b
console.log(a);//undefined
console.log(b);//報錯
複製代碼
可是使用typeof
var a;
// var b; 未聲明b
console.log(typeof a); //undefined
console.log(typeof b); //undefined 不會報錯
複製代碼
所以,對於沒有聲明的變量,typeof是惟一可執行的操做。在寫程序的時候,咱們應該顯式初始化變量,這樣咱們再使用typeof時,看到undefined時,就知道這個變量是未聲明的。
var c=null;
console.log(c);//null
console.log(typeof c);//object
複製代碼
null值表示一個空對象指針。
若是定義的變量未來要保存對象,那麼能夠先給其null值。所以,看到null,咱們就應該知道它是幹嗎的。
另外:
console.log(null==undefined);//true
var car=null;
if(car!=null){
//執行某些操做
}//這樣是能夠的。
複製代碼
這裏就存在一個問題。如何判斷變量是null呢?
if(car==null){}//這樣是不許確的,由於undefined也能夠==null。
複製代碼
利用typeof也不行,由於會返回object。
if(car===null){}//這樣寫比較簡單。
複製代碼
不要測試某個特定的浮點數值,好比,0.1+0.2結果不是0.3。這是基於IEEE754數值浮點計算的通病。解決這個問題,一般是把浮點數轉換成整數再計算。Es6中出現了一個新的常數,Number.EPSILON,而這個值等於2^-52。相似於取極限,(0.1+0.2)-0.3小於Number.EPSILON就能夠認爲0.1+0.2等於0.3。 關於Number()和parseInt()的區別。
var a="22asdfs";
console.log(parseInt(a));//22
console.log(Number(a));//NaN
var a="22.5";
console.log(parseInt(a));//22 int就是整形的意思,因此會忽略小數點。
console.log(Number(a));//22.5
var a="";//空字符,加空格也如此
console.log(parseInt(a));//NaN
console.log(Number(a));//0
var a="22e-6";
console.log(parseInt(a));//22
console.log(Number(a));//0.000022
var a="0x111";
console.log(parseInt(a));//273
console.log(Number(a));// 273
var a="AF";
console.log(parseInt(a,16));//175
console.log(Number(a));//NaN
複製代碼
Number()能夠對任意類型作轉換,而parseInt()則只能對字符串作轉換。parseInt有第二個參數,作基數。Number()對boolean的false轉爲0,true轉爲1。Null轉換爲0,undefined轉換爲NaN。
parseFloat只識別十進制數,忽略前導0,十六進制數0x開頭,只能識別爲0。第二個小數點無效。無第二個參數。
字符字面量 記住一些常見的轉義字符,使用反斜\
開頭。\n
,\t
,\r
,\b
等。使用雙字節字符length可能不會返回準確字符數目。
字符串特色 字符串一旦建立值就不能改變!一旦想改變某變量保存的字符串,須要先銷燬原來的字符串,再使用另外一個包含新值的字符串填充變量。也是由於這個特色,一些舊版瀏覽器拼接字符串效率低。
轉換爲字符串 把一個值轉換爲字符串有兩種方法,一種使用toString()方法,另外一種使用類型轉換String()函數。 null和undefined沒有toString屬性。因此
var chr=null
chr.toString()//報錯
複製代碼
可是,使用String()轉型能夠。其首先查看是否有toString()方法,有則調用。若是值是null則返回」 null」,是undefined則返回」undefined」。
每一個Object對象都有如下屬性和方法:
constructor,hasOwnProperty,toString,valueOf,isPrototypeOf,propertyIsEnumerable,toLocalString。 能夠經過下面方法看到,全部對象都繼承自Object的原型對象。
console.log(Object.getOwnPropertyNames(Object.prototype))
複製代碼
Objecet.keys和Object.getOwnPropertyName的區別:Object.keys列舉對象自有可枚舉屬性。 Object.getOwnPropertyName列舉對象的自有屬性。
能夠經過propertyIsEnumerable來檢查屬性是否可枚舉
console.log(Object.prototype.propertyIsEnumerable("toString"));
//false
複製代碼
另外for in能夠列舉對象的全部可枚舉屬性。包括繼承和非繼承的屬性。
一元加減運算符。非數字應用一元加減運算符,能夠類型轉換。
var chr="10";
console.log(+chr+2);//12
console.log(chr+2);//102
複製代碼
有符號整數,正負轉換一概反碼加一。 好比用四位表示二進制有符號整數。
0000 表示0
0001表示1 1111表示-1 0010表示2 1110表示-2 0011表示3 1101表示-3 0100表示4 1100表示-4 0101表示5 1011表示-5 0110表示6 1010表示-6 0111表示7 1001表示-7
負值=取反(正值)+1 這個方法通常用做負數求補。利用按位非的特色。~~兩個按位非能夠對數字下取整。能夠想象,這比Math.floor效率快。
計算機中的符號數有三種表示方法,即原碼(轉載)、反碼(轉載)和補碼(轉載)。數值一概用補碼來表示和存儲。緣由在於,使用補碼,能夠將符號位和數值域統一處理。
按位非 就是按位取反。 符號~ 用上面的例子來說就是負值減一 取反(正值)=負值-1
按位與 很方便的判斷奇偶,奇數&1=1,偶數&0=0。
If(數字&1){
//奇數
}else{
//偶數
}
複製代碼
按位或
也能夠用來取整,數字|0 ,包括不過~~感受看起來更舒服。
關於位操做,能夠結合計算機組成原理第二章運算方法和運算器來看。
按位異或還能夠作數值交換。這種狀況不多見,能夠不用額外聲明變量。
a^=b;
b^=a;
a^=b;
複製代碼
對2求補可用按位掃描技術來執行所需求補操做。從右向左找到第一個「1」,從這位到右保持不變,這位左側的數字所有求反就OK。
直接補碼陣列乘法器,符號位參與運算,因此省去對2求補和補位運算,提升效率。瞭解便可。
對於位操做符有更深入直觀的認識。一些運算(例如取整)使用位操做符能大大提升效率。
位運算符的妙用:轉載:https://www.cnblogs.com/happy1992/p/7064114.html
邏輯非,!!兩次至關於類型轉換Boolean(),返回所求內容對應的布爾值。
邏輯與 && 短路操做符。若是左側可以決定結果,則不會繼續對右側求值。 基於這種原理,每每在使用上來作遞進的判斷。好比先判斷是否有對象Car,若是有,判斷這個對象下面是否有屬性a,若是有,對屬性a賦值。肯定具有某一條件(左側),則返回(右側)
var me=null;
//程序某一處me={high:185,skin:"black"};
var b=me&&me.high;
console.log(b);
複製代碼
邏輯或 || 也是操做符。當左側爲true,返回左側,不對右側求值。當左側爲false則返回右側值。常常用在給變量賦值的狀況,若是沒有初始化的值則返回右側的默認值。(左側)不符合條件,則返回(右側)。
var me={skin:"black"};
//程序某一處me.high=180;
var b=me.high||185;
console.log(b);
複製代碼
乘法中操做符幾個特殊的結果:
Infinity*0爲NaN。 //別忘了NaN!=NaN NaN與任何數都爲NaN, Infinity與非0數仍是(+-)Infinity。
除法中幾個特殊結果:
NaN與任何數都爲NaN Infinity除Infinity和0除0都爲 NaN
求模中幾個特殊結果:
被除數是0結果爲0 被除數是有限數,除數是無限大,結果是被除數 其餘凡是你認爲沒結果的都是NaN
加法當有字符串爲操做數時,對於其餘數據類型用toString()方法,null和undefined這兩種使用String();
可用()來影響操做順序和轉換類型。
減法規則:存在除number之外簡單數據類型時,先調用Number()。若是存在Object類型,先經過valueOf()轉換。若是不存在則先toString()再Number()轉爲數字。Null直接用Number()轉爲0,undefined爲NaN。
總結爲在操做數分別爲字符串和數字時,加法當字符串拼接,減法當數字相減。
對於null和undefined的存在,書上沒有具體闡述。可是,關係操做符比較偏心轉數字,加號操做符偏心轉字符串。針對和數字的比較有:
var a=undefined;
console.log(a<1);//false ,若是轉換了類型,則按照規則,undefined轉爲數字NaN
console.log(a>1);//false
var a=null;
console.log(a<1);//true根據規則null轉成0.
console.log(a>1);//false
console.log(a<"a");//false 即使有字符串,也是轉數字的,
//a變成NaN,所以始終是false
console.log(a>"a");//false
複製代碼
==
操做符可能須要類型轉換,null和undefined則不轉換。 ===
不進行轉換即相等才返回true。
也叫三目(元)運算符。在ecmascript中最靈活的一種,大神的代碼中特別常見。特別相似於if…else…
條件?表達式1 :表達式2
複製代碼
三目運算符是能夠嵌套使用的。好比:
條件1?表達式1:條件2?表達式2:條件3?表達式3:表達式4
能夠將當即執行函數表達式放入三目運算符。由於這樣能夠封閉做用域,傳參,返回值。結合賦值語句使用很強大。
在vue裏頗有用。
不過在後面研究label和break的時候,發現三目運算符不能帶break和continue一塊兒用,會報錯。
將代碼的做用與設置到一個特定的對象中。在with代碼塊內部,每一個變量首先被認爲是局部變量,若是局部環境找不到變量的定義,就會查找特定對象做用域是否有同名屬性。若是有,則以特定對象中屬性值做爲變量的值。 with嚴格模式會報錯
關於函數表達式,函數聲明,匿名函數的分析,(function(){})();
何爲當即執行函數Immediately-InvokedFunction Expression (IIFE)
轉載:https://www.cnblogs.com/zichi/p/4401755.html
轉載:https://blog.csdn.net/linshichen/article/details/78328125
這部分能夠結合紅皮書第四章變量、做用域和內存問題理解
Js堆棧、淺拷貝、深拷貝、基本類型、引用類型: