1.JavaScript概述
- javaScript與ECMAScript的相愛相殺
-
1996年11月,JavaScript的創造者--Netscape公司,決定將JavaScript提交給國際標准化組織ECMA,希望這門語言能夠成為國際標准。次年,ECMA發布262號標准文件(ECMA-262)的第一版,規定了瀏覽器腳本語言的標准,並將這種語言稱為ECMAScript,這個版本就是1.0版。 該標准一開始就是針對JavaScript語言制定的,但是沒有稱其為JavaScript,有兩個方面的原因。一是商標,JavaScript本身已被Netscape注冊為商標。二是想體現這門語言的制定者是ECMA,而不是Netscape,這樣有利於保證這門語言的開發性和中立性。 因此ECMAScript和JavaScript的關系是,前者是后者的規格,后者是前者的一種實現。
- ES6就是指ECMAScript6,盡管ECMAScript是一個重要的標准,但它並不是JavaScript唯一的部分,當然也不是唯一標准化的部分,實際上,一個完整的JavaScript實現是由以下3個不同部分組成的:
- 核心(ECMAScript)
- 文檔對象模型(DOM)Document object model(整合js,css,html)
- 瀏覽器對象模型(BOM)Broswer object model(整合js和瀏覽器)
- JavaScript是腳本語言
- JavaScript是一種輕量級的編程語言
- JavaScript是可插入HTML頁面的編程代碼
- JavaScript插入HTML頁面后,可由所有的現代瀏覽器執行
2.JavaScript引入方式
- Scipt標簽內寫代碼
-
<script> // 在這里寫你的JS代碼 </script>
- 引入額外的js文件
-
<script src="myscript.js"></script>
- 結束符:JavaScirpt中的語句要以分號;為結束符
3.JavaScript的數據類型
- JavaScript中有動態類型
-
var x; // 此時x是undefined var x = 1; // 此時x是數字 var x = "Alex" // 此時x是字符串
-
JavaScript中只有一種數值類型,不區分整形和浮點型
-
var a = 12.34; var b = 20; var c = 123e5; // 12300000 var d = 123e-5; // 0.00123
- 還有一種NaN,表示是一個數值類型,但不是一個數字
- 常用方法:
-
parseInt("123") // 返回123 parseInt("ABC") // 返回NaN,NaN屬性是代表非數字值的特殊值,該屬性用於指示某個值不是數字。 parseFloat("123.456") // 返回123.456
-
JavaScript中的字符串類型
-
var a = "Hello" var b = "world; var c = a + b; console.log(c); // 得到Helloworld
- .indexOf()方法只接收兩個參數,一個是目標字符串,一個是從什么開始,如果第一個值為負,默認從0開始找
- substring()和slice()方法的不同
-
string.slice(start, stop)和string.substring(from, to): 相同點: start=stop:返回空字符串 from=to:返回空字符串 stop省略或則to省略,則取到對末; substring特點: 如果from>to,from與to交換位置,如果一方為負數,則設為0 slice不會交換,就是若是負數則從左往右找
-
JavaScript中的布爾值類型(Boolean)
- 幾種為false的特殊數據:'', 0, null, undefined, NaN;
-
JavaScript中的對象類型
-
對象(Object)
JavaScript 中的所有事物都是對象:字符串、數值、數組、函數...此外,JavaScript 允許自定義對象。
JavaScript 提供多個內建對象,比如 String、Date、Array 等等。
對象只是帶有屬性和方法的特殊數據類型
- 數組:數組對象的作用是:使用單獨的變量名來存儲一系列的值。類似於Python中的列表
- a.pop()里面不用傳參數,沒有作用;沒有按索引的插入或刪除;
- .sort()方法:
- 沒有調用該方法時沒有使用參數,將按字母順序對數組中的元素進行排序,說得更精確點,是按照字符編碼的順序進行排序。要實現這一點,首先應把數組的元素都轉換成字符串(如有必要),以便進行比較
-
- 如果想按照其他標准進行排序,就需要提供比較函數,該函數要比較兩個值,然后返回一個用於說明這兩個值的相對順序的數字。比較函數應該具有兩個參數 a 和 b,其返回值如下:
- 若 a 小於 b,在排序后的數組中 a 應該出現在 b 之前,則返回一個小於 0 的值;
若 a 等於 b,則返回 0;
若 a 大於 b,則返回一個大於 0 的值;
- .splice(index,howmany,item1.......itmex)從索引index開始刪,刪除howmany個,item表示刪除過后要添加的元素;
-
類型查詢
- type是一個二元運算符,不是一個函數,也不是一個語句;
- 對變量或則調用typeof運算符將返回下列值之一:
- 變量時undefined的--undefined
- 變量是Boolean類型的--boolean
- 變量是Number類型的--number
- 變量是String類型的--string
- 變量是引用類型或Null類型的--object
-
運算符
- 比較運算符:== === != !== < > <= >=
- == 比較時,先將兩端轉成一種數據類型,然后比較
- === 既比較數據類型,又比較數值;
- 算數運算符:+ - * / % ++ --
- 邏輯運算符:&& || !
- 比較運算符:== === != !== < > <= >=
-
流程控制
- 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(); switch (day) { case 0: console.log("Sunday"); break; case 1: console.log("Monday"); break; default: console.log("...") } #注意case語句必須要跟一個break語句,否則程序會繼續執行后續case語句;
- for
-
for (var i=0;i<10;i++) { console.log(i); }
- forEach
-
var a = [11,22,33,44,55] a.forEach(function(i,j,e,t,u){ console.log(i,j,e,t,u) }) *****forEach沒有返回值 #i:代表取元素中的值,j代表元素對應的索引,e代表元素本身,再往后沒了,就undefined VM1167:3 11 0 (5) [11, 22, 33, 44, 55] undefined undefined VM1167:3 22 1 (5) [11, 22, 33, 44, 55] undefined undefined VM1167:3 33 2 (5) [11, 22, 33, 44, 55] undefined undefined VM1167:3 44 3 (5) [11, 22, 33, 44, 55] undefined undefined VM1167:3 55 4 (5) [11, 22, 33, 44, 55] undefined undefined
- map
-
var a = [11,22,33,44,55] a.map(function(i,j,k){ return [i,j,k] }) #輸出結果: (5) [Array(3), Array(3), Array(3), Array(3), Array(3)] 0:(3) [11, 0, Array(5)] 1:(3) [22, 1, Array(5)] 2:(3) [33, 2, Array(5)] 3:(3) [44, 3, Array(5)] 4:(3) [55, 4, Array(5)] length:5 __proto__:Array(0) map也是迭代把對象傳入,有返回值
- 三元運算
-
var a = 1; var b = 2; var c = a > b ? a : b #如果a>b 把a賦值給c,否則b賦值c;
函數
// 普通函數定義 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; } sum(1, 2); // 調用函數 // 匿名函數方式 var sum = function(a, b){ return a + b; } sum(1, 2); // 立即執行函數 *******最外層必須加上括號
應用場景:頁面加載時自動觸發的效果
函數調用完自動銷毀函數內的變量 (function(a, b){ return a + b; })(1, 2);
注意:函數返回值如果有多個,默認只返回最后一個值;
arguments:
- javascript免費贈送一個關鍵字arguments,它只在函數內部起作用,並且永遠指向當前函數的調用者傳入的所有參數,arguments類似Array,但它並不是;
-
function foo(x) { console.log('x = ' + x); // 10 for (var i=0; i<arguments.length; i++) { console.log('arg ' + i + ' = ' + arguments[i]); // 10, 20, 30 } } foo(10, 20, 30); arg 0 = 10 arg 1 = 20 arg 2 = 30
- 利用arguments,你可以獲得調用者傳入的所有參數,也就是說,即使函數不定義任何參數,還可以拿到參數的值
-
function abs(a){ if (arguments.length == 0){ return 0; } var x = arguments[0]; return x >0 ? x:-x; } undefined abs(-0) 0 abs(0) -0
rest參數
- 由於JavaScript函數允許接收任意個函數,於是我們就不得不用arguments來獲取所有參數:
-
function foo(a, b) { var i, rest = []; if (arguments.length > 2) { for (i = 2; i<arguments.length; i++) { rest.push(arguments[i]); } } console.log('a = ' + a); console.log('b = ' + b); console.log(rest); }
- 為了獲取除了已定義參數a,b之外的參數,不得不用arguments,並且循環要從索引2開始以便排除前兩個參數,要是只是為了獲得額外的rest參數,有沒有更好的方法?
- ES6標准引入了rest參數,上面的函數可以改寫為:
-
function foo(a, b, ...rest) { console.log('a = ' + a); console.log('b = ' + b); console.log(rest); } foo(1, 2, 3, 4, 5); // 結果: // a = 1 // b = 2 // Array [ 3, 4, 5 ]
函數中this的詳解
- 在函數的內部,this是一個特殊變量,它在函數調用時到底指向的是誰?;
- 如果以對象的方法形式調用,比如fun.age(),這時this指的就是fun;
- 如果單獨調用函數,比如getAge(),此時函數的this指向的就是全局對象,也就是window;
- 情況代碼分析:
-
function getAge() { var y = new Date().getFullYear();
console.log(this) #window return y - this.birth; } var xiaoming = { name: '小明', birth: 1990, age: getAge }; xiaoming.age(); // 25, 正常結果 getAge(); // NaN #這時
-
詞法分析的過程:
- JavaScript中在調用函數的一瞬間,會先進行詞法分析:
- 詞法分析過程:
- 當函數調用的前一瞬間,會先形成一個激活對象:Avtive Object(AO),並會分析以下3個方面:
-
- 1:函數參數,如果有,則將此參數賦值給AO,且值為undefined。如果沒有,則不做任何操作。
-
var age = 18; function foo(i) { console.log(i) } foo() #在詞法分析階段,AO已經被賦值undefined,當函數執行時,沒有參數傳入重新賦值, 所以打印undefined
- 2:函數局部變量,如果AO上有同名的值,則不做任何操作。如果沒有,則將此變量賦值給AO,並且值為undefined。
-
var age = 18; function foo(){ console.log(age); var age = 22; console.log(age) } foo(); #結果: undefined 22
- 3:函數聲明,如果AO上有,則會將AO上的對象覆蓋。如果沒有,則不做任何操作。
-
var age = 18; function foo(){ console.log(age); var age = 22; console.log(age); function age(){ console.log("呵呵"); } console.log(age); } foo(); // ƒ age(){ // console.log("呵呵"); // } // 22 // 22 1.判斷有沒有參數傳入 2.判斷有沒有局部同名的局部變量, 3.判斷有沒有定義的同名函數
自定義對象
- JavaScript的對象本質上是鍵值對的集合(Hash結構),但是只能用字符串作為鍵;類似於Python的字典
-
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屬性
-
ES6中提供了Map數據結構。它類似於對象,也是鍵值對的集合,但是“鍵”的范圍不限於字符串,各種類型的值(包括對象)都可以當做鍵。
也就是說,Object結構提供了“字符串--值”的對應,Map結構提供了“值--值”的對應,是一種更完善的Hash結構實現。
-
var m = new Map(); var o = {p: "Hello World"} m.set(o, "content"} m.get(o) // "content" m.has(o) // true m.delete(o) // true m.has(o) // false map
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"); 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 () 獲取完整年份 //getYear () 獲取年 //getHours () 獲取小時 //getMinutes () 獲取分鍾 //getSeconds () 獲取秒 //getMilliseconds () 獲取毫秒 //getTime () 返回累計毫秒數(從1970/1/1午夜)
- JSON對象
-
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對象
-
//RegExp對象 //創建正則對象方式1 // 參數1 正則表達式(不能有空格) // 參數2 匹配模式:常用g(全局匹配;找到所有匹配,
而不是在第一個匹配后停止)和i(忽略大小寫) // 用戶名只能是英文字母、數字和_,並且首字母必須是英文字母。
長度最短不能少於6位 最長不能超過12位。 // 創建RegExp對象方式(逗號后面不要加空格) var reg1 = new RegExp("^[a-zA-Z][a-zA-Z0-9_]{5,11}$"); // 匹配響應的字符串 var s1 = "bc123";
//RegExp對象的test方法,測試一個字符串是否符合對應的正則規則,
返回值是true或false。 reg1.test(s1); // true // 創建方式2 // /填寫正則表達式/匹配模式(逗號后面不要加空格) var reg2 = /^[a-zA-Z][a-zA-Z0-9_]{5,11}$/; reg2.test(s1); // true // String對象與正則結合的4個方法 var s2 = "hello world"; s2.match(/o/g);// ["o", "o"] 查找字符串中 符合正則 的內容 s2.search(/h/g);// 0 查找字符串中符合正則表達式的內容位置 s2.split(/o/g); // ["hell", " w", "rld"] 按照正則表達式對字符串進行切割 s2.replace(/o/g, "s"); // "hells wsrld" 對字符串按照正則進行替換 // 關於匹配模式:g和i的簡單示例 var s1 = "name:Alex age:18"; s1.replace(/a/, "哈哈哈"); // "n哈哈哈me:Alex age:18" s1.replace(/a/g, "哈哈哈"); // "n哈哈哈me:Alex 哈哈哈ge:18" 全局匹配 s1.replace(/a/gi, "哈哈哈");// "n哈哈哈me:哈哈哈lex 哈哈哈ge:18" 不區分大小寫 // 注意事項1: // 如果regExpObject帶有全局標志g,test()函數不是從字符串的開頭開始查找,
而是從屬性regExpObject.lastIndex所指定的索引處開始查找。 // 該屬性值默認為0,所以第一次仍然是從字符串的開頭查找。 // 當找到一個匹配時,
test()函數會將regExpObject.lastIndex的值
改為字符串中本次匹配內容的最后一個字符的下一個索引位置。 // 當再次執行test()函數時,將會從該索引位置處開始查找,從而找到下一個匹配。 // 因此,當我們使用test()函數執行了一次匹配之后,如果想要重新使用test()函數從頭開始查找,
則需要手動將regExpObject.lastIndex的值重置為 0。 // 如果test()函數再也找不到可以匹配的文本時,
該函數會自動把regExpObject.lastIndex屬性重置為 0。 var reg3 = /foo/g; // 此時 regex.lastIndex=0 reg3.test('foo'); // 返回true // 此時 regex.lastIndex=3 reg3.test('xxxfoo'); // 還是返回true // 所以我們在使用test()方法校驗一個字符串是否完全匹配時,一定要加上^和$符號。 // 注意事項2(說出來你可能不信系列): // 當我們不加參數調用RegExpObj.test()方法時,
相當於執行RegExpObj.test("undefined"), 並且/undefined/.test()默認返回true。 var reg4 = /^undefined$/; reg4.test(); // 返回true reg4.test(undefined); // 返回true reg4.test("undefined"); // 返回true RegExp相關 - Math對象
-
abs(x) 返回數的絕對值。 exp(x) 返回 e 的指數。 floor(x) 對數進行下舍入。 log(x) 返回數的自然對數(底為e)。 max(x,y) 返回 x 和 y 中的最高值。 min(x,y) 返回 x 和 y 中的最低值。 pow(x,y) 返回 x 的 y 次冪。 random() 返回 0 ~ 1 之間的隨機數。 round(x) 把數四舍五入為最接近的整數。 sin(x) 返回數的正弦。 sqrt(x) 返回數的平方根。 tan(x) 返回角的正切。 Math