JavaScript學習筆記

Seven的JavaScript學習筆記

JavaScript是什麼

是一種運行在客戶端的腳本語言(不需要編譯,運行過程中由js解釋器逐行解釋並執行),主要用於網頁的前端驗證(檢查用戶輸入的內容是否符合一定的規則)。js程式碼逐行執行

js作用

  • 表單動態校驗(密碼強度檢測)

  • 網頁特效

  • 服務端開發(Node.js)

  • 桌面程式(Electron)

  • app(cordova)

  • 控制硬體-物聯網(ruff)

  • 遊戲開發(cocos2d-js)

html/css/js關係

js:實現業務邏輯和頁面控制(決定功能)。

js的組成

  • ECAMScirpt:js語法

  • DOM:頁面文檔對象模型

  • BOM:瀏覽器對象模型

1.ECAMScript

包括網景公司的JavaScript和微軟的Jscript。它規定了js的編程語法和基礎核心知識,是所有瀏覽器廠商共同遵循的一套js語法工業標準。

2.DOM

文檔對象模型,是處理可擴展標記語言的標準編程介面。通過dom提供的介面可以對頁面上的各種元素進行操作。

3.BOM

瀏覽器對象模型,提供了獨立於內容的、可與瀏覽器窗口進行互動的對象結構。通過bom可以操作瀏覽器窗口,比如彈出框、控制瀏覽器跳轉、獲取解析度等。

js的三種書寫方法(同css)

行內式

<input type="button" value="suger" onclick"alert('yes')">
  • 可以將單行或少量js程式碼寫在html標籤的事件屬性中(以on開頭的)

  • 在js中我們推薦使用單引號『』,html中推薦使用雙引號「」

  • 可讀性差,引號易錯(多層嵌套匹配時容易弄混)

  • 特殊情況下使用

嵌入式

<script>
     alery('hello world');
</script>

外部式

<script src="my.js"></script>
  • 利於html頁面程式碼結構化

  • 適合js程式碼量較大情況

  • script標籤中間不可以寫程式碼

js常用輸入輸出語句

  • alert(”message’) ; 瀏覽器彈出警示框 ,輸出的,展示給用戶的

  • console.log(‘message’) ;瀏覽器控制台列印輸出資訊,控制台輸出是程式設計師自己看的

  • prompt(‘information’);瀏覽器彈出輸入框,用戶可以輸入

以上語句都歸屬於瀏覽器

console.log輸出可以 :console.log(變數名1,變數名2,···)

prompt用法

prompt獲取的內容都為字元串類型

let name = prompt('請輸入姓名');//將用戶輸入存入name變數中
alert(name);//彈出剛剛用戶輸入的資訊(彈出name)

嚴格檢查模式 『use strict』

‘use strict’:嚴格檢查模式,預防js的隨意性導致的一些問題

必須寫在js的第一行!

前提:idea需要設置支援es6語法

變數的使用

聲明變數

age = 1;//聲明一個全局變數age,值為1.
var age0;//聲明一個age0的變數
let age1;//聲明一個age1的塊變數(es6新出現,現在多用let)
var name1 = 'gao',
    name2 = 'zhang',
    age2 = 10;//聲明多個變數

Js是一種弱類型語言(動態語言),所有不用提前聲明變數類型,程式運行過程中會自動確定。

變數命名規則

變數名字母、數字、下劃線或$開頭,嚴格區分大小寫,不能是關鍵字

更新變數

一個變數被重新賦值後,原有值被覆蓋,以最後一個值為準

let的基本用法

ES6 新增了let命令,用來聲明變數。它的用法類似於var,但是所聲明的變數,只在let命令所在的程式碼塊內有效。局部變數用let

{
  let a = 10;
  var b = 1;
}
a // ReferenceError: a is not defined.
b // 1

上面程式碼在程式碼塊之中,分別用letvar聲明了兩個變數。然後在程式碼塊之外調用這兩個變數,結果let聲明的變數報錯,var聲明的變數返回了正確的值。這表明,let聲明的變數只在它所在的程式碼塊有效。

for循環的計數器,就很合適使用let命令。

for (let i = 0; i < 10; i++) {
  // ...
}

console.log(i);
// ReferenceError: i is not defined

上面程式碼中,計數器i只在for循環體內(也就是花括弧{}內部)有效,在循環體外引用就會報錯。

下面的程式碼如果使用var,最後輸出的是10

var a = [];
for (var i = 0; i < 10; i++) {
  a[i] = function () {
    console.log(i);
  };
}
a[6](); // 10

上面程式碼中,變數ivar命令聲明的,在全局範圍內都有效,所以全局只有一個變數i。每一次循環,變數i的值都會發生改變,而循環內被賦給數組a的函數內部的console.log(i),裡面的i指向的就是全局的i。也就是說,所有數組a的成員裡面的i,指向的都是同一個i,導致運行時輸出的是最後一輪的i的值,也就是 10。

如果使用let,聲明的變數僅在塊級作用域內有效,最後輸出的是 6。

var a = [];
for (let i = 0; i < 10; i++) {
  a[i] = function () {
    console.log(i);
  };
}
a[6](); // 6

上面程式碼中,變數ilet聲明的,當前的i只在本輪循環有效,所以每一次循環的i其實都是一個新的變數,所以最後輸出的是6。你可能會問,如果每一輪循環的變數i都是重新聲明的,那它怎麼知道上一輪循環的值,從而計算出本輪循環的值?這是因為 JavaScript 引擎內部會記住上一輪循環的值,初始化本輪的變數i時,就在上一輪循環的基礎上進行計算。

另外,for循環還有一個特別之處,就是設置循環變數的那部分是一個父作用域,而循環體內部是一個單獨的子作用域。

for (let i = 0; i < 3; i++) {
  let i = 'abc';
  console.log(i);
}
// abc
// abc
// abc

上面程式碼正確運行,輸出了 3 次abc。這表明函數內部的變數i與循環變數i不在同一個作用域,有各自單獨的作用域(同一個作用域不可使用 let 重複聲明同一個變數)。

let不存在變數提升,不允許重複聲明,存在暫時性死區。詳見ES6 入門教程

let和var區別

  • 作用域不同。var是函數作用域,let是塊作用域。

  • let不能在定義之前訪問該變數,但是var可以。

  • let不能被重新定義,但是var是可以的

js中的數據

數據分為基本數據類型和引用數據類型

  • 引用數據類型(複雜數據類型)

  • 基本數據類型(簡單數據類型)

    • number數值類型(js不區分小數和整數)

      • 特殊值:infinity無窮大 -infinity無窮小 NaN非數值
    • string字元串類型(所用裝在引號內的內容都是這個類型)

    • 布爾類型

    • 空類型

      • undefined(變數定義了,但是沒有賦值:沒有值)

      • null(定義了,賦值為null:有值)

可以用typeof 變數名來進行數值類型檢測,返回結果為該變數的數據類型

注意:null類型返回的值是object

判斷數字類型也可以通過看控制台裡面的文字顏色判斷。

  • number類型 字為藍色

  • string類型 字為黑色

  • Boolean類型 true或false為深藍色

  • undefined和null類型為淺灰色

js數據類型轉換

轉數字

  1. number();整體不可以轉換成一個合法數字時返回NaN

  2. parseInt();把要轉換的內容一位一位查看,只有第一位不是合法數字時出現NaN,否則保留前面的數字值。

  3. parseFloat();與parseInt()相同,但是可以解析到小數部分

  4. 隱式轉換(利用算術運算轉為數值型) e.g ’12’-0即可把字元串型12轉為數值型

轉字元串

  1. string();

  2. tostring();括弧內不寫內容 用法:變數.toString();

  3. 加號拼接字元串(隱式轉換)原理:和字元串拼接的結果都是字元串 用法:變數+’字元串’

轉布爾

  • boolean();只有0,NaN,空字元串,undefined和null會轉成false,其他都是true

比較運算符

  1. = 賦值

  2. == 等於(類型不一樣,值一樣,也為true)

  3. === 絕對等於(類型和值都一樣才為true)

NaN與所有的數值都不相等,包括自己。只能通過isNaN(NaN)來判斷這個數是否是NaN(是數字返回true)

浮點數問題

console.log((1/3) === (1-2/3));

結果為false。因為存在精度問題。所以盡量避免使用浮點數進行運算

可以使用toFixed方法

數組

js中數組值不需要是相同類型的對象

var arr = [1,2,'hi',null]

當取數組下標越界時,會出現undefined

  1. 長度arr.length

注意:假如給arr.length賦值,數組大小就會發生變化。如果賦值變大,多出來的部分為undefinded;如果賦值過小,元素就會丟失

  1. indexOf() 通過元素獲取下標

注意:字元串的「1」和數字 1 是不同的。如果不存在返回-1

  1. slice() 截取數組的一部分,返回一個新數組。類似string中的substring() (也是包頭不包尾)

  2. push() , pop()尾部

arr.push('a','b');//把a,b加入到數組的尾部
arr.pop();//彈出尾部的一個元素
  1. unshift() ,shift()頭部
arr.unshift('a','b');//把a,b加入到數組的頭部
arr.shift();//彈出頭部的一個元素
  1. 排序arr.sort()

  2. 元素反轉arr.reverse()

  3. concat()

['c','b','a']
arr.concat([1,2,3]);
['c','b','a',1,2,3]
arr
['c','b','a']

注意:concat並沒有修改數組,只是返回一個新的數組(如果想保存這個返回的新數組,可以用另一個數組裝這個返回的數組arr2=arr.concat([1,2,3]);

  1. 連接符join

列印並用連接符拼接數組

['c','b','a']
arr.join('-');
"c-b-a"
  1. 多維數組
arr = [[1,2],[3,4],[5,6]];
arr[1][1];
4

對象

js中所有的鍵都是字元串,值是任意對象

person['age']//結果為3

對象是花括弧,數組是中括弧, 每個屬性之間使用逗號隔開

var person = {
    name:"ming",
    age:3,
    hobby:['js','html','css']
}

對象賦值(直接賦值)

person.name = "hong"

取對象的值

person.name
> "ming"
person.age
> 3

使用一個不存在的對象屬性不會報錯

person.haha//會出現一個undefined

動態的刪減屬性(通過delete)

delete person.name//刪除了person的name屬性,在控制台中返回一個true

動態的添加(直接給新的屬性添加值即可)

person.haha = "haha"

判斷屬性值是否在這個對象中(xxx in xxx)

'age' in person
true
//繼承了父類的toString方法
'toString' in person
true

判斷一個屬性是否是這個對象自身擁有的( hasOwnProperty() )

person.hasOwnProperty('toString')
false
person.hasOwnProperty('age')
true

字元串

  1. 轉義字元
\n  換行   \b 空格
\t  tab   \\ 斜杠  \" 雙引號
\u4e2d  \u#### Unicode字元
\x41   Ascll字元
  1. 多行字元串編寫(用“包裹)
var msg =
` hello
world
!!!!! `
  1. 模板字元串
let name = "ming";
let age = 3;
let msg = `你好,${name}`

輸出結果為 你好,ming

  1. 字元串長度
var student = "student";
console.log(student.lenth)
  1. 字元串可變性(不可變?)

  2. 大小寫轉換

//注意這裡是方法,不是屬性
student.toUpperCase();
student.toLowerCase();
  1. 獲取下標

注意:js不區分字元和字元串,字元就是長度為1的字元串

student.indexOf('s')
  1. 截取
student.substring(1);//從第1個字元截取到最後一個字元 tudent
student.substring(1,3);//[1,3)包頭不包尾 tu
  1. 字元串引號嵌套(外單內雙或外雙內單)

因為js對引號的匹配遵循就近原則,所以文字內加引號時要遵循外單內雙或外雙內單

  1. 字元串拼接用+號console.log('hello' + '!!')

注意:拼接前會把與字元串相加的任何類型轉成字元串類型,再拼成一個新的字元串。

var name;
console.log(name+'名字');
//最後結果為  undefined名字(undefined變為一個字元串和姓名顯示在控制台里)

流程式控制制

if判斷

var age = 3;
if ( age > 3 ){
    alert('haha');
}else if ( age < 3 ){
    alert('kuku');
}else{
    alert('xixi');
}

while循環,注意避免程式死循環

var age = 3;
while ( age < 10 ){
    age = age + 1;
    console.log(age);
}

do{
    age = age + 1;
    console.log(age);
}while( age < 10 )

for循環

for( let i = 0 ; i < 10 ; i++ ){
 console.log(i);
}

forEach循環

var age = [1,12,123,1234]
age.forEach(e=>{console.log(e)})//寫法1
age.forEach(function (value){   //寫法2
    console.log(value)
})

for…in(其實我沒搞懂這啥)

解釋性語言和編譯型語言

都是將程式語言翻譯成機器語言的工具(翻譯器),區別在於翻譯的時間點不同

  • 編譯器在程式碼執行之前進行編譯,生成中間程式碼文件 java

  • 解釋器在運行時進行及時解釋,並立即執行(邊解釋邊執行) js