JavaScript學習筆記
- 2022 年 1 月 24 日
- 筆記
- 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
上面程式碼在程式碼塊之中,分別用let
和var
聲明了兩個變數。然後在程式碼塊之外調用這兩個變數,結果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
上面程式碼中,變數i
是var
命令聲明的,在全局範圍內都有效,所以全局只有一個變數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
上面程式碼中,變數i
是let
聲明的,當前的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數據類型轉換
轉數字
-
number();整體不可以轉換成一個合法數字時返回NaN
-
parseInt();把要轉換的內容一位一位查看,只有第一位不是合法數字時出現NaN,否則保留前面的數字值。
-
parseFloat();與parseInt()相同,但是可以解析到小數部分
-
隱式轉換(利用算術運算轉為數值型) e.g ’12’-0即可把字元串型12轉為數值型
轉字元串
-
string();
-
tostring();括弧內不寫內容 用法:變數.toString();
-
加號拼接字元串(隱式轉換)原理:和字元串拼接的結果都是字元串 用法:變數+’字元串’
轉布爾
- boolean();只有0,NaN,空字元串,undefined和null會轉成false,其他都是true
比較運算符
-
= 賦值
-
== 等於(類型不一樣,值一樣,也為true)
-
=== 絕對等於(類型和值都一樣才為true)
NaN與所有的數值都不相等,包括自己。只能通過isNaN(NaN)來判斷這個數是否是NaN(是數字返回true)
浮點數問題
console.log((1/3) === (1-2/3));
結果為false。因為存在精度問題。所以盡量避免使用浮點數進行運算
可以使用toFixed方法
數組
js中數組值不需要是相同類型的對象
var arr = [1,2,'hi',null]
當取數組下標越界時,會出現undefined
- 長度
arr.length
注意:假如給arr.length
賦值,數組大小就會發生變化。如果賦值變大,多出來的部分為undefinded;如果賦值過小,元素就會丟失
indexOf()
通過元素獲取下標
注意:字元串的「1」和數字 1 是不同的。如果不存在返回-1
-
slice()
截取數組的一部分,返回一個新數組。類似string中的substring()
(也是包頭不包尾) -
push()
,pop()
尾部
arr.push('a','b');//把a,b加入到數組的尾部
arr.pop();//彈出尾部的一個元素
unshift()
,shift()
頭部
arr.unshift('a','b');//把a,b加入到數組的頭部
arr.shift();//彈出頭部的一個元素
-
排序
arr.sort()
-
元素反轉
arr.reverse()
-
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]);
)
- 連接符
join
列印並用連接符拼接數組
['c','b','a']
arr.join('-');
"c-b-a"
- 多維數組
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
字元串
- 轉義字元
\n 換行 \b 空格
\t tab \\ 斜杠 \" 雙引號
\u4e2d \u#### Unicode字元
\x41 Ascll字元
- 多行字元串編寫(用“包裹)
var msg =
` hello
world
!!!!! `
- 模板字元串
let name = "ming";
let age = 3;
let msg = `你好,${name}`
輸出結果為 你好,ming
- 字元串長度
var student = "student";
console.log(student.lenth)
-
字元串可變性(不可變?)
-
大小寫轉換
//注意這裡是方法,不是屬性
student.toUpperCase();
student.toLowerCase();
- 獲取下標
注意:js不區分字元和字元串,字元就是長度為1的字元串
student.indexOf('s')
- 截取
student.substring(1);//從第1個字元截取到最後一個字元 tudent
student.substring(1,3);//[1,3)包頭不包尾 tu
- 字元串引號嵌套(外單內雙或外雙內單)
因為js對引號的匹配遵循就近原則,所以文字內加引號時要遵循外單內雙或外雙內單
- 字元串拼接用+號
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