做者:Brendan Eichjavascript
1.shell部分(也就是咱們顧名思義的外殼)php
2.內核部分java
2.1.渲染引擎(語法規定和渲染)python
2.2.js引擎es6
2.3.其餘模塊正則表達式
2008年Google發佈最新瀏覽器Chrome,它是採用優化後的javascript引擎,引擎代號V8,因能把js代碼直接轉化爲機械碼來執行,進而以速度快而聞名。shell
ChromeV8引擎是由c語言編寫的 v8引擎直接能夠將內容轉換成0,1的數字,因此Chrome比任何瀏覽器都要快,若是沒有v8引擎須要將彙編語言轉成成C語言在轉換成javascript語言。數組
編譯語言(C,C++)瀏覽器
特色:先所有解釋,在所有執行。jvm
優勢:快
缺點:移植性很差(不能跨平臺)
解釋性語言(Javascript,php,python)
特色:解釋一行,執行一行
優勢:跨平臺
缺點:稍微慢一點
另外注意的一點就是java與其餘的語言是不一樣的,它歷史叫作oak語言
解釋方式:.java文件 -> 經過javac命令 -> 編譯 -> .class文件 -> jvm虛擬機解釋執行
一、解釋性語言(不須要編譯成文件,跨平臺)
二、單線程
js三大部分:ECMAScript,DOM,BOM
變量(variable)
變量聲明 var a = 1;
變量賦值 a = 1;
命名規則
一、變量名必須以英文字母,_,$開頭
二、變量名能夠包括英文字母、_、$、數字
三、不能夠用系統的關鍵字、保留字做爲變量名
js中的保留字和關鍵字
1.原始值(stack棧,不可改變的)先進後出
Number(數字),String(字符串),Boolean(布爾值),undefined(undefined),null(空,佔位符)
特色:拷貝的數,不影響其餘的值
例如:var a = 10;
b = a;
b = 20;
console.log(b) // 20
2.引用值(heap堆)
Array(數組),Object(對象),function(函數),Date(日期),RegExp(正則表達式)
特色:拷貝的是地址,影響其餘的值
例如:var arr = [1,2];
arr1 = arr;
arr1.push(3);
console.log(arr) // 1,2,3
以下圖一cst和zx指向的是同一個地址,因此只要改變就會發生變化。
以下圖二 a 賦值給b 是拷貝了一個副本,以後b在發生變化,和a沒有任何關係
圖一
圖二
js語句基本規則
語句後面要用分號結束「;」
js語法錯誤會引起後續代碼終止,但不會影響其它js代碼塊
書寫格式要規範,「= + / -」兩邊都應該有空格
運算操做符
「+」
1.數學運算、字符串連接
2.任何數據類型加字符串都等於字符串
「-」,「*」,「/「,「%」,」=「,「()」
優先級」=「最弱,」()」優先級較高
「++」,「- -」,」+=「,「-=」,「/=「,「*=」,「%=」
被認定爲假的六個值:
undefinnde,null,false,null,0," "
邏輯運算符:
&&:先看第一個表達式轉換成布爾值的結果,若是結果爲真,那麼它會看第二個表達式的結果轉換成布爾值的結果(undefined,null,false,null,0,
" "這些值都是false),而後若是隻有兩個表達式的話,只看到第二個表達式就能夠返回該表達式的結果了。若是第一個爲false,就能夠直接返回false了。
||:只有有一個表達式爲真就返回真。
! :取反字符
for循環的底層原理:
for(var i = 0; i < 10; i++){}的實現
第一步:var i= 0;
第二步:if(i < 10){
console.log('a')
}
第三步:i++;
第四步:if(i < 10){
console.log('a')
}
......
注意若是for循環只寫中間的一個條件,那麼就是while循環
for(;i < 10;){} === while(i < 10){}
switch,case語句至關於if{}else{}
如:
if(a == 10){
console.log(10)
}else if(a == 20){
console.log(20)
}
換成switch,case
switch(a){
case 10 :
return 10;
case 20:
return 20;
}
還有一點須要注意的一旦用了return 後面的代碼就不會執行了,就不用break了
二:typeof
首先須要知道typeof可以,且只可以返回的六種類型
number,string,boolean,object,function,undefined,這些結構以前已經解釋過了,就不一一解釋了。
類型轉換:
顯示類型轉換:
Number:強行轉換成數字類型,注意的是undefined不能轉換成數字
parseInt:轉換成整型,其餘的NaN,會轉換成Number類型,從數字最後一位開始截取下來。如 typeof('123abc') // number 123;
另一點:parseInt(num,radio) -> radio爲基地轉換成10進制的數
parseFloat:轉換成浮點型,並保留一位小數;
string:轉換成字符串,寫什麼都是字符串;
boolean:轉換成布爾值,除了" ",其餘都是爲true;
toString:也是轉換成字符串,和string的區別在於用法不一樣,(undefined,null)不可用toString這個方法;
另一點:toString()括號內能夠跟目標進制的數
隱式類型轉換:
isNaN -> Number()
++/ -- +/-(一元正負運算符) -> Number()
+ 加號 -> String()
*/% -> Number()
&& | ! -> Number()
注意 !== 和 === 不發生類型轉換
3、函數
1.初始函數:
定義方式:
函數聲明:function (){}
函數表達式:
命名函數表達式:var test = function test() {}
匿名函數表達式(也稱爲函數表達式):var test = function () {}
實參和形參
例如:function test(a,b) {console.log(a,b)} test(1,2) //a,b稱爲形式參數,簡稱爲形參; 1,2稱爲實際參數,簡稱爲實參;
注意:函數function test(a,b){至關於隱式的var a,b;}
查看形參的長度:test.length(函數名的長度)
查看形參的長度:arguments.length(實參列表)
重點:函數裏面的實參和形參存在映射的關係,只要其中它們有一個發生了變化另一個也會發生變化,即便它們都是原始值,這是函數的特性
若是形參的長度大於實參的長度多出來的位數不會發生映射的關係。
另外的一個知識點,return:
(1)若是沒有寫return,則在函數的最後系統會自動幫你加上return,就比如沒有寫分號同樣
(2)若是寫了return,下面的代碼則不會繼續執行了.return返回的必須定義了容器來接收它,否則不會顯示。
2.預編譯:
大部分人都會記住兩句話叫作:
(1).函數聲明總體提高 意思是:函數聲明無論在哪裏調用都是好使的.
例如: test() //1 function test(){console.log(1)} 就算在前面執行依然可以打印出1
(2)變量 聲明提高 注意了這句話須要分開來讀 變量 聲明提高 而不是 變量聲明提高 什麼意思呢? 是這樣的:
例如 var a = 10;這叫作變量聲明 若是你在以前打印 a 會出現undefined 爲何會這樣呢 由於系統內部只會把 var 提早到最頂端 而賦值語句
不會提高到最頂部 這也是JavaScript語言的特色,因此會出先undefined。
注意點: 無論在全局仍是在局部聲明變量,必需要經過 var,let(這是es6會學到的)來聲明否則歸window全部。
例如:function test() {var a = b = 10} test() console.log(window.b,window.a) //10,undefined 由於b是沒有進行變量聲明獲得的值因此歸
window全部 而a就是經過變量聲明來的值,因此window上面是訪問不到的.這個b也可能叫作"暗示全局變量"
預編譯是發生在函數執行的前一刻(四部曲):
(1):建立AO對象(Activation Object)又稱爲執行期上下文。
(2):找形參和變量聲明,將變量和形參名做爲Ao的屬性名,值爲undefined.
(3):將實參和形參相統一.
(4):在函數體裏面找函數聲明.值賦予函數體
寫一個小例子就懂了:
function fn(a){
console.log(a);
var a = 123;
console.log(a);
function a() {}
console.log(a)
var b = function () {}
console.log(b)
function d(){}
}
fn(1)
這個例子若是你只知道以前兩句話是解不出來的,那咱們就一步一步的分析一下吧。
第一步建立Ao對象:
AO{}
第二步找形參和變量聲明,值爲undefined
AO{a:undefined,b:undefined}
第三步將實參和形參相統一
AO{a:1 b:undefined}
第四步找函數聲明 注意是 functio test() {} 而不是 var test = function () {}
AO{a:function a(){},b:undefined,d:function d() {}}
因此值爲// function a() {},123,123,function (){}
3.做用域:
[[scope]]:每一個javascript函數都是一個對象,對象中有些屬性咱們能夠訪問,但有些不能夠,這些屬性僅供javascript引擎存取,
[[scope]]就是其中一個。[[scope]]指的就是咱們所說的做用域,其中存儲了運行期上下文的集合。
運行期上下文:當函數執行時,會建立一個稱爲執行期上下文的內部對象。一個執行期上下文定義了一個函數執行時的環境,
函數每次執行時對應的執行上下文都是獨一無二的,因此屢次調用一個函數會致使建立多個執行上下文,當函數執行完畢,執行上下文被銷燬。
查找變量順序:從做用域鏈的頂端依次向下查找。
看圖解釋:
a函數在定義的時候產生一個Go(global object)放到做用域的最頂端。
a函數在執行的前一刻,也就是咱們所說的預編譯過程,建立一個執行期上下文對象放到做用域的最頂端。
b函數在建立的時候,直接能夠拿到a函數的勞動成果放到本身做用域的最頂端。
b函數執行生成一個執行期上下文,放到本身做用域最頂端,而後將a的勞動成果依次向下,須要注意的點
看圖中的標註
上面的圖解是做用域的大體流程。
在寫一個小的實例:
function a() {
function b() {
function c() {
}
c()
}
b()
}
a()
執行過程:
a 定義 a.[[scope]] -> 0 : Go
a 執行 a.[[scope]] -> 0 : aAo
1 :Go
b 定義 b.[[scope]] -> 0 : aAo
1 : Go
b 執行 b.[[scope]] -> 0 : bAo
1 : aAo
2 : Go
c 定義 c.[[scope]] 0 : bAo
1 : aAo
2 : bAo
c 執行 c.[[scope]] 0 : cAo
1 : bAo
2 : aAo
3 : Go
以上就是函數的執行順序,也解釋了爲何函數內部能夠訪問到外部的變量,而外部不能夠訪問到內部的變量
致使報錯,也就比如 兒子能夠問父親要錢 能夠問爺爺要錢,可是反過來是否是不行啊。