前端視頻學習(四、JavaScript基礎)

JS課程安排:

  1. JS基礎 :6天
  2. WebAPI: 6-7天
  3. JS高級:5天
  4. jQuery:5天

JS基礎:

  1. 基本介紹、語法、變量、數據類型、運算符
  2. 條件、循環
  3. 數組、函數
  4. 函數——作用域、預解析
  5. 創建對象、數據類型深入、內置對象
  6. 內置對象和方法

目錄

1. 簡介

Brendan Eich 在95年花了10天時間設計出了JavaScript,並且因爲它不喜歡Java,所以也不喜歡JavaScript

1.1 JS分三個部分:

  1. ECMAScript 標準——基本語法
  2. DOM——Document Object Model
  3. BOM—— Browser Object Model

在這裏插入圖片描述

1.2 JS能做的東西:

  1. 網頁特效
  2. 服務端開發 node.js
  3. 命令行工具 node.js
  4. 桌面 Electron
  5. App Cordova
  6. 控制硬件-物聯網 Ruff
  7. 遊戲開發 cocos2d-js

1.3 JavaScript語言特點

  1. 腳本語言
  2. 解釋性語言
  3. 動態類型語言
  4. 基於對象的語言

1.4 Js代碼書寫位置

  1. 在script標籤中
<script>
	alert('haha');
</script>
  1. 寫在html標籤中
<button onclick="alert('abc');" />
  1. **在外部.js文件中,由html文件引入: **
<script src="demo.js" ></script>

1.5 js代碼的注意問題

  1. 在一對script標籤中有錯誤的代碼,後面的代碼也不會執行
  2. 一對script標籤的錯誤,不會影響其他script標籤中的代碼執行;
  3. script標籤中,本來要寫 type="text/javascript"或者language="JavaScript",但是html5標準中可以省略
  4. typelanguage也可以同時寫在script
  5. script標籤在頁面中可以出現多個
  6. script標籤的位置一般放在<body>內部的最後端,有時會放在head中
  7. 如果一個script標籤的作用是引入外部的js文件,那麼這個script標籤中不要寫代碼

WebStorm不是直接打開文件顯示的,而是自己以一個小型服務器的方式瀏覽頁面


2. 變量

2.1 變量聲明初始化

a. 基本代碼規範:

  1. JS變量區分大小寫
  2. 聲明變量使用var
  3. 字符串使用單引號或者雙引號
  4. 語句用分號結尾

b. 變量名規範:

  1. 一般以字母,$,下劃線,數組組成,但不能以數字開頭
  2. 變量名一般小寫
  3. 使用camelCase方式命名
  4. 不能使用關鍵字
  5. 第二次初始化同一個變量名,則初始化會變成賦值

c. 聲明+初始化:

var num = 10;
var num1, num2, num3;
var num1, num2, num3 = 10;
var num1=10, num2 = 10, num3 = 20;
var num1 = num2 = num3 = 30;


var name = '小黑';   // 字符串使用 " 或者 ' 
var flag = true;
var obj = null;
console.log(flag);

2.2 代碼註釋

// 單行註釋

/* 
	多行註釋
*/


/**
* 這是說明這個函數是幹什麼的
* @param param1 這裏說明這個param1參數是幹什麼的
* @return {}  這裏說明返回值是個什麼
* */

2.3 變量類型

a. 原始數據類型:

  1. number: 整數和小數都是 number 類型, NaN也是number類型
  2. string
  3. boolean
  4. null類型還是 object
  5. undefined : 變量聲明沒賦值、 函數沒有返回值確賦值給了一個變量; undefined 和數字運算,結果爲 NaN,也是number類型
  6. object

b. 查看變量類型:

typeof(變量);
typeof 變量;
// number string boolean object undefined object function

c. 進製表示

十六進制: 0x
八進制: 0

d. 數字類型

數字最大最小值

Number.MAX_VALUE
Number.MIN_VALUE
Infinity    // 無窮大
-Infinity   //無窮小

不要用小數和小數相等

(0.1+0.2) == 0.3   // false

和NaN比較

  • 數字和undefined運算,結果是NaN,類型爲number;
  • 數字和NaN運算,結果是NaN,類型爲number
  • 使用isNaN判斷
  • isNaN不光能用來判斷NaN,主要可以判斷是不是數字
var num;
typeof (num+10);   // number---NaN
num+10 == NaN;  // false  , NaN之間用 == 比較都是false

// 使用 isNaN判斷
isNaN(10);    // NaN != NaN

e. 字符串

長度

// 長度
var strvar = "hahsasdsad";
strvar.length

拼接

  1. 加法中有一個是字符串,則會轉變成字符串拼接
  2. 如果使用了減法、乘法、除法,則會嘗試將字符串變成數字後運算。如果轉換失敗,則返回NaN
// 拼接:
str3 = str1 + str2
console.log(10+"20");   // 1020
console.log(10-"20");   // -10
console.log(10 * "5");   // 50

2.4 ★類型轉換

其他類型轉數字:

parseInt("10");   //10  
parseInt("10asdasdasd");   //10
parseInt("10.98");   //10
parseInt("asd10");   //NaN
parseFloat("10")   //10
parseFloat("10asdasd")   //10
parseFloat("10.98")   //10.98
parseFloat("10.98asdsad")   //10.98
parseFloat("asd10asdasd")   //NaN

Number就是轉數字, 和parse不同,它需要全部都是數字,更加嚴格

Number("10");   //10
Number("10asdasd");  //NaN
Number("10.98");   //10.98
Number("10.98asdsad"); //NaN
Number("asd10asdasd");  //NaN

其他類型 轉字符串:

第一種:(要變量有意義,比如不能爲 undefined, null

num.toString();     //變量無意義,則無法使用 toString()

第二種:

String(var);

第三種:

var + '';

其他類型轉boolean:

Boolean(var):
1       true
0       false
11      true
-10     true
"hah"   true
""      false
null    false
undefined false

3. 操作符

  • 算數運算符: + - * / % ( python沒有整除,需要用 parseInt來取整)
  • 一元運算符: ++ --
  • 二元運算符:
  • 三元運算符: ?:
  • 賦值運算符: += -= /= %= *=字符串和數字比較的時候會有類型轉換)
  • 關係運算符:> >= < <= == === != !===
==  不嚴格的等於:
var str = "5";
var int = 5;
str == int ; // true

=== 嚴格的等於:
str === int ; // false
  • 邏輯運算符: && || !
var a = null;
// 沒報錯,短路比較
if(a != null && a.length > 5){
    alert(a.length);
}

算術運算表達式
關係運算表達式
邏輯運算表達式

優先級

優先級從高到底
	1. ()  優先級最高
	2. 一元運算符  ++   --   !
	3. 算數運算符  先*  /  %   後 +   -
	4. 關係運算符  >   >=   <   <=
	5. 相等運算符   ==   !=    ===    !==
	6. 邏輯運算符 先&&   後||
	7. 賦值運算符

4. 條件

if (條件){    // 條件部分會被轉換成 Boolean
}

if(){
} else{
}

if(){

} else if(){

} else{

}

//三元表達式
let result = a?b:c;


// switch判斷
switch (key) {
    case value:
        //代碼..
        break;

    default:
        break;
}

switch 注意事項

switch內部的比較是使用的===,判斷類型+內容,而不是==

var age = "10"
switch (key) {
    case 10:
        ..
        break;

    case "10":
        console.log("字符串10");    // 會執行這一句
        break;
}

5. 循環

document.write()寫到HTML文檔中的東西,在源代碼中看不到,而在調試窗口的element能看到。

  • while
  • do-while
  • for
  • continue, break
while (condition) {
	語句    
}


do {
    語句
} while (condition);


for (let index = 0; index < array.length; index++) {
    const element = array[index];    
}


for in

for of

a.foreach

6. 數組

6.1 創建數組

  1. 通過構造函數
var ar = new Array();   // 構造函數創建空數組

var ar = new Array(5);   // 創建長度爲5的數組, 每個元素都是 undefined

var ar = new Array(1,2,"3",new Object());   // 直接傳入內容

console.log(arra.length);
  1. 通過字面量
var ar = [];   //字面量創建

數組特點

  1. 使用長度的方式創建數組,數組內部的值都是undefined
  2. 數組可以存儲不同類型內容
  3. 可以動態給數組的任意索引賦值,這能改變數組長度,並且沒有值的都是undefined

6.2 動態改變數組長度

var ar = [];
alert(a.length);  // 0

ar[1] = ""; 
alert(a.length);  // 2

a[2] ;     //undefined  不存在的值會undefined

6.3 遍歷


for(let i = 0; i < a.length; i++){
	
}

a.forEach(element => {
      console.log(element);  
    });


for (const iterator of a) {
    console.log(iterator);
}

7. 函數

7.1 函數定義

function funcname(arg1, arg2){
    ...
    return result;
}

Math.PI

★函數的注意問題:

  1. 函數一旦重名(多次定義),後面的會覆蓋前面的函數
function f1(){
    console.log('1');
}
f1();
function f1(){
    console.log('2');
}
f1();
// 結果會打印2次 2
  1. 形參的個數和實參的個數可以不一致(可多可少), 沒有傳遞的值或者接收了沒有return的函數值,結果是undefined
function haha(x,y) {

        console.log(x);
        console.log(y);
        console.log(arguments.length);
}

haha();   // undefined  undefined  0
haha(1,2,3);   // 1  2   3
  1. 直接輸出函數名字,結果爲函數的代碼

7.2 函數的參數和返回值

a. 返回值問題

  • 如果沒有return,函數返回值爲undefined
  • 如果return後面沒有內容,則返回值也是undefined

b. arguments

arguments是一個僞數組

function funcname(x, y){
    console.log(arguments); // 獲取所有傳入的參數  arguments.length
}

7.3 命名函數和匿名函數

函數有名字就是命名函數,沒名字就是匿名函數

function(){
	// 這是匿名函數
}


function f1(){
	// 這是匿名函數
}

函數自調用——匿名函數直接調用

(function (){

})()

7.4 ★函數聲明和函數表達式

  • 函數能夠調用,是因爲函數名存儲的函數的代碼:
  • 如果函數能被調用,則調用方式爲: 函數的代碼();

1. 函數聲明

function f1(){

}
f1();   // 函數代碼();  

2. 函數表達式

函數表達式後面要加分號

var f2 = function (){

};
f2();

3. 函數表達式的覆蓋問題

函數聲明重名的,後面覆蓋前面的,導致前面的失效; 而函數表達式,只有在賦值的時候,纔會覆蓋:

function f1(){
    console.log('1');
}
f1(); // 2
function f1(){
    console.log('2');
}
f1(); // 2
f2 = function (){

}
f2();
// 1 
f2 = function (){
    console.log('2');
}
f2();
// 2

7.5 函數作爲參數和返回值

函數作爲參數,叫做回調函數

typeof f1   // function

function f1(f2){
    f2();
}
function f2(){

}

作爲返回值:

function f3(){
    return function(){
        console.log();
    }
}
fn = f3();
fn();

7.6 ★作用域

1. 跨越script標籤

跨越script標籤,也可以引用:

<script>
	var num = 10;
	console.log(num);  // 10
</script>
<script>
	console.log(num);  // 10
</script>

2. 塊級作用域

在沒有let之前,js沒有塊級作用域

{
	var num = 10;
}	
console.log(num);  // 10

使用let定義的,纔是塊級作用域; 用var的話,沒有塊級作用域

3. 全局變量

  • var在函數外面聲明的變量是全局變量
  • 除了函數內部定義的, 其他定義的都是全局變量(除了let)

4. 局部變量

函數內部定義的是局部變量, 只在函數內部有效

5. 隱式全局變量

  • 聲明變量沒有使用var,叫作隱式全局變量
  • 隱式全局變量定義在函數中,外面也能訪問
  • 定義變量使用var是不會被刪除的,沒有使用var是會被刪除的
var num1 = 10;
num2 = 20;
delete num1;
delete num2;
console.log(typeof num1);  // number
console.log(typeof num2);  // undefined

6. 作用域鏈

  • 標籤內定義的叫做0級作用域
  • 0級作用域定義的函數內部,叫做1級作用域
  • 函數最內層查找變量的順序,是 N級–> … --> 3級–> 2級–>1級–>0級

下面的num,會一層層向上找,直到找到

var num = 10;
function f1(){
    var num = 20;
    function f2(){
        var num = 30;
        function f3(){
            var num = 40;
            console.log(num);
        }
        f3();
    }
    f2();
}
f1();

7.5 ★★預解析

JavaScript代碼的執行是由瀏覽器中的JavaScript解析器來執行的。JavaScript解析器執行JavaScript代碼的時候,分爲兩個過程:

  1. 預解析過程
  2. 代碼執行過程
  1. 把變量的聲明提升到當前作用域的最前面,只會提升聲明,不會提升賦值。
  2. 把函數的聲明提升到當前作用域的最前面,只會提升聲明,不會提升調用。
  3. 先提升var,在提升function
  4. 變量提升
    定義變量的時候,變量的聲明會被提升到作用域的最上面,變量的賦值不會提升。
  5. 函數提升
    JavaScript解析器首先會把當前作用域的函數聲明提前到整個作用域的最前面

特點

  1. 瀏覽器把變量、函數的聲明提前了,提前到當前作用域的最上面,不會提升到作用域之外
  2. 多對<script>之間的預解析不會衝突——只會在各自範圍內進行預解析
  3. 先提升var再提升function,即 var在function之前
  4. 函數表達式不會提升

例子

例1——預解析提前 變量聲明

console.log(num);       // 結果爲 undefined,代表變量聲明瞭但是沒賦值
var num = 10;     

例2——預解析提前函數聲明

f1()   // 調用成功,說明函數聲明被提前了
function f1(){
	console.log("haha")   
}

例3——num提前到作用域內部的頂端

var num = 20;
function f1(){
    console.log(num);   // 結果爲undefined, 說明 內部的num被提升到了 f1內部作用域的頂端
    var num = 10;
}
f1();

//相當於:
var num = 20;
function f1(){
	var num;
	console.log(num);
	num = 10;
}

例4:

f1();                 // 打印 undefined
var num = 20;
function f1(){
    console.log(num);   
}

// 相當於:
var num;
function f1(){
	console.log(num);
}
f1();   // 所以是undefined
num = 20;

例5——預解析不會把變量提升到函數外

function f1(){
	console.log(num);  // undefined
	var num = 10;
}
f1();
console.log(num);  // 報錯

//相當於
function f1(){
	var num;
	console.log(num);
	num = 10;
}
f1();
console.log(num);

例6:——預解析只在script標籤內部(同一個全局作用域內)

<script>
f1();   // 1
function f1(){
	console.log("1");
}
</script>

<script>
function f1(){
	console.log("1");
}
</script>
<script>
function f1(){
	console.log("1");
}
</script>

<script>
f1();   // 2
function f1(){
	console.log("1");
}
</script>

例7:

console.log(a);    // 易錯點:輸出函數代碼
function a(){               
    console.log('hahaha');
}
var a = 1;   
console.log(a);     // 輸出1

// 相當於
var a ;
function a(){...}  // 此處a就變成了代碼
console.log(a);
a = 1;
console.log(a);

例8:—— 隱式全局變量的提升

f1();
console.log(c);    // 9
console.log(b);     // 9
console.log(a);     // 報錯
function f1(){
    var a = b= c = 9;    //易錯點
    console.log(a);
    console.log(b);
    console.log(c);
}

//提升後爲:
function f1(){
    var a;  //局部變量
    a = 9;
    b = 9;  //隱式全局變量
    c = 9;  //隱式全局變量
    console.log(a);
    console.log(b);
    console.log(c);
}
f1();
console.log(c);
console.log(b);
console.log(a);

例9——函數表達式不會提升

f1();       //無法調用, 因爲函數表達式不會提升, 只提升函數定義
var f1 = function(){
    console.log(a);
    var a = 10;
}

// 提升後爲:
var f1;
f1();
f1 = function(){...};

8. 對象

  • JS本來沒有類的概念,只有對象。
  • JS是基於對象的語言——萬物皆對象,而不是真正的面向對象的語言,但是可以模擬面向對象

  • 判斷對象類型: 變量 instanceof 類型
  • 訪問自己對象的屬性/方法: this

8.1 創建對象

1. 通過調用系統的構造函數創建

new Object()

var obj = new Object();
// 添加屬性和方法
obj.age = 18;
obj.name = "foo";
obj.eat = function(){
    this.age ...            //當前對象中使用 this關鍵字
};

1b 工廠方法創建對象

function createPeople(name, age){
	var person =  new Object();
	person.name = name;
	person.age = age;
	person.sayHi = function(){
	
	};
}

2. 自定義構造函數創建

Object是系統構造函數,系統定義方式爲:

function Object(value){}

使用構造函數. 和普通函數的區別就是名字開頭是否大寫

function Person(name, age){       
    this.name = name;
    this.age =  age; 
    this.sayHi = function(){
        console.log(this.name);
    }
}
var obj = new Person('haha',18);
obj instanceof Person

創建對象經歷的事情:

  1. 在內存中申請一塊空閒的空間,創建對象
  2. this設置爲當前對象
  3. 設置對象屬性和方法
  4. 返回this對象

3. 字面量形式創建

var obj = {};
obj.name = "";
obj.sayHi = function(){
	console.log(this.name):
}

var obj = {
    name: "小明",
    age: 20;
    sayHi: function(){

    },
    eat: function(){

    }
};

8.2 獲取和設置對象的屬性、方法—— .[]

以某個變量值當做屬性名來訪問,就只能使用[]

obj.屬性名    // 不管有沒有,都能 點出來,點出來是 undefined
obj["屬性名"]  = 值

obj.plary();
obj['play']();

8.3 Json

  1. 對象:是 屬性與方法的集合
  2. 對象:也是一組無序屬性的集合,屬性的值可以是任意類型

json: 鍵/值 都用雙引號括起來

var json = {
    "name":"ab",
    "age" : "18",
    "sex": "male"
}
json.ddsdsd      // 能點出來,但是沒有的屬性,都是 undefined

json.name
json["name"]


// 遍歷對象
for(var key in obj){
    console.log(key);    // 遍歷對象的屬性
    console.log(obj[key]);    // 注意不要使用 obj.key,這就成了訪問 'key'這個屬性了
}

8.4 JS的數據類型

原始數據類型: number, string, boolean, undefined, null, object:

  • 基本類型(簡單),值類型: number, string, boolean
  • 複雜類型(引用):object
  • 空類型: undefined, null
var num1 = 66;
var num2 = 88;

function f1(num, num1) {
	num = 100;
	num1 = 100;
	num2 = 100;
	
	console.log(num1);
	console.log(num2);
	console.log(num);
}

f1(num1, num2);

console.log(num1);
console.log(num2);
console.log(num);		

9. 內置對象

JS有三種對象:內置對象、自定義對象、瀏覽器對象

在MDN上自學

9.1 Math對象——是一個對象,但不是函數對象

Math的所有屬性都是靜態屬性

Math在內部的定義方式:

Math = {}      //Math是用 {}定義的,而不是 function Math() , 所以無法new
Math.abs = function(){}    //靜態

可以new的對象是這麼定義的:

function XXX(){
}
XXX.prototype.funcname = function(){}    // 實例方法
// Math 的方法/屬性
Math.random(); // 返回[0,1)的小數
Math.PI
Math.E
Math.abs(null); ---0
Math.abs("abc"); ---NaN
  .ceil .floor
	.max   .min
	Math.pow(7,2);  -- 49
	Math.sqrt(16); -- 4

9.2 Date——創建實例對象使用

創建:

var birthday = new Date(1231252151251); // timestamp創建
var birthday = new Date(1995, 11, 17);   // 12月17日,月份從0開始
var birthday = new Date(1995, 11, 17, 3, 24, 0);
var d = new Date('2019-9-11')
var current = new Date();

var now = Date.now();  返回當前時間的timestamp(毫秒)

獲取方法:

var now = new Date();
now.getFullYear();  // 獲取年份
now.getMonth();  // 獲取月份,從0開始
now.getDate();  // 獲取日期
now.getDay();  // 獲取星期,從0開始
now.getHours();  
now.getMinutes();
now.getSeconds();  
now.getMilliseconds() 

d.valueof()   //獲得毫秒 
var d = + new Date()   //不支持H5的瀏覽器 通過這種方式獲取毫秒

封裝獲取日期時間函數:

function formatDate(d) {
  //如果date不是日期對象,返回
  if (!date instanceof Date) {
    return;
  }
  var year = d.getFullYear(),
      month = d.getMonth() + 1, 
      date = d.getDate(), 
      hour = d.getHours(), 
      minute = d.getMinutes(), 
      second = d.getSeconds();
  month = month < 10 ? '0' + month : month;
  date = date < 10 ? '0' + date : date;
  hour = hour < 10 ? '0' + hour : hour;
  minute = minute < 10 ? '0' + minute:minute;
  second = second < 10 ? '0' + second:second;
  return year + '-' + month + '-' + date + ' ' + hour + ':' + minute + ':' + second;
}

9.3 String

字符串是不可變的

  • string——字符串類型——基本類型
var str = "內容";
  • String ——字符串類型——引用類型
var str2 = new String("內容"); // 引用類型
str.length
str.concat(str2,str3..)
str.indexOf('substr')
str.match(regex)
.replace  .search  .slice   .split   .substr  .substring
.toLowerCase   .toUpperCase    .trim()
String.fromcharcode()

9.4 Array

創建方式

  1. 字面值: []
  2. 構造函數: new Array()

判斷是不是數組

Array.isArray()
ar instanceof Array
方法 描述
Array.isArray() 判斷是不是數組
arr.length 獲取長度
Array.from([1,2,3,4]) 從已有數組創建新數組
arr1.concat(arr2) 數組拼接
arr.every(callback[, thisArg]) 所有元素都要滿足條件,才返回true
arr.filter(callback[, thisArg]) 返回滿足條件元素構成的新數組
添加和刪除方法
arr.pop() 從後面刪除並且返回
arr.push(值) 在後面插入,返回數組長度
arr.shift() 刪除第一個元素並且返回
.arr.unshift(值) 在前面插入,返回長度
arr.foreach(callBack) 遍歷
arr.indexOf()
var str = arr.join('符號')
arr.map(callback)
arr.reverse()
arr.sort(callback)
arr.slice(1,3) 返回淺拷貝,第一個包括,第二個參數不包括

9.5 基本包裝類型

隱式轉換成基本包裝類型

  • 普通變量沒法調用屬性和方法
  • 本身是基本類型,但是在執行代碼的過程中,如果這種類型變量調用了屬性或者方法,那麼這種類型就不再是基本類型了, 而是基本包裝類型; 這個變量也就變成了包裝類型:

基本類型:

  • string
  • number
  • boolean
var str1 = "hello";
str1.replace("ll","HH");   // 調用了方法, 這個變量就成了基本包裝類型對象

str.indexOf()
num.toString()

Boolean的基本包裝類型

  • 如果是一個對象&&true, 結果爲true
  • 如果是 true&&對象,返回結果爲 這個對象
// boolean的基本包裝類型
var flag = new Boolean(false);
flag && true  // true , 因爲第一個是對象,對象是true
true && flag   // 返回是這個對象

基本包裝類型 vs. 類型轉換

var num2 = Number("10");  //類型轉換
var num3 = new Number("10"); //基本包裝類型

案例練習

交換2個變量的值:

var num1 = 10, num2 = 20;
var num1 = num1 + num2;
num2 = num1 - num2;
num1 = num1 - num2; 


var num1 = 10, num2 = 20;
var temp = num2;
num2 = num1;
num1 = temp;
console.log(num1,num2);


var num1 = 10, num2 = 20;
num1 = num1 ^ num2;
num2 = num1 ^ num2;
num1 = num1 ^ num2;

++、–練習

var a = 1;

alert( ++a + ++a + ++a);   //9
alert(a);    //4

閏年

let year = parseInt(prompt("請輸入年份"));

if (year % 400 == 0){
    alert("閏年");
}
else if(year % 4 == 0 && year % 100 != 0 ){
    alert("閏年");
}
else{
    alert("不是閏年");
}

畫星星、乘法口訣表

冒泡排序

var a = [4, 6, 7, 1, 3, 8, 10, 9, 5];

for (let i = 0; i < a.length - 1; i++) {

    for (let j = 0; j < a.length -i-1; j++) {

        if (a[j] > a[j + 1]) {
            let temp = a[j];
            a[j] = a[j + 1];
            a[j + 1] = temp;
        }
    }
}
alert(a);
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章