JavaScript概述
ECMAScript和JavaScript的關系
1996年11月,JavaScript的創造者--Netscape公司,決定將JavaScript提交給國際標准化組織ECMA,希望這門語言能夠成為國際標准。次年,ECMA發布262號標准文件(ECMA-262)的第一版,規定了瀏覽器腳本語言的標准,並將這種語言稱為ECMAScript,這個版本就是1.0版。
該標准一開始就是針對JavaScript語言制定的,但是沒有稱其為JavaScript,有兩個方面的原因。一是商標,JavaScript本身已被Netscape注冊為商標。二是想體現這門語言的制定者是ECMA,而不是Netscape,這樣有利於保證這門語言的開發性和中立性。
因此ECMAScript和JavaScript的關系是,前者是后者的規格,后者是前者的一種實現。
ECMAScript的歷史
年份 | 名稱 | 描述 |
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 |
注:ES6就是指ECMAScript 6。
盡管 ECMAScript 是一個重要的標准,但它並不是 JavaScript 唯一的部分,當然,也不是唯一被標准化的部分。實際上,一個完整的 JavaScript 實現是由以下 3 個不同部分組成的:
- 核心(ECMAScript)
- 文檔對象模型(DOM) Document object model (整合js,css,html)
- 瀏覽器對象模型(BOM) Broswer object model(整合js和瀏覽器)
簡單地說,ECMAScript 描述了JavaScript語言本身的相關內容。
JavaScript 是腳本語言
JavaScript 是一種輕量級的編程語言。后來出現了node.js,可以作為后端語言來開發項目,js是一個既能做前端又能做后端的語言,但是js這個作者用了10天就開發了這么個語言,所以寫的不是很完善,這個語言有很多的槽點,后面學習起來大家就知道啦。
JavaScript 是可插入 HTML 頁面的編程代碼。
JavaScript 插入 HTML 頁面后,可由所有的現代瀏覽器執行。
JavaScript 很容易學習。
JavaScript引入方式
1. Script標簽內寫代碼
在head標簽里面可以寫,在body標簽里面也可以寫,放到head標簽里面和放到body標簽里面到底有什么區別,我們后續在講~
<script> // 在這里寫你的JS代碼
//console.log('騎士計划!') #f12建打開瀏覽器的調試窗口,然后在console這個調試台就能看到這個內容了
//alert('騎士計划!') #這個是瀏覽器窗口一打開咱們這個文件,就彈出一個窗口 </script>
console:
alert:
2. 引入額外的JS文件
<script src="myscript.js"></script>
JavaScript語言規范
注釋(注釋是代碼之母)
// 這是單行注釋 /* 這是
多行注釋 */
結束符
JavaScript中的語句要以分號(;)為結束符。也就是說和縮進沒關系了
JavaScript語言基礎
變量聲明
1.JavaScript的變量名可以使用_,數字,字母,$組成,不能以數字開頭。
2.聲明變量使用 var 變量名; 的格式來進行聲明
var name = "Alex";
也可以分兩步,聲明變量var name;然后name='Alex',但是通常我們都是一步寫完 var age = 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
boolean
byte
char
class
const
debugger
double
enum
export
extends
final
float
goto
implements
import
int
interface
long
native
package
private
protected
public
short
static
super
synchronized
throws
transient
volatile
保留字列表
JavaScript數據類型
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是字符串
數值(Number)
JavaScript不區分整型和浮點型,就只有一種數字類型。
var a = 12.34; var b = 20; var c = 123e5; // 12300000 var d = 123e-5; // 0.00123
還有一種NaN,表示不是一個數字(Not a Number),也就是說是一個值,但不是數字。
常用方法:
parseInt("123") // 返回123 parseInt("ABC") // 返回NaN,NaN屬性是代表非數字值的特殊值。該屬性用於指示某個值不是數字。 parseFloat("123.456") // 返回123.456
var a2 = 1.11
typeof(a2)
"number"
parseInt('123')
123
parseFloat('123.456')
123.456
a3 = parseFloat('123.123')
123.123
typeof(a3)
"number"
a4 = parseInt('123a')
123
typeof(a3)
"number"
a5 = parseInt('abc')
NaN
字符串(String)
var a = "Hello" var b = "world; var c = a + b; console.log(c); // 得到Helloworld
常用方法:
方法 | 說明 |
.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),返回切割后的元素個數 | 分割 |

var name = 'taibai' name.length // 返回字符串元素個數 6 var name = ' taibai ' name.trim() // 去除字符兩邊空格 "taibai" var name = ' taibai ' name.trimLeft() // 去除字符串左邊空格 "taibai " name.trimRight() // 去除字符串右邊空格 " taibai" // 和python相同,對字符串做的任何操作,都是形成了新的字符串,原字符串不變 console.log(name) " taibai " // var name = 'taibai' name.charAt(3) // 通過索引獲取對應元素 "b" name.concat('nb') "taibainb" // 字符串的拼接與 + 功能相同 name.indexOf('b') // 通過元素獲取索引 3 name.slice(1,3) // 切片,尾部索引不寫默認切到最后一個元素為止 "ai" var name = 'TaiBai' name.toLowerCase() // 所有字母變小寫 "taibai" name.toUpperCase() // 所有字母變大寫 "TAIBAI" name.split('a') // 按照字符串切割,默認全部切割 (3) ["T", "iB", "i"] name.split('a',1) // 設置切割次數,切割幾次返回幾次的結果 ["T"] name.split('a',2) (2) ["T", "iB"] name.split('a',3) (3) ["T", "iB", "i"]
拼接字符串一般使用“+”
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 */
布爾值(Boolean)
區別於Python,true和false都是小寫。
var a = true; var b = false;
""(空字符串)、0、null、undefined、NaN都是false。
null和undefined
- null表示值是空,一般在需要指定或清空一個變量時才會使用,如 name=null;
- undefined表示當聲明一個變量但未初始化時,該變量的默認值是undefined。還有就是函數無明確的返回值時,返回的也是undefined。
null表示變量的值是空,undefined則表示只聲明了變量,但還沒有賦值。
還不明白,上圖吧!
對象(Object)
JavaScript 中的所有事物都是對象:字符串、數值、數組、函數...此外,JavaScript 允許自定義對象。
JavaScript 提供多個內建對象,比如 Number、String、Date、Array 等等,通過new實例化的對象都是object類型(var s = new String('hello'),var n = new Number(12)等),數組不需要new生命,類型就是object類型。
對象只是帶有屬性和方法的特殊數據類型。
數組
數組對象的作用是:使用單獨的變量名來存儲一系列的值。類似於Python中的列表。
var a = [123, "ABC"]; console.log(a[1]); // 輸出"ABC"
常用方法:
方法 | 說明 |
.length | 數組的大小 |
.push(ele) | 尾部追加元素 |
.pop() | 獲取尾部的元素 |
.unshift(ele) | 頭部插入元素 |
.shift() | 頭部移除元素 |
.slice(start, end) | 切片 |
.reverse() #在原數組上改的 | 反轉 |
.join(seq)#a1.join('+'),seq是連接符 | 將數組元素連接成字符串 |
.concat(val, ...) #連個數組合並,得到一個新數組,原數組不變 | 連接數組 |
.sort() | 排序 |
.forEach() #講了函數再說 | 將數組的每個元素傳遞給回調函數 |
.splice() #參數:1.從哪刪(索引), 2.刪幾個 3.刪除位置替換的新元素(可多個元素) | 刪除元素,並向數組添加新元素。 |
.map() #講了函數再說 | 返回一個數組元素調用函數處理后的值的新數組 |
concat示例:

var l1 = [1,2,'taibai']; l1; (3) [1, 2, "taibai"] l1.length // 獲取數組元素個數 3 l1.push('nb'); // 在數組尾部追加元素 4 l1 (4) [1, 2, "taibai", "nb"] l1.pop() // 刪除數組最后的元素並獲取 "nb" l1 (3) [1, 2, "taibai"] l1.unshift(111) // 在數組頭部插入元素 4 l1 (3) [111, 1, 2 ,"taibai"] l1.shift() // 刪除數據頭部元素 111 l1 (2) [1, 2, "taibai"] l1.slice(1,2) // 對數據切片 顧頭不顧腚 [2] l1.reverse() // 對原數組反轉 (2) ["taibai", 2, 1] l1.join('+') // 對數組元素進行拼接 與python用法相反 "taibai+2+1" var l2 = ['taibai','大濕兄']; var l3 = [666,777]; new_l = l1.concat(l2,l3); // 將多個數組合並成一個新數組,原數組不變 (7) ["taibai", 2, 1, "taibai", "大濕兄", 666, 777] // 排序 // 默認會將數組的所有元素轉化成字符串,然后按照首個字符的ASCII碼的順序進行排序。 var l1 = [12,7,83,69] l1.sort() (4) [12, 69, 7, 83] // 如果相對數字進行排序,需要引入函數的概念: function SortNumber(a,b){ return a - b }; l1.sort(SortNumber) (4) [7, 12, 69, 83] // 倆倆進行比較如果 a-b>0 則 a與b的順序進行更換。 var l1 = [83,69,12,7] l1.splice(1,2,'太白','barry', '吳老師'); (2) [69, 12] l1 (5) [83, "太白", "barry", "吳老師", 7]
關於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 arr= [ { 'sortNo': 2}, { 'sortNo': 1}, { 'sortNo': 5}, { 'sortNo': 6}, { 'sortNo': 7}, { 'sortNo': 3}, { 'sortNo': 9}, { 'sortNo': 4}, { 'sortNo': 0} ]; arr.sort(function(a, b){ return a.sortNo - b.sortNo; }); console.log(arr); //輸出結果 //{ 'sortNo': 0} //{ 'sortNo': 1} //{ 'sortNo': 2} //{ 'sortNo': 3} //{ 'sortNo': 4} //{ 'sortNo': 5} //{ 'sortNo': 6} //{ 'sortNo': 7} //{ 'sortNo': 9} 對象數組排序示例
關於遍歷數組中的元素,可以使用下面的兩種方式:
var a = [10, 20, 30, 40];
#方式一 for (var i=0;i<a.length;i++) { console.log(a[i]); }
#方式二
for (var i in a){
console.log(a[i])
}
forEach()(等學到后面再說這個)
語法:
forEach(function(currentValue, index, arr), thisValue)
參數:
參數 | 描述 | ||||||||
---|---|---|---|---|---|---|---|---|---|
function(currentValue, index, arr) | 必需。 數組中每個元素需要調用的函數。 函數參數:
|
||||||||
thisValue | 可選。傳遞給函數的值一般用 "this" 值。 如果這個參數為空, "undefined" 會傳遞給 "this" 值 |
splice()
語法:
splice(index,howmany,item1,.....,itemX)
參數:
參數 | 描述 |
---|---|
index | 必需。規定從何處添加/刪除元素。 該參數是開始插入和(或)刪除的數組元素的下標,必須是數字。 |
howmany | 必需。規定應該刪除多少元素。必須是數字,但可以是 "0"。 如果未規定此參數,則刪除從 index 開始到原數組結尾的所有元素。 |
item1, ..., itemX | 可選。要添加到數組的新元素 |
看使用:
map()(后面再講)
語法:
map(function(currentValue,index,arr), thisValue)
參數:
參數 | 描述 | ||||||||
---|---|---|---|---|---|---|---|---|---|
function(currentValue, index,arr) | 必須。函數,數組中的每個元素都會執行這個函數 函數參數:
|
||||||||
thisValue | 可選。對象作為該執行回調時使用,傳遞給函數,用作 "this" 的值。 如果省略了 thisValue ,"this" 的值為 "undefined" |
補充:
ES6新引入了一種新的原始數據類型(Symbol),表示獨一無二的值。它是JavaScript語言的第7種數據類型。
內置對象和方法
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': 'taibai','age': 18};
typeof a;
"object"
// 可以通過簡直對的形式取值
a['name'];
"taibai"
// 可以通過萬能的點取值
a.age
18
遍歷對象中的內容:
var a = {"name": "Alex", "age": 18}; for (var i in a){ console.log(i, a[i]); }
類型查詢
typeof "abc" // "string" typeof null // "object" typeof true // "boolean" typeof 123 typeof NAN // "number"
typeof undefined //undefined
typeof是一個一元運算符(就像++,--,!,- 等一元運算符),不是一個函數,也不是一個語句。
對變量或值調用 typeof 運算符將返回下列值之一:
- undefined - 如果變量是 Undefined 類型的
- boolean - 如果變量是 Boolean 類型的
- number - 如果變量是 Number 類型的
- string - 如果變量是 String 類型的
- object - 如果變量是一種引用類型或 Null 類型的,需要注意的是
typeof null
返回為object
,因為特殊值null
被認為是一個空的對象引用。
運算符
算數運算符
+ - * / % ++ -- i++,是i自加1,i--是i自減1 i++的這個加1操作優先級低,先執行邏輯,然后再自加1,而++i,這個加1操作優先級高,先自加1,然后再執行代碼后面的邏輯
比較運算符
> >= < <= != == === !==
注意:
1 == “1” // true #弱等於,將1轉換為字符串'1',在=號兩個數據類型不同的時候,會自動給你變成相同的,具體怎么一個變換規則,先不用理他,因為這種比較不好,因為以后咱們就盡量用===。 1 === "1" // false #強等於,比較類型也比較值
var i = 10; var b = '10'; // == 若等於,看着像是相等的 i == b; true // === 強等於,必須一樣 i === b; false i!=b; // 看着好像不相等的 false // 絕對是不等的 i!==b; true
提一個輸入法的高級用法:搜狗輸入法的一個高級用法:不認識的字:先輸入一個字母uhuohuohuo,就看到了焱,不會寫大寫的12345怎么辦?先輸入一個v12345,你就看到壹萬貳仟叄佰肆拾伍了。
邏輯運算符
&& || ! #and,or,非(取反)!null返回true
1 && 0; // 等同於and 0 1 || 0; // 等同於or 1 !0; // 等同於 not true
賦值運算符
= += -= *= /= #n += 1其實就是n = n + 1
好了同志們,學到這里就練習練習吧~~~然后在學~~~
流程控制
if-else
var a = 10; if (a > 5){ console.log("yes"); }else { console.log("no"); }
if-else if-else #多條件
var a = 10; if (a > 5){ console.log("a > 5"); }else if (a < 5) { console.log("a < 5"); }else { console.log("a = 5"); }
switch 切換
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(2){ case 1: case 2: case 3: console.log("c"); //當變量值為1,2,3中的任何一個時,都會在控制台打印出c break; default: console.log("d"); }
switch(2){ case 1: console.log(55); case 2:console.log(66); case 3: console.log("c"); //當變量值為1,2,3中的任何一個時,都會在控制台打印出c break; default: console.log("d"); }
打印結果:
66 c
如果滿足條件的沒有break;那么會按照上面滿足多個條件中的一個就執行對應邏輯的寫法:
並且會執行case條件滿足后的那個代碼。
var i = 5;
// 每個條件對應的結果后面必須加break,如果不加break,滿足條件的case執行完畢之后,下面的case無論條件滿足與否,都會執行。
switch (i) {
case 3:
console.log('數字3');
break;
case 4:
console.log('數字4');
break;
case 5:
console.log('數字5');
break;
case 6:
console.log('數字6');
break;
default:
console.log('沒有符合條件的結果')
};
// 多條件執行同一個結果的示例:
var i = 5;
switch (i) {
case 3: case 4: case 5:
console.log('多個條件執行同一個結果');
break;
default:
console.log('沒有符合條件的結果');
}
switch中的case子句通常都會加break語句,否則程序會繼續執行后續case中的語句。
for
for (var i=0;i<10;i++) { //就這么個寫法,聲明一個變量,變量小於10,變量每次循環自增1,for(;;){console.log(i)};這種寫法就是個死循環,會一直循環,直到你的瀏覽器崩了,就不工作了,回頭可以拿別人的電腦試試~~ console.log(i); }
// 從1打印到10
// for (變量;限制條件;循環方式) {}
for (var i = 0;i < 11;++i){
console.log(i)
};
// 循環數組:將數組的索引與元素對應打印出來。
var l1 = ['a', 'b', 'c', 'd', 'e']
for (var i= 0;i<l1.length;i++){
console.log(i,l1[i]);
};
// 直接循環一個列表,得到的是每個元素的索引:
for (i in l1){
console.log(i,l1[i]);
};
// 循環字典時,循環體中不能使用點獲取值。
var dict1 = {'name':'太白','age':10}
for (var k in dict1){
console.log(k,dict1.k);
}// 獲取不到
var dict1 = {'name':'太白','age':10}
for (var k in dict1){
console.log(k,dict1[k]);
}// 這樣才可以
while
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
來吧,大家練習一下~~~~
在我們的pycharm中可以更改js的版本
函數
函數定義
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; }
函數中的arguments參數
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(); //輸出結果是?
2.
var city = "BeiJing"; function Bar() { console.log(city); } function f() { var city = "ShangHai"; return Bar; } var ret = f(); ret(); // 打印結果是?
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。如果沒有,則不做任何操作,但是一般有參數的時候,我們在執行函數的時候就把參數賦值給了這個參數,所以不會打印出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
答案解析:
面向對象
創建對象:
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對象
創建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"); #月/日/年(可以寫成04/03/2020) 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 () 獲取星期 ,數字表示(0-6),周日數字是0 //getMonth () 獲取月(0-11,0表示1月,依次類推) //getFullYear () 獲取完整年份 //getHours () 獲取小時 //getMinutes () 獲取分鍾 //getSeconds () 獲取秒 //getMilliseconds () 獲取毫秒 //getTime () 返回累計毫秒數(從1970/1/1午夜),時間戳
var d1 = new Date(); d1 Tue Oct 22 2019 17:45:37 GMT+0800 (中國標准時間) d1.toDateString(); "Tue Oct 22 2019" d1.toLocaleString(); "2019/10/22 下午5:45:37" var d2 = new Date('04/03/1988 11:12'); d2.toLocaleString(); "1988/4/3 上午11:12:00" var d = new Date(); d.getDate(); 22 d.getDay(); 2 d.getHours(); 17
練習:
編寫js代碼,將當前日期按“2017-12-27 11:11 星期三”格式輸出。
詳細Date對象方法:點我
JSON對象
var str1 = '{"name": "chao", "age": 18}'; var obj1 = {"name": "chao", "age": 18}; // JSON字符串轉換成對象 var obj = JSON.parse(str1); // 對象轉換成JSON字符串 var str = JSON.stringify(obj1);
RegExp對象
RegExp相關:用的比較多
Math對象(類似於python的內置函數)
Math:不需要new來創建對象,直接使用Math.下面的方法
var x = -10
Math.abs(x)
10
var x = 2
Math.exp(x)
7.38905609893065
var x = 3.1415
Math.floor(x)
3
var x = 5
Math.log(x)
1.6094379124341003
var x = 1;
var y = 3;
Math.max(x,y);
3
Math.min(x,y);
1
Math.pow(2,5);
32
Math.random()
0.46414671149111175
Math.random()
0.7975478310719861
Math.round(3.45)
3
Math.round(3.55)
4