1996年11月,JavaScript的創造者--Netscape公司,決定將JavaScript提交給國際標準化組織ECMA,但願這門語言可以成爲國際標準。次年,ECMA發佈262號標準文件(ECMA-262)的初版,規定了瀏覽器腳本語言的標準,並將這種語言稱爲ECMAScript,這個版本就是1.0版。css
該標準一開始就是針對JavaScript語言制定的,可是沒有稱其爲JavaScript,有兩個方面的緣由。一是商標,JavaScript自己已被Netscape註冊爲商標。二是想體現這門語言的制定者是ECMA,而不是Netscape,這樣有利於保證這門語言的開發性和中立性。html
所以ECMAScript和JavaScript的關係是,前者是後者的規格,後者是前者的一種實現。python
JavaScript 已經由 ECMA(歐洲電腦製造商協會)經過 ECMAScript 實現語言的標準化。es6
年份 | 名稱 | 描述 |
---|---|---|
1997 | ECMAScript 1 | 第一個版本 |
1998 | ECMAScript 2 | 版本變動 |
1999 | ECMAScript 3 | 添加正則表達式 添加 try/catch |
ECMAScript 4 | 沒有發佈 | |
2009 | ECMAScript 5 | 添加 "strict mode",嚴格模式 添加 JSON 支持 |
2011 | ECMAScript 5.1 | 版本變動 |
2015 | ECMAScript 6 | 添加類和模塊 |
2016 | ECMAScript 7 | 增長指數運算符 (**) 增長 Array.prototype.includes |
注: ECMAScript 6 也稱爲 ECMAScript 2015。 ECMAScript 7 也稱爲 ECMAScript 2016。
儘管 ECMAScript 是一個重要的標準,但它並非 JavaScript 惟一的部分,固然,也不是惟一被標準化的部分。實際上,一個完整的 JavaScript 實現是由如下 3 個不一樣部分組成的:正則表達式
JavaScript 是一種輕量級的編程語言。編程
JavaScript 是可插入 HTML 頁面的編程代碼。數組
JavaScript 插入 HTML 頁面後,可由全部的現代瀏覽器執行。瀏覽器
JavaScript 很容易學習。數據結構
在head標籤裏面能夠寫,在body標籤裏面也能夠寫,放到head標籤裏面和放到body標籤裏面到底有什麼區別,咱們後續在講~ <script> // 在這裏寫你的JS代碼 //console.log('騎士計劃!') #f12建打開瀏覽器的調試窗口,而後在console這個調試臺就能看到這個內容了 //alert('騎士計劃!') #這個是瀏覽器窗口一打開我們這個文件,就彈出一個窗口 </script>
<script src="1.js"> </script> //有點相似於在html引入css樣式,就如link
// 這是單行註釋 /* 這是
多行註釋 */
JavaScript中的語句要以分號(;)爲結束符。也就是說和縮進不要緊了閉包
1.JavaScript的變量名可使用_,數字,字母,$組成,不能以數字開頭。(和大多數編程語言相似)
2.聲明變量使用 var 變量名; 的格式來進行聲明(這個比較不同)
var a='今每天氣真好'
也能夠分兩步,聲明變量var a;而後a='今每天氣真好',可是一般咱們都是一步寫完 var b = 18;
注意:
變量名是區分大小寫的。
推薦使用駝峯式命名規則。首字母大寫
保留字不能用作變量名。(保留字也就是咱們編程語言常說的關鍵字)
補充:(ES6新特性,等我們學到 VUE 在細說,簡單瞭解一下就好了)
ES6新增了let命令,用於聲明變量。其用法相似於var,可是所聲明的變量只在let命令所在的代碼塊內有效。例如:for循環的計數器就很適合使用let命令。
for (let i=0;i<arr.length;i++){...}
ES6新增const用來聲明常量。一旦聲明,其值就不能改變。這個東西就是爲了定義一個固定的常量,供你們使用,這個常量不會改變
const PI = 3.1415; PI // 3.1415 PI = 3 // TypeError: "PI" is read-only //若是真好改變就把聲明那段刪掉從新寫
再次補充:保留字列表,不用硬記,寫多了天然就知道了
abstract | else | instanceof | super |
boolean | enum | int | switch |
break | export | interface | synchronized |
byte | extends | let | this |
case | false | long | throw |
catch | final | native | throws |
char | finally | new | transient |
class | float | null | true |
const | for | package | try |
continue | function | private | typeof |
debugger | goto | protected | var |
default | if | public | void |
delete | implements | return | volatile |
do | import | short | while |
double | in | static | with |
JavaScript擁有動態類型(python也是動態的)
var x; // 此時x是undefined 靜態語言好比c:建立變量的時候,要指定變量的類型,python3.6也出現了類型註解的新特性def func(x:int,y:int) --> int: return x + y,意思是參數是int類型,返回值也是int類型的,就是個註釋的做用 var x = 1; // 此時x是數字 var x = "Alex" // 此時x是字符串
JavaScript不區分整型和浮點型,就只有一種數字類型。
var a = 12.34; var b = 20; var c = 123e5; // 12300000 123*10^5 var d = 123e-5; // 0.00123
還有一種NaN,表示不是一個數字(Not a Number),也就是說是一個值,但不是數字。
經常使用方法:
parseInt("123") // 返回123 parseInt("ABC") // 返回NaN,NaN屬性是表明非數字值的特殊值。該屬性用於指示某個值不是數字。 parseFloat("123.456") // 返回123.456
字符串(String)
var a='python';
var b='牛逼';
var c=a+b;
console.log(c) ; //返回python牛逼 能夠拼接
經常使用方法:
方法 | 說明 |
.length #不加括號的是屬性 | 返回長度 |
.trim() #獲得一個新值 | 移除空白 |
.trimLeft() | 移除左邊的空白 |
.trimRight() | 移除右邊的空白 |
.charAt(n) #n相似索引,從0開始,超過最大值返回''空字符串 | 返回第n個字符 |
.concat(value, ...) #s1='hello';s.concat('xx');獲得helloxx | 拼接 |
.indexOf(substring, start) #這個start是從索引幾開始找,沒有返回-1,根據索引找元素 | 子序列位置 |
.substring(from, to) #不支持複數,因此通常都不用它,瞭解一下就好了 | 根據索引獲取子序列 |
.slice(start, end) #var s1='helloworld';s1.slice(0,-5)看結果,就用它 | 切片 |
.toLowerCase() #所有變小寫 | 小寫 |
.toUpperCase() #所有變大寫 | 大寫 |
.split(delimiter, limit)#分隔,s1.splite(' '),後面還能夠加參數s1.split(' ',2),返回切割後的元素個數 | 分割 |
注意:上面方法的寫法,駝峯體,駝峯體的每一個開始字母都要大寫,不然滬報錯.
拼接字符串通常使用「+」
slice和substring的區別:
string.slice(start, stop)和string.substring(start, stop): 二者的相同點: 若是start等於end,返回空字符串 若是stop參數省略,則取到字符串末 若是某個參數超過string的長度,這個參數會被替換爲string的長度 substirng()的特色: 若是 start > stop ,start和stop將被交換 若是參數是負數或者不是數字,將會被0替換 silce()的特色: 若是 start > stop 不會交換二者 若是start小於0,則切割從字符串末尾往前數的第abs(start)個的字符開始(包括該位置的字符) 若是stop小於0,則切割在從字符串末尾往前數的第abs(stop)個字符結束(不包含該位置字符) slice和substring的區別
補充:
ES6中引入了模板字符串。模板字符串(template string)是加強版的字符串,用反引號(`)標識,ESC鍵下面那個鍵就是反引號。它能夠當作普通字符串使用,也能夠用來定義多行字符串,或者在字符串中嵌入變量。你使用chorme瀏覽器就行,chorme瀏覽器支持ES6
// 普通字符串 `這是普通字符串!` // 多行文本 `這是多行的 文本` // 字符串中嵌入變量 var name = "q1mi", time = "today"; `Hello ${name}, how are you ${time}?`
上面的寫法是ES6中的,而且在console中輸入內容的時候,按着shift+回車來進行換行,就可以不執行代碼直接換行了~~~
注意:
若是模板字符串中須要使用反引號,則在其前面要用反斜槓轉義。
JSHint啓用ES6語法支持:/* jshint esversion: 6 */
也只有true和false,和pyhon的差異就是python是大寫,二這個是小寫
var a=true;
var b=false;
全部的'空'都是假的 :""(空字符串)、0、null、undefined、NaN都是false.
null表示變量的值是空,undefined則表示只聲明瞭變量,但尚未賦值。
JavaScript 中的全部事物都是對象:字符串、數值、數組、函數...此外,JavaScript 容許自定義對象。
JavaScript 提供多個內建對象,好比 String、Date、Array 等等。
對象只是帶有屬性和方法的特殊數據類型。
數組(arry)
數組對象的做用是:使用單獨的變量名來存儲一系列的值。相似於Python中的列表。
var a=['1',2,'3']
conselo.log(a[1]) //返回2
經常使用方法:
方法 | 說明 |
.length | 數組的大小 |
.push(ele) | 尾部追加元素 |
.pop() | 獲取尾部的元素 |
.unshift(ele) | 頭部插入元素 |
.shift() | 頭部移除元素 |
.slice(start, end) | 切片 |
.reverse() #在原數組上改的 | 反轉 |
.join(seq)#a1.join('+'),seq是鏈接符 | 將數組元素鏈接成字符串 |
.concat(val, ...) #連個數組合並 | 鏈接數組 |
.sort() | 排序 |
.forEach() #講了函數再說 | 將數組的每一個元素傳遞給回調函數 |
.splice() | 刪除元素,並向數組添加新元素。 |
.map() #講了函數再說 | 返回一個數組元素調用函數處理後的值的新數組 |
語法:
splice(index,howmany,item1,.....,itemX)
參數:
參數 | 描述 |
---|---|
index | 必需。規定從何處添加/刪除元素。 該參數是開始插入和(或)刪除的數組元素的下標,必須是數字。 |
howmany | 必需。規定應該刪除多少元素。必須是數字,但能夠是 "0"。 若是未規定此參數,則刪除從 index 開始到原數組結尾的全部元素。 |
item1, ..., itemX | 可選。要添加到數組的新元素 |
關於sort()須要注意:
若是調用該方法時沒有使用參數,將按字母順序對數組中的元素進行排序,
說得更精確點,是按照字符編碼的順序進行排序。要實現這一點,首先應把數組的元素都轉換成字符串(若有必要),以便進行比較。
上面的這種比較方式不是咱們想要的啊,怎麼辦?
若是想按照其餘標準進行排序,就須要提供比較函數,也就是本身提供一個函數提供排序規則,
該函數要比較兩個值,而後返回一個用於說明這兩個值的相對順序的數字。比較函數應該具備兩個參數 a 和 b,其返回值以下:
若 a 小於 b,在排序後的數組中 a 應該出如今 b 以前,則返回一個小於 0 的值。
若 a 等於 b,則返回 0。
若 a 大於 b,則返回一個大於 0 的值。
示例:
function sortNumber(a,b){ return a - b } var arr1 = [11, 100, 22, 55, 33, 44] arr1.sort(sortNumber)
關於遍歷數組中的元素,可使用下面的方式:
var a=[1,2,3,4];
for (i=0,i<a.length,i++) //先打印i再自加1,由於i的優先級很低
{onsole.log(a[i])}
typeof "abc" // "string" typeof null // "object" typeof true // "boolean" typeof 123 typeof NAN // "number"
typeof undefined //undefined
typeof是一個一元運算符(就像++,--,!,- 等一元運算符),不是一個函數,也不是一個語句。
對變量或值調用 typeof 運算符將返回下列值之一:
+ - * / % ++ -- i++,是i自加1,i--是i自減1 //i++.i--的優先級都比較低
> >= < <= != == === !==
注意:
1 == 「1」 // true #弱等於,將1轉換爲字符串'1',在=號兩個數據類型不一樣的時候,會自動給你變成相同的,具體怎麼一個變換規則,先不用理他,由於這種比較很差,由於之後我們就儘可能用===。
1 === "1" // false #強等於,比較類型也比較值 //經常使用的是這個
提一個輸入法的高級用法:搜狗輸入法的一個高級用法:不認識的字:先輸入一個字母uhuohuohuo,就看到了焱,不會寫大寫的12345怎麼辦?先輸入一個v12345,你就看到壹萬貳仟叄佰肆拾伍了。
&& || ! #and,or,非(取反)!null返回true
= += -= *= /= #n += 1其實就是n = n + 1
var a = 10; if (a > 5){ console.log("yes"); }else { console.log("no"); }
var a = 10; if (a > 5){ console.log("a > 5"); }else if (a < 5) { console.log("a < 5"); }else { console.log("a = 5"); }
var day = new Date().getDay(); //示例化一個今天的日期對象,getDay()是獲取天數的編號,0表示星期日 switch (day) { //這裏day這個參數必須是一個值或者是一個可以獲得一個值的算式才行,這個值和後面寫的case後面的值逐個比較,知足其中一個就執行case對應的下面的語句,
而後break,若是沒有加break,還會繼續往下判斷 case 0: //若是day是0 console.log("Sunday"); //執行它 break; //而後break跳出 case 1: console.log("Monday"); break; default: //若是沒有任何知足條件的,就執行它 console.log("...") }
switch中的case子句一般都會加break語句,不然程序會繼續執行後續case中的語句。
for (var i=0;i<10;i++) { //就這麼個寫法,聲明一個變量,變量小於10,變量每次循環自增1,for(;;){console.log(i)};這種寫法就是個死循環,會一直循環,直到你的瀏覽器崩了,就不工做了,回頭能夠拿別人的電腦試試~~ console.log(i); }
var i = 0; while (i < 10) { console.log(i); i++; }
var a = 1; var b = 2; var c = a > b ? a : b //若是a>b這個條件成立,就把冒號前面的值給c,不然把冒號後面的值給c //python中的:a = x if x>y else y
JavaScript中的函數和Python中的很是相似,只是定義方式有點區別。
// 普通函數定義 function f1() { console.log("Hello world!"); } // 帶參數的函數 function f2(a, b) { console.log(arguments); // 內置的arguments對象 console.log(arguments.length); console.log(a, b); } // 帶返回值的函數 function sum(a, b){ return a + b; //在js中,若是你想返回多個值是不行的,好比return a ,b;只能給你返回最後一個值,若是就想返回多個值,你能夠用數組包裹起來 return [a,b]; } sum(1, 2); // 調用函數 sum(1,2,3,4,5)參數給多了,也不會報錯,仍是執行前兩個參數的和,sum(1),少參數或者沒參數也不報錯,不過返回值就會是NAN // 匿名函數方式,多和其餘函數配合使用,後面咱們就會用到了 var sum = function(a, b){ //在es6中,使用var,可能會飄黃,是由於在es6中,建議你使用let來定義變量,不過不影響你使用 return a + b; } sum(1, 2); // 當即執行函數,頁面加載到這裏,這個函數就直接執行了,不須要被調用執行 (function(a, b){ return a + b; })(1, 2); //python中寫能夠這麼寫:ret=(lambda x,y:x+y)(10,20) 而後print(ret)
補充:
ES6中容許使用「箭頭」(=>)定義函數,能夠理解爲匿名函數,用的很少。
var f = v => v; // 等同於 var f = function(v){ return v; }
若是箭頭函數不須要參數或須要多個參數,就是用圓括號表明參數部分:
var f = () => 5; // 等同於 var f = function(){return 5}; var sum = (num1, num2) => num1 + num2; // 等同於 var sum = function(num1, num2){ return num1 + num2; }
function add(a,b){ console.log(a+b); console.log(arguments.length) //獲取傳入的參數的個數,arguments就是指的你傳入的全部的實參,放在一個數組裏面,這個arguments.length是統計這個數組的元素的個數。 } add(1,2)
輸出:
3 2
注意:
函數只能返回一個值,若是要返回多個值,只能將其放在數組或對象中返回。
局部變量:
在JavaScript函數內部聲明的變量(使用 var)是局部變量,因此只能在函數內部訪問它(該變量的做用域是函數內部)。只要函數運行完畢,本地變量就會被刪除。
全局變量:
在函數外聲明的變量是全局變量,網頁上的全部腳本和函數都能訪問它。
變量生存週期:
JavaScript變量的生命期從它們被聲明的時間開始。
局部變量會在函數運行之後被刪除。
全局變量會在頁面關閉後被刪除。
首先在函數內部查找變量,找不到則到外層函數查找,逐步找到最外層。
幾個例子:
1.
var city = "BeiJing"; function f() { var city = "ShangHai"; function inner(){ var city = "ShenZhen"; console.log(city); } inner(); } f(); //輸出結果是? ---> ShenZhen
2.
var city = "BeiJing"; function Bar() { console.log(city); } function f() { var city = "ShangHai"; return Bar; } var ret = f(); ret(); // 打印結果是?---> BeiJing
3.閉包
var city = "BeiJing"; function f(){ var city = "ShangHai"; function inner(){ console.log(city); } return inner; } var ret = f(); ret(); ---> ShangHai
JavaScript中在調用函數的那一瞬間,會先進行詞法分析。
詞法分析的過程:
當函數調用的前一瞬間,會先造成一個激活對象:Avtive Object(AO),並會分析如下3個方面:
1:函數參數,若是有,則將此參數賦值給AO,且值爲undefined。若是沒有,則不作任何操做。
2:函數局部變量,若是AO上有同名的值,則不作任何操做。若是沒有,則將此變量賦值給AO,而且值爲undefined。
3:函數聲明,若是AO上有,則會將AO上的對象覆蓋。若是沒有,則不作任何操做。
函數內部不管是使用參數仍是使用局部變量都到AO上找。
看兩個例子:
var age = 18; function foo(){ console.log(age); //分析到這一步的時候,發現你下面有age變量聲明,那麼age變量就在AO對象上村上了,而且值爲undefined,因此函數在執行的時候,尚未到age=22這步的時候,age=undefined var age = 22; //若是沒有這個變量聲明,那麼打印的結果應該是18 console.log(age); } foo(); // 問:執行foo()以後的結果是?
undefined
22
第二題:
var age = 18; function foo(){ console.log(age); var age = 22; console.log(age); function age(){ #發現age這個函數名也是變量,將OA上的變量給替換了,那麼函數在執行的時候,去OA上找,發現OA是個函數,而後執行到age=22的時候,age才被從新賦值 console.log("呵呵"); } console.log(age); } foo(); // 執行後的結果是?
結果:
function age(){
console.log("呵呵");
}
22
22
答案解析:
詞法分析過程: 一、分析參數,有一個參數,造成一個 AO.age=undefine; 二、分析變量聲明,有一個 var age, 發現 AO 上面已經有一個 AO.age,所以不作任何處理 三、分析函數聲明,有一個 function age(){...} 聲明, 則把原有的 age 覆蓋成 AO.age=function(){...}; 最終,AO上的屬性只有一個age,而且值爲一個函數聲明 執行過程: 注意:執行過程當中全部的值都是從AO對象上去尋找 一、執行第一個 console.log(age) 時,此時的 AO.age 是一個函數,因此第一個輸出的一個函數 二、這句 var age=22; 是對 AO.age 的屬性賦值, 此時AO.age=22 ,因此在第二個輸出的是 22 三、同理第三個輸出的仍是22, 由於中間再沒有改變age值的語句了
這些內容就是好多人搞不明白的,常常寫js代碼的時候,發現本身的結果不對啊,什麼狀況,就是由於這個沒搞清楚~~~
JavaScript中的全部事物都是對象:字符串、數字、數組、日期,等等。在JavaScript中,對象是擁有屬性和方法的數據。
咱們在學習基本數據類型的時候已經帶你們瞭解了,JavaScript中的Number對象、String對象、Array對象等。
注意var s1 = "abc"和var s2 = new String("abc")的區別:typeof s1 --> string而 typeof s2 --> Object
JavaScript的對象(Object)本質上是鍵值對的集合(Hash結構),可是隻能用字符串做爲鍵。
var a = {"name": "Alex", "age": 18}; console.log(a.name); console.log(a["age"]);
遍歷對象中的內容:
var a = {"name": "Alex", "age": 18}; for (var i in a){ console.log(i, a[i]); }
建立對象:
var person=new Object(); // 建立一個person對象 person.name="Alex"; // person對象的name屬性 person.age=18; // person對象的age屬性
面向對象,在ES5中沒有類的概念,只有個構造函數,命名的首字母要大寫,實例化的時候使用new關鍵字進行實例化
function Person(name){ this.name=name } console.log(p1.name)
Person.prototype.func1 = function(){ //添加一些方法,使用prototype,叫作原型鏈 方法
console.log(this.name,'愛編程!')
}
var p1 = new Person('chao');
p1.func1() #chao
#chao 愛編程! 相似於python中的面向對象,瞭解一下就能夠了
注意:
ES6中提供了Map數據結構。它相似於對象,也是鍵值對的集合,可是「鍵」的範圍不限於字符串,各類類型的值(包括對象)均可以當作鍵。
也就是說,Object結構提供了「字符串--值」的對應,Map結構提供了「值--值」的對應,是一種更完善的Hash結構實現。
map的使用:(map也是瞭解內容,有興趣的能夠研究一下)
擴展:JavaScript面向對象之繼承:(目前做爲了解,你們有興趣的能夠自行研究一下)
建立Date對象
//方法1:不指定參數 var d1 = new Date(); //獲取當前時間 console.log(d1.toLocaleString()); //當前時間日期的字符串表示 //方法2:參數爲日期字符串 var d2 = new Date("2004/3/20 11:12"); console.log(d2.toLocaleString()); var d3 = new Date("04/03/20 11:12"); console.log(d3.toLocaleString()); //方法3:參數爲毫秒數,瞭解一下就行 var d3 = new Date(5000); console.log(d3.toLocaleString()); console.log(d3.toUTCString()); //方法4:參數爲年月日小時分鐘秒毫秒 var d4 = new Date(2004,2,20,11,12,0,300); console.log(d4.toLocaleString()); //毫秒並不直接顯示
Date對象的方法:
var d = new Date(); //getDate() 獲取日 //getDay () 獲取星期 //getMonth () 獲取月(0-11) //getFullYear () 獲取完全年份 //getHours () 獲取小時 //getMinutes () 獲取分鐘 //getSeconds () 獲取秒 //getMilliseconds () 獲取毫秒 //getTime () 返回累計毫秒數(從1970/1/1午夜)
練習:
編寫js代碼,將當前日期按「2017-12-27 11:11 星期三」格式輸出。
詳細Date對象方法:點我
var str1 = '{"name": "Alex", "age": 18}'; var obj1 = {"name": "Alex", "age": 18}; // JSON字符串轉換成對象 var obj = JSON.parse(str1); // 對象轉換成JSON字符串 var str = JSON.stringify(obj1);
RegExp相關:用的比較多
Math: