javascript-ECMAScript


javascript介紹

Web前端有三層:

  • HTML:從語義的角度,描述頁面結構

  • CSS:從審美的角度,描述樣式(美化頁面)

  • JavaScript:從交互的角度,描述行為(提升用戶體驗)

其中JavaScript基礎又分為三個部分:

JavaScript歷史背景介紹

 

布蘭登 • 艾奇(Brendan Eich,1961年~),1995年在網景公司,發明的JavaScript。

一開始JavaScript叫做LiveScript,但是由於當時Java這個語言特別火,所以為了傍大牌,就改名為JavaScript。如同“北大”和“北大青鳥”的關系。“北大青鳥”就是傍“北大”大牌。

同時期還有其他的網頁語言,比如VBScript、JScript等等,但是后來都被JavaScript打敗了,所以現在的瀏覽器中,只運行一種腳本語言就是JavaScript

ECMAScript是一種由Ecma國際(前身為歐洲計算機制造商協會,英文名稱是European Computer Manufacturers Association)制定的標准。

JavaScript是由公司開發而成的,問題是不便於其他的公司拓展和使用。所以歐洲的這個ECMA的組織,牽頭制定JavaScript的標准,取名為ECMAScript。

簡單來說,ECMAScript不是一門語言,而是一個標准。符合這個標准的比較常見的有:JavaScript、Action Script(Flash中用的語言)。就是說,你JavaScript學完了,Flash中的程序也就輕而易舉了。

ECMAScript在2015年6月,發布了ECMAScript 6版本,語言的能力更強(也包含了很多新特性)。但是,瀏覽器的廠商不能那么快去追上這個標准。
JavaScript和ECMAScript的關系

JavaScript的發展:蒸蒸日上 

http://2004.sina.com.cn/    http://2008.sina.com.cn/   http://2012.sina.com.cn/

上面三個網站可以感受一下網頁技術的發展。 

2003年之前,JavaScript被認為“牛皮鮮”,用來制作頁面上的廣告,彈窗、漂浮的廣告。什么東西讓人煩,什么東西就是JavaScript開發的。所以瀏覽器就推出了屏蔽廣告功能。

2004年,JavaScript命運開始改變,那一年,谷歌公司開始帶頭使用Ajax技術,Ajax技術就是JavaScript的一個應用。並且,那時候人們逐漸開始提升用戶體驗了。Ajax有一些應用場景。比如,當我們在百度搜索框搜文字時,輸入框下方的智能提示,可以通過Ajax實現。比如,當我們注冊網易郵箱時,能夠及時發現用戶名是否被占用,而不用調到另外一個頁面。

2007年喬布斯發布了第一款iPhone,這一年開始,用戶就多了上網的途徑,就是用移動設備上網。
JavaScript在移動頁面中,也是不可或缺的。並且這一年,互聯網開始標准化,按照W3C規則三層分離,JavaScript越來越被重視。

2010年,人們更加了解HTML5技術,HTML5推出了一個東西叫做Canvas(畫布),工程師可以在Canvas上進行游戲制作,利用的就是JavaScript。

2011年,Node.js誕生,使JavaScript能夠開發服務器程序了。

如今,WebApp已經非常流行,就是用網頁技術開發手機應用。手機系統有iOS、安卓。比如公司要開發一個“攜程網”App,就需要招聘三隊人馬,比如iOS工程師10人,安卓工程師10人,前端工程師10人。共30人,開發成本大;而且如果要改版,要改3個版本。現在,假設公司都用web技術,用html+css+javascript技術就可以開發App。也易於迭代(網頁一改變,所有的終端都變了)。

雖然目前WebApp在功能和性能上的體驗遠不如Native App,但是“WebApp慢慢取代Native App”很有可能是未來的趨勢。
發展歷程

JavaScript入門易學性

  • JavaScript對初學者比較友好。

  • JavaScript是有界面效果的(比如C語言只有白底黑字)。

  • JavaScript是弱變量類型的語言,變量只需要用var來聲明。而Java中變量的聲明,要根據變量的類型來定義。

JavaScript的組成

JavaScript基礎分為三個部分:

  • ECMAScript:JavaScript的語法標准。包括變量、表達式、運算符、函數、if語句、for語句等。

  • DOM:操作網頁上的元素的API。比如讓盒子移動、變色、輪播圖等。

  • BOM:操作瀏覽器部分功能的API。比如讓瀏覽器自動滾動。

PS:JS機械重復性的勞動幾乎為0,基本都是創造性的勞動。而不像HTML、CSS中margin、padding都是機械重復勞動。

JavaScript的特點

(1)簡單易用:可以使用任何文本編輯工具編寫,只需要瀏覽器就可以執行程序。

(2)解釋執行(解釋語言):事先不編譯、逐行執行、無需進行嚴格的變量聲明。

(3)基於對象:內置大量現成對象,編寫少量程序可以完成目標

javascript語法

學習程序,是有規律可循的,就是程序是有相同的部分,這些部分就是一種規定,不能更改,我們成為:語法。

(1)JavaScript對換行、縮進、空格不敏感。

      備注:每一條語句末尾要加上分號,雖然分號不是必須加的,但是為了程序今后要壓縮,如果不加分號,壓縮之后將不能運行。

(2)所有的符號,都是英語的。比如括號、引號、分號。

js代碼的引入

在頁面中,我們可以在body標簽中放入<script type=”text/javascript”></script>標簽對兒,<script type=”text/javascript”></script>標簽對兒

<script type="text/javascript">

</script>

變量和賦值

變量

var a = 100;    //變量的定義和賦值
var是英語“variant”變量的縮寫。后面要加一個空格,空格后面的東西就是“變量名”,

定義變量:var就是一個關鍵字,用來定義變量。所謂關鍵字,就是有特殊功能的小詞語。關鍵字后面一定要有空格隔開。

變量的賦值:等號表示賦值,將等號右邊的值,賦給左邊的變量。

變量名:我們可以給變量任意的取名字。

 PS:在JavaScript中,永遠都是用var來定義變量,這和C、Java等語言不同
變量說明

變量名有命名規范:只能由英語字母、數字、下划線、美元符號$構成,且不能以數字開頭,並且不能是JavaScript保留字,變量區分大小寫也就是說A和a是兩個變量。

abstract、booleanbytechar、class、const、debuggerdouble、enum、export、extends、final、float、goto
implements、import、int、interface、long、native、package、private、protected、public、short、static、super、synchronized、throws、transient、volatile
js保留字

賦值

將等號右邊的值,賦給左邊的變量;等號右邊的變量,值不變。

var a = "3";
var b = 2;
a = b

console.log(a)
console.log(b)

注釋

// 我是單行注釋
/*
    多行注釋1
    多行注釋2
*/

備注:sublime中,單行注釋的快捷鍵是ctrl+/,多行注釋的快捷鍵是ctrl+shift+/

輸入輸出信息

彈出警告框:alert語句

<script type="text/javascript">
       alert("小馬哥");
</script>
alert(英文翻譯為“警報”)的用途:彈出“警告框”。

控制台輸出console.log("") 和輸入框prompt()

console.log("")
表示在控制台中輸出。console表示“控制台”,log表示“輸出”。
控制台在Chrome瀏覽器的F12中。控制台是工程師、程序員調試程序的地方。程序員經常使用這條語句輸出一些東西,來測試程序是否正確。

prompt()
實際上是一個輸入框,就是專門用來彈出能夠讓用戶輸入的對話框。prompt()語句中,用戶不管輸入什么內容,都是字符串。

alert("從前有座山");                //直接使用,不需要變量
var a = prompt("請輸入一個數字");   // 需要用變量,才能接收用戶輸入的值

示例:
alert("從前有座山");                //直接使用,不需要變量
var a = prompt("請輸入一個數字");   // 必須用一個變量,來接收用戶輸入的值
console.log和prompt

代碼示例:

<script type="text/javascript">
        var a = prompt('今天是什么天氣?');
        console.log(a);
</script>

上方代碼中,用戶輸入的內容,將被傳遞到變量 a 里面。效果如下:

基礎數據類型

變量里面能夠存儲數字、字符串等。和 python一樣,js中定義變量的時候不必指定類型,變量會自動的根據存儲內容的類型不同,來決定自己的類型。查看類型使用typeof方法。

數值類型:number

在JavaScript中,只要是數,就是數值型(number)的。無論整浮、浮點數(即小數)、無論大小、無論正負,都是number類型的。

var a = 100;            //定義了一個變量a,並且賦值100
console.log(typeof a);  //輸出a變量的類型
console.log(typeof(a));  //輸出a變量的類型
var num = 2.379
var newNum = num.toFixed(2)
console.log(newNum)
小數的保留

字符串類型:string

1.定義
var a = "abcde";
var b = '路飛';   //不區分單雙引號

console.log(typeof a);
console.log(typeof b);
2.常用方法
方法 說明
.length   #不加括號的是屬性 返回長度
.trim()    #得到一個新值 移除空白
.trimLeft() 移除左邊的空白
.trimRight() 移除右邊的空白
.concat(value, ...) #s1='hello';s.concat('xx');得到helloxx 拼接
.charAt(n) #n類似索引,從0開始,超過最大值返回''空字符串 返回第n個字符
.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 str = 'alex';
var charset = str.charAt(1);
console.log(charset);//l
chartAt() 返回指定索引的位置的字符
var str1 = 'alex';
var str2  = 'sb';
console.log(str1.concat(str2,str2));//alexsbsb
concat 返回字符串值,表示兩個或多個字符串的拼接
        var a = 'hello,world'
        var r = a.match("world")
        console.log(r)
        var r = a.match("World")
        console.log(r)

        // 正則
        var a = 'abcd,dcba'
        var r = a.match(/\w+/)
        console.log(r)

        // g表示匹配多次
        var r = a.match(/\w+/g)
        console.log(r)
match() 字符串匹配和正則匹配
var a = '1234567755';
var newStr = a.replace("4567","****");
console.log(newStr);//123****755
replace(a,b) 將字符串a替換成字符串b
var str = 'alex';
console.log(str.indexOf('e'));//2
console.log(str.indexOf('p'));//-1
console.log(str.search('e'));//2
console.log(str.search('p'));//-1
indexof()/search() 查找字符的下標,如果找到返回字符串的下標,找不到則返回-1 。
var str = '小馬哥';
console.log(str.slice(1,2));//
slice(start,end) 切片。左閉右開 分割數組 接收負參數
var  str =  '我的天呢,a是嘛,你在說什么呢?a哈哈哈';
console.log(str.substr(0,4));//我的天呢
var  str =  '我的天呢,a是嘛,你在說什么呢?a哈哈哈';
console.log(str.substr(9,6));
var  str =  '我的天呢,a是嘛,你在說什么呢?a哈哈哈';
console.log(str.substr(-3,3));
substr(start,length) 返回一個字符串:從指定位置開始,取指定字符數。
如果 indexStart 等於 indexEnd,substring 返回一個空字符串。
如果省略 indexEnd,substring 提取字符一直到字符串末尾。
如果任一參數小於 0 或為 NaN,則被當作 0。
如果任一參數大於 stringName.length,則被當作 stringName.length。
如果 indexStart 大於 indexEnd,則 substring 的執行效果就像兩個參數調換了一樣
substring(indexStart,indexEnd) 切子字符串。顧頭不顧尾
var  str =  '我的天呢,a是嘛,你在說什么呢?a哈哈哈';
console.log(str.split('a'));//["我的天呢,", "是嘛,你在說什么呢?", "哈哈哈"]  如果第二個參數沒寫,表示返回整個數組
console.log(str.split('a',2));//["我的天呢,", "是嘛,你在說什么呢?"] 如果定義了個數,則返回數組的最大長度
split('sep',n) 切割,根據n保留切割的數組長度
var str = 'EVA';
console.log(str.toLowerCase());//eva
toLowerCase():轉小寫
var str = 'xiaomage';
console.log(str.toUpperCase());
toUpperCase():轉大寫
var  str =  '     我的天呢     ';
console.log(str.trim());//我的天呢
trim() 去除字符串兩邊的空白

布爾值:boolean

var b1 = false;
console.log(typeof b1)

空元素:null

var c1 = null;//空對象. object
console.log(c1)

未定義:undefined

var d1;
//表示變量未定義
console.log(typeof d1)

內置對象類型

數組:Array

1.數組的創建
var colors = ['red','color','yellow']; //字面量方式創建(推薦)
var colors2 = new Array();//使用構造函數(后面會講)的方式創建 使用new關鍵詞對構造函數進行創建對象
2.數組的賦值
var arr = [];
//通過下標進行一一賦值
arr[0] = 123;
arr[1] = '哈哈哈';
arr[2] = '嘿嘿嘿'
3.數組的常用方法
方法 說明
.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()  #講了函數再說 返回一個數組元素調用函數處理后的值的新數組

var north = ['北京','山東','天津'];
var south = ['東莞','深圳','上海'];
var newCity = north.concat(south);
console.log(newCity)
concat方法:列表的拼接
var score = [98,78,76,100,0];
var str = score.join('|');
console.log(str);//98|78|76|100|0
join方法:將數組中的元素使用指定的字符串連接起來,它會形成一個新的字符串
var score = [98,78,76,100,0];
//toString() 直接轉換為字符串  每個元素之間使用逗號隔開
           
var str = score.toString();
console.log(str);//98,78,76,100,0
toString方法:將數組轉換成字符串
var arr = ['張三','李四','王文','趙六'];
var newArr  = arr.slice(1,3);
console.log(newArr);//["李四", "王文"]
slice(start,end):切片(左閉右開)
var arr = ['張三','李四','王文','趙六'];
var item = arr.pop();
console.log(arr);//["張三", "李四","王文"]
console.log(item);//趙六
pop方法:刪除尾元素
var arr = ['張三','李四','王文','趙六'];
var newLength= arr.push('小馬哥');//可以添加多個,以逗號隔開
console.log(newLength);//5
console.log(arr);//["張三", "李四","王文","趙六","小馬哥"]
push方法:向數組末尾添加一個元素或多個元素,並返回新的長度
var names = ['alex','xiaoma','tanhuang','angle'];
names.reverse();
console.log(names);
reverse()方法:翻轉數組
var names = ['alex','xiaoma','tanhuang','abngel'];
names.sort();
console.log(names);// ["alex", "angle", "tanhuang", "xiaoma"]
sort()方法:排序
布爾類型值 = Array.isArray(被檢測的值) ;
Array.isArray(被檢測的值):判斷是否為數組
var arr = [1,2,3]
var n = arr.shift()
console.log(arr)
console.log(n)
shift():刪除並返回數組的第一個元素
var arr = [1,2,3]
var n = arr.unshift(0)
console.log(arr)
console.log(n)
var arr = [1,2,3]
var n = arr.unshift('alex','wahaha')
console.log(arr)
console.log(n)
unshift():向數組的開頭添加一個或更多元素,並返回新的長度
var array = [1,2,3,4,5,6];
array.splice(0);      //方式1:刪除數組中所有項目
array.length = 0;     //方式1:length屬性可以賦值,在其它語言中length是只讀
array = [];           //方式3:推薦
清空數組的幾種方式
關於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)
sort的問題
    var arr = ['alex','wusir']
    arr.forEach(fn)
    function fn(item,index){
        console.log(index,item)
    }
forEach方法,設定每一個元素執行某函數
    var arr = ['alex','wusir']
    var ret = arr.map(fn)
    function fn(name,index) {
        console.log(index,name)
        return name+'sb'
    }
    console.log(ret)
map方法,循環每一個元素完成某操作返回新的值組成新數組

 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);

遍歷對象中的內容:

var a = {"name": "Alex", "age": 18};
for (var i in a){
  console.log(i, a[i]);
}

日期:Date

1.定義

創建日期對象只有構造函數一種方式,使用new關鍵字

var myDate = new Date();  //創建了一個date對象
2.常用方法

//創建日期對象
var myDate=new Date();
        
//獲取一個月中的某一天
console.log(myDate.getDate());

//返回本地時間
console.log(myDate().toLocalString());//2018/5/27 下午10:36:23

注意:以上getxxx的方法都是對時間的獲取,如果要設置時間,使用setxxx,請參考鏈接:http://www.runoob.com/jsref/jsref-obj-date.html

RegExp對象

RegExp相關:用的比較多 

//RegExp對象

//創建正則對象方式1
// 參數1 正則表達式(不能有空格)
// 參數2 匹配模式:常用g(全局匹配;找到所有匹配,而不是在第一個匹配后停止)和i(忽略大小寫)

// 用戶名只能是英文字母、數字和_,並且首字母必須是英文字母。長度最短不能少於6位 最長不能超過12位。

// 創建RegExp對象方式(逗號后面不要加空格),假如匹配用戶名是只能字母開頭后面是字母加數字加下划線的5到11位的
var reg1 = new RegExp("^[a-zA-Z][a-zA-Z0-9_]{5,11}$"); //注意,寫規則的時候,里面千萬不能有空格,不然匹配不出來你想要的內容,除非你想要的內容本身就想要空格,比如最后這個{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

注意,此處有坑:如果你直接寫一個reg2.test(),test里面啥也不傳,直接執行,會返回一個true,用其他的正則規則,可能會返回false,是因為,test里面什么也不傳,默認傳的是一個undefined,並且給你變成字符串undefined,所以能夠匹配undefined的規則,就能返回true,不然返回false


// String對象與正則結合的4個方法
var s2 = "hello world";

s2.match(/o/g);         // ["o", "o"]             查找字符串中 符合正則 的內容 ,/o/g后面這個g的意思是匹配所有的o,
s2.search(/h/g);        // 0                      查找字符串中符合正則表達式的內容位置,返回第一個配到的元素的索引位置,加不加g效果相同
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()方法校驗一個字符串是否完全匹配時,一定要加上^和$符號,把匹配規則寫的確定一些,盡量不用上面這種的寫法/xxx/。

// 注意事項2(說出來你可能不信系列):
// 當我們不加參數調用RegExpObj.test()方法時, 相當於執行RegExpObj.test(undefined),然后將這個undefined又轉為字符串"undefined",去進行匹配了, 並且/undefined/.test()默認返回true。
var reg4 = /^undefined$/;
reg4.test(); // 返回true
reg4.test(undefined); // 返回true
reg4.test("undefined"); // 返回true
RegExp相關

數學相關:Math

1.常用方法

Math.abs(x)      返回數的絕對值。
pow(x,y)    返回 x 的 y 次冪。
round(x)    把數四舍五入為最接近的整數。
sqrt(x)     返回數的平方根。
exp(x)      返回 e 的指數。
log(x)      返回數的自然對數(底為e)。
sin(x)      返回數的正弦。
tan(x)      返回角的正切。
其他方法
var x = 1.234;
//天花板函數  表示大於等於 x,並且與它最接近的整數是2
var a = Math.ceil(x);
console.log(a);//2
Math.ceil() 向上取整,'天花板函數'
var x = 1.234;
// 小於等於 x,並且與它最接近的整數 1
var b = Math.floor(x);
console.log(b);//1
Math.floor 向下取整,'地板函數'
console.log(Math.max(2,5));//5
console.log(Math.min(2,5));//2
max/min 求兩個數的最大值和最小值
var ran = Math.random();
console.log(ran);[0,1)

如果讓你取100-200之間的隨機數,怎么做?
公式:min - max之間的隨機數: min+Math.random()*(max-min)
隨機數 Math.random() 區間[0,1)

以上是咱們介紹的JS常用對象的方法,如果想參考更多內容,請參考鏈接:http://www.runoob.com/jsref/jsref-tutorial.html

數據類型之間的轉換

parseInt() :字符串轉數字

var a = '5'
var a = parseInt(a);
console.log(typeof(a))

//帶有自動凈化的功能;只保留字符串最開頭的數字,后面的中文自動消失。
console.log(parseInt("2018你真帥!!")); 

//自動帶有截斷小數的功能:取整,不四舍五入。
var a = parseInt(5.8) + parseInt(4.7);
console.log(a);
var a = parseInt(5.8 + 4.7);
console.log(a);

 parseFloat() : 字符串轉小數 

var a = parseFloat('5.8')+ parseFloat('4.7');
console.log(a);
var a = parseFloat('5.8' + '4.7');
console.log(a);

String()和.toString:轉字符串

var n1 = 123;
var str1 = String(n1);
console.log(typeof str1);

var num = 234;
console.log(num.toString())

Boolean():任何數據類型都可以轉成布爾值

var b1 = '123';  // true
var b3 = -123;  // true
var b4 = Infinity; //表示正無窮大 true

var b2 = 0;       // false
var b5 = NaN;     //false
var b6;              //表示undefined //false
var b7 = null;    //false

 

運算符

賦值運算符

以var x = 12,y=5來演示示例|

比較運算符

var x = 5;

算數運算符

var a = 5,b=2

'+': 字符串可相加,數字也可相加,字符串和數字也可以相加。值得注意的是,如果字符串和數字相加會自動把結果轉換成字符串。如下:

console.log('吃了'+'么') //'吃了么'
console.log(12+3)       //15
console.log('吃了'+3)   //'吃了3'

'-':字符串 - 數值 = 數值

var a = "3";
var b = 2; console.log(a-b) //1 console.log(b-a) //-1 字符串與數字之間相減的結果是數字

 

邏輯運算符

&& 邏輯與  ||邏輯或  !邏輯非

sum = 500
math = 98
console.log(sum>400 && math>90)  //true
sum = 400
math = 98
console.log(sum>400 && math>90)  //false
&&邏輯與,兩側條件都成立的時候才成立
sum = 500
math = 98
console.log(sum>400 || math>90)  //true
sum = 400
math = 98
console.log(sum>400 || math>90)  //true
||邏輯或,兩側條件有一個成立的時候就成立
sum = 500
console.log(!(sum>400))  //false
math = 88
console.log(!(math>90))  //true
!邏輯非 true變false,false變true
//1.模擬  如果總分 >400 並且數學成績 >89分 被清華大學錄入
//邏輯與&& 兩個條件都成立的時候 才成立
if(sum>400 && math>90){
    console.log('清華大學錄入成功')
}else{
    alert('高考失利')
}

//2.模擬 如果總分>400 或者你英語大於85 被復旦大學錄入
//邏輯或  只要有一個條件成立的時候 就成立
if(sum){
    alert('被復旦大學錄入')
}else{
    alert('高考又失利了')
}

//3.邏輯非 true變false,false變true
var sum = 0
if(!sum){
    alert('竟然考了個0分');
}
else{
    alert('好歹有個成績');
};
流程控制和與或非

流程控制

var ji  = 20;
if(ji >= 20){
    console.log('恭喜你,吃雞成功,大吉大利')
}
alert('alex');//下面的代碼還會執行
if單分支
var ji  = 20;
if(ji>=20){
    console.log('恭喜你,吃雞成功,大吉大利')
}else{
    console.log('很遺憾 下次繼續努力')
if...else...
if (true) {
   //執行操作
}else if(true){
    //滿足條件執行            
}else if(true){
   //滿足條件執行        
}else{
  //滿足條件執行
}
if...else if...else
var gameScore = 'better';
switch(gameScore){
//case表示一個條件 滿足這個條件就會走進來 遇到break跳出。如果某個條件中不寫 break,那么直到該程序遇到下一個break停止
    case 'good':
    console.log('玩的很好')
    //break表示退出
    break;
    case  'better':
    console.log('玩的老牛逼了')
    break;
    case 'best':
    console.log('恭喜你 吃雞成功')
    break;

    default:
    console.log('很遺憾')
}
case語句
var i = 1; //初始化循環變量

while(i<=9){ //判斷循環條件
    console.log(i);
    i = i+1; //更新循環條件
}
while循環
//不管有沒有滿足while中的條件do里面的代碼都會走一次
var i = 3;//初始化循環變量
do{

    console.log(i)
    i++;//更新循環條件

}while (i<10) //判斷循環條件
do-while循環
for(var i = 1;i<=10;i++){
        console.log(i)
}
 
var arr = [1,2,3,4,5]
for (n in arr){
        console.log(n)
}
for循環
var a = 1
var b =2
var c = a>b ? a:b  //如果a>b成立返回a,否則返回b
console.log(c)
三元運算符

函數

函數的定義

 function 函數名字(){

    }
function:是一個關鍵字。中文是“函數”、“功能”。
函數名字:命名規定和變量的命名規定一樣。只能是字母、數字、下划線、美元符號,不能以數字開頭。
參數:后面有一對小括號,里面是放參數用的。
大括號里面,是這個函數的語句。
語法說明

函數的調用

 函數名字();

函數的參數和返回值:形參和實參

注意:實際參數和形式參數的個數,要相同。

注意:函數只能返回一個值,如果要返回多個值,只能將其放在數組或對象中返回。

console.log(sum(3, 4));

//函數:求和
function sum(a, b) {
       return a + b;
}

偽數組:arguments

arguments代表的是實參。有個講究的地方是:arguments只在函數中使用

 

(1)返回函數實參的個數:arguments.length

fn(2,4);
fn(2,4,6);
fn(2,4,6,8);

function fn(a,b,c) {
    console.log(arguments);
    console.log(fn.length);         //獲取形參的個數
    console.log(arguments.length);  //獲取實參的個數
    console.log("----------------");
}

結果:

(2)之所以說arguments是偽數組,是因為:arguments可以修改元素,但不能改變數組的長短。舉例:

fn(2,4);
fn(2,4,6);
fn(2,4,6,8);

function fn(a,b) {
    arguments[0] = 99;  //將實參的第一個數改為99
    arguments.push(8);  //此方法不通過,因為無法增加元素
}
// 匿名函數方式,多和其他函數配合使用,后面我們就會用到了
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)
自執行函數

函數的全局變量和局部變量

局部變量

在JavaScript函數內部聲明的變量(使用 var)是局部變量,所以只能在函數內部訪問它(該變量的作用域是函數內部)。只要函數運行完畢,本地變量就會被刪除。

全局變量:

在函數外聲明的變量是全局變量,網頁上的所有腳本和函數都能訪問它。

變量生存周期:

JavaScript變量的生命期從它們被聲明的時間開始。局部變量會在函數運行以后被刪除。全局變量會在頁面關閉后被刪除。

作用域

首先在函數內部查找變量,找不到則到外層函數查找,逐步找到最外層。

幾個例子:

var city = "BeiJing";
function f() {
  var city = "ShangHai";
  function inner(){
    var city = "ShenZhen";
    console.log(city);
  }
  inner();
}

f();  //輸出結果是? ---> ShenZhen
例1
var city = "BeiJing";
function Bar() {
  console.log(city);
}
function f() {
  var city = "ShangHai";
  return Bar;
}
var ret = f();
ret();  // 打印結果是?---> BeiJing
例2
var city = "BeiJing";
function f(){
    var city = "ShangHai";
    function inner(){
        console.log(city);
    }
    return inner;
}
var ret = f();
ret();   ---> ShangHai
例3:閉包

面向對象(了解)

創建對象的幾種常用方式:

1.使用Object或對象字面量創建對象

2.工廠模式創建對象

3.構造函數模式創建對象

4.原型模式創建對象

使用Object或對象字面量創建對象

JS中最基本創建對象的方式:

var student = new Object();
student.name = "easy";
student.age = "20";

這樣,一個student對象就創建完畢,擁有2個屬性name以及age,分別賦值為"easy"20

如果你嫌這種方法有一種封裝性不良的感覺。來一個對象字面量方式創建對象。

var sutdent = {
  name : "easy",
  age : 20
};

這樣看起來似乎就完美了。但是馬上我們就會發現一個十分尖銳的問題:當我們要創建同類的student1,student2,…,studentn時,我們不得不將以上的代碼重復n次....

var sutdent1 = {
  name : "easy1",
  age : 20
};

var sutdent2 = {
  name : "easy2",
  age : 20
};

...

var sutdentn = {
  name : "easyn",
  age : 20
};
創建多個變量的困擾

有個問題?能不能像工廠車間那樣,有一個車床就不斷生產出對象呢?我們看”工廠模式”。

工廠模式創建對象

JS中沒有類的概念,那么我們不妨就使用一種函數將以上對象創建過程封裝起來以便於重復調用,同時可以給出特定接口來初始化對象

function createStudent(name, age) {
  var obj = new Object();
  obj.name = name;
  obj.age = age;
  return obj;
}

var student1 = createStudent("easy1", 20);
var student2 = createStudent("easy2", 20);
...
var studentn = createStudent("easyn", 20);

這樣一來我們就可以通過createStudent函數源源不斷地”生產”對象了。看起來已經高枕無憂了,但貪婪的人類總有不滿足於現狀的天性:我們不僅希望”產品”的生產可以像工廠車間一般源源不斷,我們還想知道生產的產品究竟是哪一種類型的。

比如說,我們同時又定義了”生產”水果對象的createFruit()函數:

function createFruit(name, color) {
  var obj = new Object();
  obj.name = name;
  obj.color = color;
  return obj;
}

var v1 = createStudent("easy1", 20);
var v2 = createFruit("apple", "green");
水果對象

對於以上代碼創建的對象v1、v2,我們用instanceof操作符去檢測,他們統統都是Object類型。我們的當然不滿足於此,我們希望v1是Student類型的,而v2是Fruit類型的。為了實現這個目標,我們可以用自定義構造函數的方法來創建對象

構造函數模式創建對象

在上面創建Object這樣的原生對象的時候,我們就使用過其構造函數:

var obj = new Object();
var arr = new Array(10);  //構造一個初始長度為10的數組對象
構造函數創建原生數組

在進行自定義構造函數創建對象之前,我們首先了解一下構造函數普通函數有什么區別。

1、實際上並不存在創建構造函數的特殊語法,其與普通函數唯一的區別在於調用方法。對於任意函數,使用new操作符調用,那么它就是構造函數;不使用new操作符調用,那么它就是普通函數。

2、按照慣例,我們約定構造函數名以大寫字母開頭,普通函數以小寫字母開頭,這樣有利於顯性區分二者。例如上面的new Array(),new Object()。

3、使用new操作符調用構造函數時,會經歷(1)創建一個新對象;(2)將構造函數作用域賦給新對象(使this指向該新對象);(3)執行構造函數代碼;(4)返回新對象;4個階段。

ok,了解了構造函數普通函數的區別之后,我們使用構造函數將工廠模式的函數重寫,並添加一個方法屬性: 

function Student(name, age) {
  this.name = name;
  this.age = age;
  this.alertName = function(){
    alert(this.name)
  };
}

function Fruit(name, color) {
  this.name = name;
  this.color = color;
  this.alertName = function(){
    alert(this.name)
  };
}

這樣我們再分別創建Student和Fruit的對象:

var v1 = new Student("easy", 20);
var v2 = new Fruit("apple", "green");
alert(v1 instanceof Student);  //true
alert(v2 instanceof Student);  //false
alert(v1 instanceof Fruit);  //false
alert(v2 instanceof Fruit);  //true

alert(v1 instanceof Object);  //true 任何對象均繼承自Object
alert(v2 instanceof Object);  //true 任何對象均繼承自Object
instanceof操作符來檢測對象類型

這樣我們就解決了工廠模式無法區分對象類型的尷尬。那么使用構造方法來創建對象是否已經完美了呢?使用構造器函數通常在js中我們來創建對象。

我們會發現Student和Fruit對象中共有同樣的方法,當我們進行調用的時候這無疑是內存的消耗。

我們完全可以在執行該函數的時候再這樣做,辦法是將對象方法移到構造函數外部:

function Student(name, age) {
  this.name = name;
  this.age = age;
  this.alertName = alertName;
}

function alertName() {
  alert(this.name);
}

var stu1 = new Student("easy1", 20);
var stu2 = new Student("easy2", 20);

在調用stu1.alertName()時,this對象才被綁定到stu1上。

我們通過將alertName()函數定義為全局函數,這樣對象中的alertName屬性則被設置為指向該全局函數的指針。由此stu1和stu2共享了該全局函數,解決了內存浪費的問題

但是,通過全局函數的方式解決對象內部共享的問題,終究不像一個好的解決方法。如果這樣定義的全局函數多了,我們想要將自定義對象封裝的初衷便幾乎無法實現了。更好的方案是通過原型對象模式來解決。

原型的模式創建對象

原型鏈甚至原型繼承,是整個JS中最難的一部分也是最不好理解的一部分,在這里由於我們課程定位的原因,如果對js有興趣的同學,可以去查閱一下相關JS原型的一些知識點。更加有助於你以后前端JS的面試。

function Student() {
    this.name = 'easy';
    this.age = 20;
}


Student.prototype.alertName = function(){
    alert(this.name);
};

var stu1 = new Student();
var stu2 = new Student();

stu1.alertName();  //easy
stu2.alertName();  //easy

alert(stu1.alertName == stu2.alertName);  //true 二者共享同一函數
示例


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM