第七十篇 js基礎

1、前言

1.JavaScript是腳本編程語言,也能夠說是一種運行在瀏覽器中的解釋型語言,js語言開發的文件是以.js爲後綴的html

2.JavaScript做用:經過在HTML文件中引入js文件來控制HTML代碼的交互功能以及前臺數據處理的業務邏輯,js語言也能夠直接寫在HTML文件中java

3.JavaScript採用的是ECMAScript語法,ECMAScript目前廣泛使用的版本有ES5和ES6兩個版本,咱們的學習也是基於這兩個版原本完成的算法

4.學習方向:js代碼書寫位置(引入位置)、js基礎語法(變量、數據類型、運算符、流程控制、函數、數據類型的使用)、js選擇器和js頁面操做四個大的方向編程

5.學習目的:完成頁面標籤與用戶的人機交互以及前臺數據處理的業務邏輯數組

2、js的引入方式

1.行間式(內嵌式)

1.語法:瀏覽器

<標籤 on+事件類型="js代碼" ></標籤>

<!-- 例子 -->
<!DOCTYPE html>
<html>
<head>
    <meta charset='utf-8'>
    <title>行間式</title>
    <style>
        #box {
            width: 300px;
            height: 300px;
            background-color: blue;
        }
    </style>
</head>  

<body>
    <!-- 必需要注意的是:「-」命名的方法必須將它省略並將鏈接的第一個字母大寫-->
    <div id="box" onclick="this.style.backgroundColor='red'">
        點擊就會變紅
    </div>
</body>
</html>

2.js代碼直接書寫在標籤的鉤子事件中dom

3.行間式引入方式必須結合事件來使用,內聯式和外聯式能夠不結合事件編程語言

2.內聯式

1.在head或body中,定義script標籤,而後在script標籤中書寫js代碼函數

2.須要注意的是:因爲HTML和js都是腳本語言,都是書寫一行執行一行,因此推薦將script標籤以及js代碼放在body標籤最下方

<!-- 例子 -->
<!DOCTYPE html>
<html>
<head>
    <meta charset='utf-8'>
    <title>內聯式</title>
    <style>
        #box {
            width: 300px;
            height: 300px;
            background-color: blue;
        }
    </style>
</head>  

<body>
    <!-- 用於沒有使用事件,因此會直接執行js代碼-->
    <div id = "box">
        直接變粉
    </div>
</body>
    <script>
        //必須將方法中的「-」及其後面的第一個字母一塊兒換成該字母大寫形式
        box.style.backgroundColor = "pink"
    </script>
</html>

3.外聯式

1.先在.js文件中寫好js代碼,而後在HTML文件中經過script標籤引入,直接在script標籤內的src屬性中連接js文件

2.連接外部js文件的script標籤就至關於單標籤,標籤內的代碼塊會自動屏蔽

3.所以,外聯式和內聯式不要混在一個script標籤中使用

//外聯式.js

bax.style.background = 'yello'
<!-- 外聯式.html -->

<!DOCTYPE html>
<html>
<head>
    <meta charset='utf-8'>
    <title>內聯式</title>
    <style>
        #box {
            width: 300px;
            height: 300px;
            background-color: blue;
        }
    </style>
</head>  

<body>
    <!-- 用於沒有使用事件,因此會直接執行js代碼-->
    <div id = "box">
        直接變粉
    </div>
</body>
    <script src='外聯式.js'></script>
</html>

3、js基礎語法

1.變量

//語法:
//關鍵字 變量名 = 變量值
//關鍵字:不寫/var/let/const
var a = 1;

1.1 全局變量

1.定義全局變量時,在變量名前面,什麼都不用加,只須要給它賦值便可;或者是在除函數外的任何位置使用var聲明的變量也是全局變量

2.全局變量能夠在頁面中任何位置被訪問

3.若是頁面不關閉,全局變量所佔用的內存就不會釋放,它會一直佔用內存空間,直到頁面關閉

4.全局變量能夠重定義,變量名前不加任何關鍵字的聲明方式不推薦使用

<script>
//隱式全局變量
a = 2
console.log(a)
//推薦使用的定義方式
var b = 3
console.log(b)
</script>

1.2 局部變量

1.局部變量,就是在函數內部用var聲明的變量

2.局部變量在函數內定義和使用,它沒法被函數外部所訪問

3.用var聲明的局部變量能夠重定義

<script>
function f(n1, n2){
    var a = 6;
    console.log(a)
}
</script>

1.3 塊級變量

1.ES5中沒有塊級做用域,ES6中增長了let命令用來聲明塊級變量

2.塊級做用域指的是由花括號限定的做用域,在塊級做用域中用let聲明的變量就是塊級變量

3.塊級變量只能在塊級做用域中定義和使用,它沒法被塊級做用域外部所訪問

4.用let聲明的塊級變量不能重定義,若是強行修改,它會報該變量已被聲明的錯誤

5.用var在塊級做用域中定義的變量,它能夠被外部訪問(由於此時它是全局變量)

<script>
{
    var a = 1; //能夠看做是全局變量
    let b = 2; //塊級變量
    console.log(b)
}

console.log(a)
</script>

1.4 常量

1.常量經過在變量名前面加 const 來定義

2.定義在全局的常量能夠被任何位置所訪問,定義在塊級或局部的常量只能在它定義的做用域中使用

3.常量不能被修改,不然也會報該常量已被聲明的錯誤

<script>
const a = 10;
console.log(a);
function f(){
    const b = 1;
    console.log(b)
}
    
{
    const c = 2;
    console.log(c)
}
    
</script>

1.5 總結

1.函數內部屬於局部做用域,大括號內部屬於塊級做用域,除此以外的區域就是全局做用域

2.在全局中定義的變量屬於全局變量,它能夠在頁面任何位置被訪問

3.在大括號內經過let定義的變量屬於塊級變量,只能在塊級做用域中使用

4.在函數內部定義的變量屬於局部變量,只能在函數中使用,當函數被調用以後,除了沒有加任何關鍵字的變量能夠被其餘做用域訪問外,其餘的都不能被訪問

5.常量不管是在塊級做用域仍是局部做用域中定義,它都沒法被外界訪問

6.當須要在塊級做用域中定義的變量不想被外界訪問時,就經過let來定義;當須要在函數中定義的變量不被外界訪問時,就使用var來定義

2.數據類型

1.JavaScript是一種弱類型語言,沒有明確的類型分類,不用過度去強調數據類型的分類,根據大致分類,能有助於本身記憶和理解,可以方便、正確靈活的使用就能夠

2.咱們能夠將數據類型分爲基本數據類型和引用數據類型兩大類

3.基本數據類型:數字類型、字符串類型、布爾類型、Null類型、未定義類型

4.引用數據類型:函數、對象、數組、時間類型等

5.能夠經過「typeof(變量名)」 或「typeof 空格 變量名」 來查看變量的數據類型

2.1 基本數據類型

1.數字類型(number)

1.用來表示數值,數值能夠是小數也能夠是整數,不像其餘強類型語言分int/float等等那麼細

var n1 = 11;

var n2 = 3.1415926;

console.log(typeof(n1), typeof n2);

2.字符串類型(string)

1.字符串是經過單引號或雙引號包裹變量值來賦值的

var s1 = 'aaa';

var s2 = "bbb";

console.log(typeof s1, typeof s2);

2.當須要多行字符串時,可使用上斜點包裹(反引號),並用冒號來分行

var s3 = `hello:
world`;

console.log(typeof s3);

3.布爾類型(boolean)

1.布爾類型只有兩個值:一個是true,一個是false,都是小寫

2.布爾值中的true能夠轉化爲數字1,false能夠轉化爲數字0

var b1 = true;
var b2 = false;
console.log(typeof b1, typeof b2);
console.log(b1 + b2);

4.空類型(Null)

1.null是JavaScript保留的關鍵字,null類型只有一個null值,表示爲空或不存在的對象引用

var nu = null;
console.log(typeof nu);

5.未定義類型(undefined)

1.undefined是全局對象Window的一個特殊屬性,顧名思義就是未定義的意思,undefined類型也只有一個值,就是Undefined,表示一個變量定義了但未賦值

2.出現undefined的常見狀況通常有三種:1)獲取一個對象的屬性不存在時,返回undefined;2)當函數沒有返回值時,返回undefined;3)函數有多個形參,調用函數時,實參數量小於形參數量,那麼多出來的形參的參數值就是undefined

var un1;
var un2 = undefined;

function f(){
    return
}
res = f();

function f1(n1, n2){
    console.log("n1: %s, n2: %s", n1, n2);
}
res1 = f1();

console.log(un1, un2, res, res1);

2.2 引用數據類型

1.函數類型(function)

1.定義一個變量並將整個函數賦值給它,就能夠經過這個變量來調用函數了,調用方法也是直接在變量名後面加小括號

var fp = function () {};
console.log(fp, typeof fp);  // f(){}  "function"
fp();

2.對象類型(object)

1.經過new一個object()函數,獲得一個對象類型

2.能夠將對象類型看做是字典類型,大括號裏面用鍵值對來做爲定義對象的屬性,多個屬性用逗號隔開

3.對象類型中能夠經過key來取值,可是key必須是定義了的數據,而不能是變量名

var obj = new object();  //等同於 var obj = {}
console.log(obj, typeof obj) //{} "object"

var dic = {name: 'king'} //等同於 var dic = {'name': 'king'}
console.log(dic['name'], typeof dic); // king   "object"
console.log(dic[name]); //顯示爲undefined類型

3.數組類型(array)

1.和列表相似,數組的值用中括號包裹,裏面用逗號隔開

2.數組本質上是一個對象類型

var arr = [1, 2, 3];
console.log(arr, typeof arr); //(2) [1, 2] 0: 1 1: 2 length: 2 __proto__: Array(0) "object"

4.時間類型

1.時間類型本質上也是對象類型

2.它是經過new加Date()函數來賦值的,能夠獲得一個當前時間

var d = new Date();
console.log(d, typeof d); // 14:35:11 GMT+0800 (中國標準時間) "object"

2.3 總結

1.數據類型之間能夠相互轉化,基本上是數字類型、字符串類型以及布爾類型之間的轉化:1)布爾類型中的true轉化爲1,false轉化爲0,能夠與數字類型進行算術運算;2)數字類型中除了0是false,其餘數值都是true;3)數字類型與字符串進行加法運算時,獲得是將兩個值進行拼接後的結果,且爲字符串類型;4)數字類型與字符串進行除加法以外的其餘運算時,獲得的是數字類型,若結果不能轉化爲具體的數值,則基本上都會轉化爲NaN

<script>
    var a = true;
    var b = 2;
    console.log(a + b); //3 數字類型
    
    var n1 = 6;
    var s1 = 'c';
    console.log(n1 + s1); // 6c 字符串類型
    console.log(n1/s1); //NaN 數字類型
    
    var s2 = '6';
    console.log(n1 - s2); //0 數字類型
</script>

2.一個變量如果Null或是NaN,那麼它的布爾值就是false;若是用undefined做爲判斷語句的條件,它會報「引用錯誤:未定義」的異常

<script>
    if(null){
        console.log('null') //不會打印,由於null的布爾值爲false
    }
    
    if(nan){
        console.log('nan') //同上
    }
    
    if(undefined){
        console.log('undefined') //報錯 ReferenceError: Undefined is not defined
    }
</script>

3.隨機數

1.經過Math中的random()方法能夠隨機生成一個取獲得0,但取不到1的[0, 1)隨機數區間

console.log(Math.random()) //[0, 1)的隨機數,理論上0能夠被取到

2.隨機出來的數乘以10,再經過parseInt()函數,則能夠生成一個取獲得0,但取不到10的[0, 10)整數區間,也就是[0, 9]的整數區間

console.log(parseInt(Math.random()));  //只能取到0
console.log(parseInt(Math.random() * 1));  //只能取到0
console.log(parseInt(Math.random() * 2));  //0到1的正整數
console.log(parseInt(Math.random() * 3));  //0到2的正整數
......
console.log(parseInt(Math.random() * 10));  //0到9的正整數
console.log(parseInt(Math.random() * 11));  //0到10的正整數

3.經過反覆演算,要想parseInt(Math.random() * number)獲得1,則number必須爲2;要想獲得2,則必須乘以的數是3;要想獲得4,則必須number是5;......

4.經過一元一次方程ax+b來思考(a和b都是正整數)如何取到正整數區間[m, n]。x是Math.random(),ax是上述中的parseInt(Math.random() * number),a爲number。想取到m,則x是0便可,則b爲m,就成了ax+m;要想最大值爲n,則ax爲n-m就能夠了,所以a就是n-m+1

var m_n = parseInt(Math.random() * (n-m+1))+m
console.log(m_n)

5.超大數取整也能夠實現[m, n]正整數區間

// (0, 1) * 超大的數 取整
// 一個正整數 % num => [0, num-1] + m => [m, num-1+m] => n = num+m-1 => num = n-m+1
// 一個正整數 % (n-m+1) + m => [m, n]
var random_num = parseInt( Math.random() * 10000000000 % (14 - 7 + 1) ) + 7;
console.log(random_num)

4.運算符

1.算術運算符

1. + - * / %

console.log(5/2); // 2.5
console.log(parseInt(5/2)); // 2  取整
console.log(parseFloat(5/2)); // 2.5
console.log(5%2);  //1 取餘

2.空字符串加數字,會獲得字符串,;純數字字符串前面有加號,會獲得數字

res1 = 1 + '';
console.log(res1, typeof res1);  // 1  字符串類型

res2 =  +'2';
console.log(res2, typeof res2);  // 2  數字類型

2.parseInt和parseFloat

1.能夠實現字符串轉化爲數字類型

2.parseInt從頭日後找,只找整數部分

3.parseFloat從頭日後找,能夠找到小數部分,且最多隻識別一個小數點

var s = '255.255.255.255string';
res1 = parseInt(s);
res2 = parseFloat(s);
console.log(res1); //255
console.log(res2); //255.255

var s1 = '3a';
console.log(parseInt(s1));  // 3
console.log(parseFloat(s1));  // 3

3.自增自減

1.++在前面的爲前自增,++在後面的爲後自增

2.前自增的優先級高於一切,也便是先自增,再作其它運算

3.後自增的優先級比賦值符號還低,通常是先運算再自增

num1 = 1;
res1 = ++num1; //會先自增再作賦值運算
console.log(num1, res1); // 2  2

num2 = 1;
res2 = num2++;  // 會先作賦值運算,再自增
console.log(num2, res2);  // 2  1

4.比較運算符

1. == 只作值的比較;=== 既比較值也比較值的數據類型

2.同理,!= 只作值的比較;!== 既比較值也比較值的數據類型

console.log(5 == '5'); // true  只比較值的大小
console.log(5 === '5'); // false  值和類型都會比較

console.log(5 != '5');  // false  值比較
console.log(5 !== '5'); //true  值比較與類型比較

5.邏輯預算法

1.&& 與,|| 或,! 非

2.用&&時:同時爲真才爲真,有一個爲假即爲假

3.用||時:同時爲假才爲假,有一個爲真即爲真

4.用 !時:非真即爲假,非假即爲真

5.短路現象:用&&時,前面爲假,後面即便爲真也不會執行;用||時,前面爲真則短路,後面即便爲真也不會執行

var n = 1;
if (false && ++n){
    console.log(n) 
}
console.log(n) //1

var a = 1;
var b = 1;
if (++a || ++b){
    console.log(a, b)  // 2  1
}

6.三目運算符

1.語法:條件 ? 結果1 : 結果2

2.若是條件成立則爲結果1,不然爲結果2

res = (true ? 'yes' : 'no');
console.log(res); // yes

5.流程控制

5.1 分支結構

1.if判斷

1.語法:1) if (條件) {代碼塊}

2) if(條件1) {代碼塊1} else if(條件2) {代碼塊2} ... else {代碼塊n}

2.條件中不能直接寫成一串,好比1 < a < 3,必須分開寫,用邏輯運算符鏈接:a>1 && a < 3

2.switch

1.語法:

switch (條件){
    case 條件1:
        代碼塊1
        break; //用來結束case,跳出switch分支結構,多個case分支能夠共享一個break
    case 條件2:
        代碼塊2
        break;
    ......
    default:
        代碼塊n  //沒有走任何case時,就會進入default分支,若是沒有錯誤狀況時能夠省略
}

month = parseInt(Math.random() * 13) + 1;
switch (month){
    case 1:
    case 3:
    case 5:
    case 7:
    case 8:
    case 10:
    case 12:
        console.log('%s月有31天', month);
        break;
    case 2:
        console.log('%s月有28天', month);
        break;
    case 4:
    case 6:
    case 9:
    case 11:
        console.log('%s月有30天', month);
        break;
}

5.2 循環

1.for

1.語法:

for (循環變量①; 條件表達式②; 增量③){
    循環體④
}

//不推薦
循環變量①
for (; 條件表達式②;){
    循環體④
    增量③
}

2.生命週期:① ②④③ ②④③ ... ②不成立,退出循環

3.for解決知道循環次數的循環

2.while

1.語法:

循環變量
while (條件表達式) {
    循環體
    增量
}

2. 1)while解決一切for與do...while能解決的問題(結合函數思想)的循環; 2)解決不知道循環次數的循環(循環用break結束)

3.do...while

1.語法:

循環變量
do {
    循環體
    增量
} while (條件表達式);

2.do...while會先執行一次循環體,再進行條件判斷

4.continue和break

1.continue的做用:跳過本次循環,轉而進行下一次循環的判斷

2.break的做用:終止循環和switch分支結構

6.函數

1.定義

關鍵字 函數名(參數列表){
函數體;
返回值
}

function 函數名(參數列表){
    代碼塊;
    return 返回值
}

//定義
function add(n1, n2){
    return n1 + n2
}

//調用
res = add(1, 2);
console.log(res);
//函數的另外兩種定義方式
var 函數名 = 關鍵字(參數列表){
    函數體;
    返回值
}
函數名()
var func = function (n1, n2){
    console.log('%s %s', n1, n2)
    return n1 + n2
}

//分兩種狀況
//當有函數體時
var 函數名 = (參數列表) => {
    函數體;
    返回值
}
var func = (n1, n2){
    console.log('%s %s', n1, n2)
    return n1 + n2
}
//當沒有函數體時(連return均可以省略了)
var 函數名 = (參數列表) => 返回值 
var func = (n1, n2) => n1 + n2

2.函數成員

1.函數名:用來調用函數,函數名存放的是函數的地址。經過函數名()調用函數

  • 1.1 引用(js中的函數也能用來作函數對象)
  • 1.2 返回值
  • 1.3 參數
  • 1.4 容器元素
//函數名的運用(引用)
function add(n1, n2){
    return n1 + n2
}

add1 = add;
res1 = add1(10, 20)
console.log(res1)

2.參數列表:將外界資源傳入內部的橋樑。你傳你的,我收個人(當實參傳少了,則未收到參數的形參賦值爲undefined;當實參傳多了,則多傳的實參將會被自動丟棄)

function f(n1, n2){
    console.log('n1: %s , n2: %s', n1, n2)
}
f(1, 2) //正常顯示
f() //兩個undefined
f(5)  //n1顯示5,n2爲undefined
f(11, 12, 13) //只顯示 n1: 11, n2: 12
  • 2.1 可變長參數,可以接收任意個數的實參
function func(...num){
    console.log(num)
}

3.函數體:解決需求的代碼塊(功能代碼塊)

4.返回值:將內部數據數據反饋給外部。只能返回一個值,不寫或空return時,會返回undefined

3.匿名函數

1.沒有聲明名字的函數

//注意用分號隔離,也能夠單獨放在一個標籤中,標籤會有本身的做用域
(function (){
    函數體
    返回值
})()

//也能夠不寫關鍵字
(()=>{console.log('匿名函數')})()

2.匿名函數調用一次後就會被回收資源

3.匿名函數自定義,能夠產生局部做用域與外界隔離,外界不能夠直接訪問

<script>
(function () {
    let number = 666
})()
</script>

<script>
console.log(number) //若是去掉匿名函數,則會打印number
</script>

7.數據類型的運用

1.字符串

// string => str
// 1)聲明
// 單引號 | 雙引號 | 反引號

// 2)字符串拼接(+)
res = 'you are' + ' ' + 'good man!';
console.log(res);

// 3)字符串的切片(slice)
s = 'you are good man!';
n_s = s.slice(8, 12);
console.log(n_s);  // good

// 4)字符串替換(replace)
s = 'you are good man!';
n_s = s.replace('man', 'woman');
console.log(n_s);

// 5)字符串拆分,切分(split)
s = 'you are good man!';
res = s.split(' ');
console.log(res);

// 6)字符串迭代(for(i of str))
s = 'abcdef';
for (num of s) {
    console.log(num)
}

2.數組

// array => list
// 1)聲明
arr = [1, 4, 2, 3, 5];
console.log(arr);

// 2)反轉(reverse)
arr.reverse();
console.log(arr);

// 3)組合(join)
str = arr.join('@');
console.log(str);

// 4)切片(slice)
new_arr = arr.slice(1, 4);
console.log(new_arr);

// 5)排序(sort)
arr.sort();
console.log(arr);

// 6)增刪改查
// 6.1 查:只有正向索引
console.log(arr[2]);

// 6.2 增
//尾增(push)
arr.push(888);  
console.log(arr);

//首增(unshift)
arr.unshift(666);  
console.log(arr);

// 6.3 刪
//尾刪(pop)
res = arr.pop(); 
console.log(arr, res);

//首刪(shift)
res = arr.shift();  
console.log(arr, res);

// 6.4 「增刪改」綜合方法:splice
//三個參數:開始操做的索引 操做的位數 操做的結果(可變長)
arr = [1, 2, 3, 4, 5];
//數組長度:arr.length
arr.splice(arr.length, 0, 666, 888); //操做的位數指的是被操做的元素個數,若是操做的位數和操做的結果數量不匹配,則以操做的結果爲基準
console.log(arr);
arr.splice(0, 2, 6, 6);
console.log(arr);

3.字典

// object => dict  // 本質是對象
// 1)定義
height = 172;
dic = {
    'name': 'king',  
    age: 26,  // 全部的key(屬性名)都是字符串類型,因此能夠省略引號
    height,  // 當value爲變量,且變量名與key同名,能夠省略value
};
console.log(dic);

// 2)訪問
console.log(dic.name);  //能夠經過「.屬性」來訪問對象的屬性
console.log(dic['age']);  // 經過key來取值

// 3)增刪改
// 增(增長屬性)
dic.gender = '男';
console.log(dic);

// 刪(delete)
delete dic.gender;
console.log(dic);

// 改(直接經過屬性名來更改屬性值)
dic.name = 'Nick';
console.log(dic);
相關文章
相關標籤/搜索