javaScript從入門到精通1.md

今日心靈雞湯:「你必定得認識到本身想往哪一個方向發展,而後必定要對準那個方向出發,要立刻。你再也浪費不起多一秒的時間了,你浪費不起。」javascript

JavaScript基礎

演示 js 的網站:
impress
naotu
codecombat
codemao
google
blockly-games
blocklycss

JavaScript介紹

創始人 Brendan Eich(布萊登.艾奇),Netscape在最初將其腳本語言命名爲LiveScript,後來Netscape在與Sun合做以後將其更名爲JavaScript。JavaScript最初受Java啓發而開始設計的,目的之一就是「看上去像Java」,所以語法上有相似之處,一些名稱和命名規範也借自Java。JavaScript與Java名稱上的近似,是當時Netscape爲了營銷考慮與Sun微系統達成協議的結果。Java和JavaScript的關係就像張雨和張雨生的關係,只是名字很像。
Java 服務器端的編程語言,JavaScript 運行在客戶端(瀏覽器)的編程語言。html

JavaScript是一種運行在***客戶端*** 的***腳本語言*** 。JavaScript的解釋器被稱爲JavaScript引擎,爲瀏覽器的一部分,普遍用於客戶端的腳本語言,最先是在HTML(標準通用標記語言下的一個應用)網頁上使用,用來給HTML網頁增長動態功能。最初的目的是爲了處理表單的驗證操做。java

javascript 是什麼?git

  • 是一門腳本語言:不須要編譯,直接運行
  • 是一門解釋性的語言:遇到一行代碼就解釋一行代碼
  • 是一門動態類型的語言:代碼只有執行到聲明的時候才知道存儲的是什麼,若是是對象,就有對象的屬性和方法;對象沒有什麼,能夠通關點語法爲對象添加屬性或方法。
  • 是一門基於對象的語言:對象具備三大特性,封裝、繼承、多態
  • 是一門弱類型的語言:強類型語言,好比定義變量,須要特定的類型 int,float,double

JavaScript如今的意義(應用場景)

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

JavaScript和HTML、CSS的區別

  1. HTML:提供網頁的結構,提供網頁中的內容\
  2. CSS: 用來美化網頁
  3. JavaScript: 能夠用來控制網頁內容,給網頁增長動態的效果

JavaScript 的組成

 

JavaScript 的組成
JavaScript 的組成

 

  1. ECMAScript - JavaScript 的核心:ECMA 歐洲計算機制造聯合會,描述了語言的基本語法和數據類型,ECMAScript 是一套標準,定義了一種語言的標準與具體實現無關
  2. BOM - 瀏覽器對象模型:一套操做瀏覽器功能的 API,經過 BOM 能夠操做瀏覽器窗口,好比:彈出框、控制瀏覽器跳轉、獲取分辨率等
  3. DOM - 文檔對象模型:一套操做頁面元素的 API,DOM 能夠把 HTML 看作是文檔樹,經過 DOM 提供的 API 能夠對樹上的節點進行操做

JavaScript的書寫位置

  • 寫在行內:<input type="button" value="按鈕" onclick="alert('Hello World')" />
  • 寫在script標籤中:<head><script>alert('Hello World!');</script></head>
  • 寫在外部js文件中,在頁面引入:<script src="main.js"></script>

變量

變量是計算機內存中存儲數據的標識符,根據變量名稱能夠獲取到內存中存儲的數據。使用變量能夠方便的獲取或者修改內存中的數據。程序員

  1. var聲明變量:var age;
  2. 變量的賦值:var age; age = 18;
  3. 同時聲明多個變量:var age, name, sex; age = 10; name = 'cjr';
  4. 同時聲明多個變量並賦值:var age = 10, name = 'cjr';
  5. 交換兩個變量的值:var a,b;a=10;b=20;
    • 方法一:var temp; temp = b; b=a; a=temp;
    • 方法二:a = a + b; b = a - b; a = a - b;
    • 方法三(異或):a = a ^ b; b = a ^ b; a = a ^ b;

變量的命名規則和規範

  • 規則 - 必須遵照的,不遵照會報錯
    • 由字母、數字、下劃線、$符號組成,不能以數字開頭
    • 不能是關鍵字和保留字,例如:for、while
    • 區分大小寫
  • 規範 - 建議遵照的,不遵照不會報錯
    • 變量名必須有意義
    • 遵照駝峯命名法。首字母小寫,後面單詞的首字母須要大寫。例如:userName、userPassword

註釋

  1. 單行註釋:用來描述下面一個或多行代碼的做用
// 這是一個變量
var name = 'hm';
  1. 多行註釋:用來註釋多條代碼
/* var age = 18; var name = 'zs'; console.log(name, age); */     
/** 還有註釋是這個樣子的,通常用來註釋代碼的做用 @type {Console} */

數據類型

原始數據類型:number,string,boolean,null,undefined,Symbol (ECMAScript 6 新定義),objectgithub

Number 類型

  • 數值字面量:數值的固定值的表示法,20 10215 20.36
  • 進制:十進制、十六進制(0xFA)、八進制(024;var i=20;i.toString(8);// 24)
  • 浮點數:
    • var n = 5e-324; // 科學計數法 5乘以10的-324次方
    • 浮點數值的最高精度是 17 位小數,但在進行算術計算時其精確度遠遠不如整數
    • var result = 0.1 + 0.2; // 結果不是 0.3,而是:0.30000000000000004
    • 不要判斷兩個浮點數是否相等
  • 數值範圍
    • 最小值:Number.MIN_VALUE,這個值爲: 5e-324
    • 最大值:Number.MAX_VALUE,這個值爲: 1.7976931348623157e+308
    • 無窮大:Infinity
    • 無窮小:-Infinity
  • 數值判斷
    • NaN:not a number ,NaN 與任何值都不相等,包括他自己
    • isNaN: is not a number,不要用 NaN 驗證是否是 ==NaN,用 isNaN()

String 類型

  • 字符串字面量:'abc' "abc"
  • 轉義符

 

轉義符
轉義符

 

  • 字符串長度:length屬性用來獲取字符串的長度
var str = 'Hello World';  console.log(str.length);
  • 字符串拼接,使用 + 鏈接
    console.log(11 + 11);
    console.log('hello' + ' world');
    console.log('11' + 11);
    console.log('male:' + true);
    • 兩邊只要有一個是字符串,那麼 「+」 就是字符串拼接功能
    • 兩邊若是都是數字,那麼就是算術功能。

Boolean 類型

  • Boolean字面量: true和false,區分大小寫
  • 計算機內部存儲:true爲1,false爲0

Undefined 和 Null

  1. undefined 表示一個聲明瞭沒有賦值的變量,變量只聲明的時候值默認是 undefined;函數沒有明確返回值,若是接收了,結果也是 undefined。
    • undefined 的變量和一個數字相加,結果是 NaN
  2. nul l表示一個空,變量的值若是想爲 null,必須手動設置

複雜數據類型 Object

獲取變量的類型

  • typeof 函數能夠獲取變量的數據類型
var age = 18;   console.log(typeof age);  // 'number'

字面量

在源代碼中一個固定值的表示法。
數值字面量:8, 9, 10;字符串字面量:"Hello World!" ;布爾字面量:true,false。web

數據類型轉換

字符串的顏色是黑色的,數值類型是藍色的,布爾類型也是藍色的,undefined和null是灰色的。express

轉換成數值類型

  • parseInt()
var num1 = parseInt("12.3abc");  // 返回12,若是第一個字符是數字會解析知道遇到非數字結束
var num2 = parseInt("abc123");   // 返回NaN,若是第一個字符不是數字或者符號就返回NaN
  • parseFloat()
console.log(parseFloat("12.045fsd"));  //12.045
console.log(parseFloat("dasd41531"));  //NaN
// parseFloat會解析第一個. 遇到第二個.或者非數字結束。若是解析的內容裏只有整數,解析成整數
  • Number()
console.log(Number("1521dasd"));  //NaN
console.log(Number("dasd123"));  //NaN
// Number()能夠把任意值轉換成數值,若是要轉換的字符串中有一個不是數值的字符,返回NaN
  • 隱式轉換
console.log("11" * 2); //22
console.log("22" - 10); //12
console.log("12" + 10); //1210字符串
var str = '500'; console.log(-str); //-500 console.log(+str); // 500

轉換成字符串類型

  • toString()
var num = 5;
console.log(num.toString());  // 5 字符串
console.log(null.toString());  // 報錯
  • String()
console.log(String(null));   //null
console.log(String(undefined));  //undefined
  • String() 函數存在的意義:有些值沒有 toString(),這個時候可使用String()。好比:undefined和null
  • 拼接字符串方式
    • num + "",當 + 兩邊一個操做數是字符串類型,一個操做數是其它類型的時候,會先把其它類型轉換成字符串再進行字符串拼接,返回字符串

轉換成布爾類型

  • Boolean()
console.log(Boolean(-4151));   //true
console.log(Boolean("dsada"));   //true
console.log(Boolean(undefined));   // false
console.log(Boolean(null));   //false

操做符

運算符 operator ,表達式 組成: 操做數和操做符編程

算數運算符

+(加)、-(減)、*(乘)、/(除)、%(取餘)

var a = 20;   var b = 3;
console.log(a - b); // 17
console.log(a + b); // 23
console.log(a * b); //60
console.log(a / b); //6.666666666666667
console.log(parseInt(a/b)); // 6
console.log(a % b); // 2

邏輯運算符(布爾運算符)

&&(與) :兩個操做數同時爲true,結果爲true,不然都是false
|| (或) :兩個操做數有一個爲true,結果爲true,不然爲false
! (非) : 取反

console.log(!1); // false
console.log(!0); // true
console.log(true || false); // true
console.log(1 && 0); // 0

關係運算符(比較運算符)

<>>=<===!==== (嚴格等於) 、 !==(嚴格不等於)

// ==與===的區別:==只進行值得比較,===類型和值同時相等,則相等
console.log(10 == "10");   // true
console.log(10 === "10");   // false

賦值運算符

=+=-=*=/=%=

var a = 10;
console.log(a *= a);  // 100
console.log(a /= a);  // 1
console.log(a %= a); // 0

一元運算符

一元運算符:只有一個操做數的運算符;5 + 6 兩個操做數的運算符 二元運算符.
++ :自身加1;--: 自身減1

  • 前置 ++:
var num1 = 5;
++num1;  // 6
var num2 = 6;
console.log(num1 + ++num2);  // 13
  • 後置 ++
var num1 = 5;
num1++;  // 6
var num2 = 6;
console.log(num1 + num2++);  // 12
  • 總結
    • 前置++:先加1,後參與運算
    • 後置++:先參與運算,後加1
    • 前置-- :先減1,後參與運算
    • 後置-- :先參與運算,後減1

運算符的優先級

優先級從高到底

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

流程控制

一個表達式能夠產生一個值,有多是運算、函數調用、有多是字面量。表達式能夠放在任何須要值的地方。語句能夠理解爲一個行爲,循環語句和判斷語句就是典型的語句。一個程序有不少個語句組成,通常狀況下;分割一個一個的語句。程序有三種流程基本結構。

順序結構

默認的,從上到下執行的代碼就是順序結構。

分支結構

根據不一樣的狀況,執行對應代碼。

循環結構

循環結構:重複作一件事情。

分支結構

if語句

// 語法結構
if (/* 條件表達式 */) {
  // 執行語句
}

if (/* 條件表達式 */){
  // 成立執行語句
} else {
  // 不然執行語句
}

if (/* 條件1 */){
  // 成立執行語句
} else if (/* 條件2 */){
  // 成立執行語句
} else if (/* 條件3 */){
  // 成立執行語句
} else {
  // 最後默認執行語句
}

三元運算符

表達式1 ? 表達式2 : 表達式3 // 是對if……else語句的一種簡化寫法
// 表達式1成立,執行表達式2;不然,執行表達式3。
var age = parseInt(prompt("請輸入您的年齡:")); // prompt 彈出輸入框

switch語句

switch (expression) {
  case 常量1:    語句;    break;
  case 常量2:    語句;    break;
  case 常量3:    語句;    break;
...
  case 常量n:    語句;    break;
  default:    語句;    break;
}

break 能夠省略,若是省略,代碼會繼續執行下一個 case。
switch 語句在比較值時使用的是全等操做符, 所以不會發生類型轉換(例如,字符串'10' 不等於數值 10)

var num1 = "10";
switch(num1){
  case 10:    console.log("執行的10");    break;
  case "10":    console.log("執行的\"10\"");    break;
} // 最後執行的是 "case "10"",嚴格的相等

布爾類型的隱式轉換

流程控制語句會把後面的值隱式轉換成布爾類型

// 轉換爲true 非空字符串 非0數字 true 任何對象
// 轉換成false 空字符串 0 false null undefined
var a = !!'123';  // true

循環結構

在javascript中,循環語句有三種,while、do..while、for循環。

while語句

// 當循環條件爲true時,執行循環體,
// 當循環條件爲false時,結束循環。
// 計算1-100之間全部數的和
var i = 1;    // 初始化變量,用做循環條件
var sum = 0;  // 存儲總和
while (i <= 100) {   // 判斷條件
  // 循環體
  sum += i;    // 自增
  i++;    // 結束條件
}
console.log(sum);

do...while語句

do..while循環和while循環很是像,兩者常常能夠相互替代,可是do..while的特色是無論條件成不成立,都會執行一次。

var i = 1;   // 初始化變量
var sum = 0;
do {
  sum += i;   // 循環體
  i++;   // 自增
} while (i <= 100);   // 循環條件

for語句

while和do...while通常用來解決沒法確認次數的循環。for循環通常在循環次數肯定的時候比較方便.

// for循環的表達式之間用的是;號分隔的,千萬不要寫成,
for (初始化表達式1; 判斷表達式2; 自增表達式3) {
  // 循環體4

var num1 = 1;    var num2 = 1;    var num3 = 0;
for(var i=3; i<=12;i++){
  num3 = num1 + num2;
  num1 = num2;
  num2 = num3;
} // 斐波拉切數列: 1,1,2,3,5,8,13,21,34,55
    console.log(num3);

continue和break

break:當即跳出整個循環,即循環結束,開始執行循環後面的內容(直接跳到大括號)
continue:當即跳出當前循環,繼續下一次循環(跳到i++的地方)

調試

  • 過去調試JavaScript的方式:alert() console.log()
  • 斷點調試:斷點調試是指本身在程序的某一行設置一個斷點,調試時,程序運行到這一行就會停住,而後你能夠一步一步往下調試,調試過程當中能夠看各個變量當前的值,出錯的話,調試到出錯的代碼行即顯示錯誤,停下。
    • 調試步驟:瀏覽器中按F12-->sources-->找到須要調試的文件-->在程序的某一行設置斷點
    • 調試中的相關操做:
      • Watch: 監視,經過watch能夠監視變量的值的變化,很是的經常使用。
      • F10: 程序單步執行,讓程序一行一行的執行,這個時候,觀察watch中變量的值的變化。
      • F8:跳到下一個斷點處,若是後面沒有斷點了,則程序執行結束。
  • 注意點:監視變量,不要監視表達式,由於監視了表達式,那麼這個表達式也會執行。

數組

上面學習的數據類型,只能存儲一個值(好比:Number/String。想存儲多個數據,就用到數組。
所謂數組,就是將多個元素(一般是同一類型)按必定順序排列放到一個集合中,那麼這個集合咱們就稱之爲數組。

數組的定義

數組是一個有序的列表,能夠在數組中存聽任意的數據,而且數組的長度能夠動態的調整。

  1. 經過數組字面量建立數組:
var arr1 = [];   // 建立一個空數組
var arr2 = [1, 3, 4];    // 建立一個包含3個數值的數組,多個數組項以逗號隔開
var arr3 = ['a', 'c'];    // 建立一個包含2個字符串的數組
console.log(arr3.length);   // 能夠經過數組的length屬性獲取數組的長度
arr3.length = 0;   // 能夠設置length屬性改變數組中元素的個數
var arr4 = [[0,1,2],[3,4,5]];   // 建立多維數組
  1. 經過構造函數建立數組:
var array = new Array();  // 定義一個空數組 []
var array = new Array(5);  // 定義長度爲 5 的空數組,(5) [empty × 5]
var array = new Array(10,20,30,"sad");  // (4) [10, 20, 30, "sad"]

獲取數組元素

  • 數組的取值
// 格式:數組名[下標] 下標又稱索引
// 功能:獲取數組對應下標的那個值,若是下標不存在,則返回 undefined。
var arr = ['red',, 'green', 'blue'];
arr[0];	  // red
arr[3];   // 這個數組的最大下標爲2,所以返回undefined
  • 遍歷數組:遍歷:遍佈全部,對數組的每個元素都訪問一次就叫遍歷。
for(var i = 0; i < arr.length; i++) {
    console.log(arr[i]);    // 數組遍歷的固定結構
}

數組中新增元素

數組的賦值

// 格式:數組名[下標/索引] = 值;
// 若是下標有對應的值,會把原來的值覆蓋,若是下標不存在,會給數組新增一個元素。
var arr = ["red", "green", "blue"];
arr[0] = "yellow";   // 把red替換成了yellow,arr = ["yellow", "green", "blue"];
arr[3] = "pink";   // 數組增長一個pink的值,["yellow", "green", "blue","pink"];
// 冒泡排序
var array = [10, 20, 30, 4, 9, 50];
for (var i = 0; i < array.length - 1; i++) {     // 比較的輪數
  for (var j = 0; j < array.length - 1 - i; j++) {   // 每輪比較的次數
    if (array[j] > array[j + 1]) {    // 從小到大排序;從大到小排序就是 <
      var temp = array[j];
      array[j] = array[j + 1];
      array[j + 1] = temp;
    }
  }
}
console.log(array);   // [4,9,10,20,30,50]

函數

把一段相對獨立的具備特定功能的代碼塊封裝起來,造成一個獨立實體,就是函數,起個名字(函數名),在後續開發中能夠反覆調用。函數的做用就是封裝一段代碼,未來能夠重複使用。

  • 函數聲明:function 函數名(){ // 函數體 }
  • 函數表達式:var fn = function() { // 函數體 }
  • 特色:函數聲明的時候,函數體並不會執行,只要當函數被調用的時候纔會執行。函數通常都用來幹一件事情,需用使用動詞+名詞命名,表示作一件事情 tellStory sayHello等。

函數的調用

  • 調用函數的語法:函數名();
  • 特色:函數體只有在調用的時候纔會執行,調用須要()進行調用。能夠調用屢次(重複使用)
function getSum() {   // 求1-100之間全部數的和
  var sum = 0;
  for (var  i = 0; i < 100; i++) {
    sum += i;
  }
  console.log(sum);
}
getSum();   // 調用

函數的參數

// 函數內部是一個封閉的環境,能夠經過參數的方式,把外部的值傳遞給函數內部
// 帶參數的函數聲明
function 函數名(形參1, 形參2, 形參...){
  // 函數體
}
// 帶參數的函數調用
函數名(實參1, 實參2, 實參3);

形參和實參:

  • 形式參數:在聲明一個函數的時候,爲了函數的功能更加靈活,有些值是固定不了的,對於這些固定不了的值。咱們能夠給函數設置參數。這個參數沒有具體的值,僅僅起到一個佔位置的做用,咱們一般稱之爲形式參數,也叫形參。
  • 實際參數:若是函數在聲明時,設置了形參,那麼在函數調用的時候就須要傳入對應的參數,咱們把傳入的參數叫作實際參數,也叫實參。
var x = 5, y = 6;
fn(x,y); 
function fn(a, b) {
  console.log(a + b);
}
//x,y實參,有具體的值。函數執行的時候會把x,y複製一份給函數內部的a和b,函數內部的值是複製的新值,沒法修改外部的x,y

函數的返回值

當函數執行完的時候,並非全部時候都要把結果打印。咱們指望函數給我一些反饋(好比計算的結果返回進行後續的運算),這個時候可讓函數返回一些東西。也就是返回值。函數經過return返回一個返回值

//聲明一個帶返回值的函數
function 函數名(形參1, 形參2, 形參...){
  //函數體
  return 返回值;
}
//能夠經過變量來接收這個返回值
var 變量 = 函數名(實參1, 實參2, 實參3);

函數的調用結果就是返回值,所以咱們能夠直接對函數調用結果進行操做。

  • 若是函數沒有顯示的使用 return語句 ,那麼函數有默認的返回值:undefined
  • 若是函數使用 return語句,那麼跟再return後面的值,就成了函數的返回值
  • 若是函數使用 return語句,可是return後面沒有任何值,那麼函數的返回值也是:undefined
  • 函數使用return語句後,這個函數會在執行完 return 語句以後中止並當即退出,也就是說return後面的全部其餘代碼都不會再執行。

arguments 的使用

JavaScript中,arguments對象是比較特別的一個對象,其實是當前函數的一個內置屬性。也就是說全部函數都內置了一個arguments對象,arguments對象中存儲了傳遞的全部的實參。arguments是一個僞數組,所以及能夠進行遍歷

function f(){
  //Arguments [Array(6), callee: ƒ, Symbol(Symbol.iterator): ƒ]
  console.log(arguments); 
  console.log(arguments[0]); // (6) [1, 85, 8, 3, 4, 0]
  console.log(arguments[1]); // undefined
  console.log(arguments.length); // 1
}
f([1,85,8,3,4,0]);

函數其它

  1. 匿名函數
    匿名函數:沒有名字的函數。
    匿名函數自調用匿名函數如何使用:將匿名函數賦值給一個變量,這樣就能夠經過變量進行調用。
var f1 = function (){    
   // 函數體 
};   // 要有逗號結尾
f1();    // 調用函數

關於自執行函數(匿名函數自調用)的做用:防止全局變量污染。

  1. 自調用函數
    匿名函數不能經過直接調用來執行,所以能夠經過匿名函數的自調用的方式來執行
(function () {
  alert(123);
})();   // 彈出提示框,123
  1. 函數是一種數據類型
function fn() {}
console.log(typeof fn);   // function
  • 函數做爲參數:由於函數也是一種類型,能夠把函數做爲兩一個函數的參數,在兩一個函數中調用
  • 函數作爲返回值:由於函數是一種類型,因此能夠把函數能夠做爲返回值從函數內部返回。
function fn(b) {
  var a = 10;
  return function () {   alert(a+b);   }
}
fn(15)();   // 彈出對話框,顯示 25

做用域

做用域:變量能夠起做用的範圍

全局變量和局部變量

  • 全局變量:在任何地方均可以訪問到的變量就是全局變量,對應全局做用域
  • 局部變量:只在固定的代碼片斷內可訪問到的變量,最多見的例如函數內部。對應局部做用域(函數做用域)
    • 不使用var聲明的變量是全局變量,不推薦使用。
    • 變量退出做用域以後會銷燬,全局變量關閉網頁或瀏覽器纔會銷燬

塊級做用域

任何一對花括號({和})中的語句集都屬於一個塊,在這之中定義的全部變量在代碼塊外都是不可見的,咱們稱之爲塊級做用域。
在 ES5 以前沒有塊級做用域的的概念,只有函數做用域,現階段能夠認爲JavaScript沒有塊級做用域

詞法做用域

變量的做用域是在定義時決定而不是執行時決定,也就是說詞法做用域取決於源碼,經過靜態分析就能肯定,所以詞法做用域也叫作靜態做用域。

在 js 中詞法做用域規則:

  • 函數容許訪問函數外的數據.
  • 整個代碼結構中只有函數能夠限定做用域.
  • 做用域規則首先使用提高規則分析
  • 若是當前做用規則中有名字了, 就不考慮外面的名字
var num = 123;
function foo() {
  console.log( num ); // 123
}
foo();

if ( false ) {
  var num = 123;
}
console.log( num ); // undefiend,若是 false 改成 true,則爲123

function f2(){
  num = 10;
}
// f2();
console.log(num);
// 調用了 f2() 就是輸出 10,至關於開闢了空間;沒有調用就報錯

做用域鏈

只有函數能夠製造做用域結構, 那麼只要是代碼,就至少有一個做用域, 即全局做用域。凡是代碼中有函數,那麼這個函數就構成另外一個做用域。若是函數中還有函數,那麼在這個做用域中就又能夠誕生一個做用域。
將這樣的全部的做用域列出來,能夠有一個結構: 函數內指向函數外的鏈式結構。就稱做做用域鏈。

// 案例1:
function f1() {
  function f2() {
  }
}

var num = 456;
function f3() {
  function f4() {    
  }
}

 

做用域鏈1
做用域鏈1

 

// 案例2
function f1() {
  var num = 123;
  function f2() {
    console.log( num );
  }
  f2();
}
var num = 456;
f1();

 

做用域鏈2
做用域鏈2

 

預解析

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

  • 預解析過程:
    • 把變量的聲明提高到當前做用域的最前面,只會提高聲明,不會提高賦值。
    • 把函數的聲明提高到當前做用域的最前面,只會提高聲明,不會提高調用。
    • 先提高var,再提高function
var a = 25;
console.log(a); // 25
function a() {
    console.log(a); // undefine
    var a = 10;
}
 a(); // a is not a function

var a;
console.log(a);  // ƒ a() { console.log('aaaaa'); }
function a() {
    console.log('aaaaa');
 }
 a();   // aaaaa
 var a = 1;
console.log(a); // 1

全局解析規則

函數內部解析規則

  • 變量提高:定義變量的時候,變量的聲明會被提高到做用域的最上面,變量的賦值不會提高。
  • 函數提高:JavaScript解析器首先會把當前做用域的函數聲明提早到整個做用域的最前面
// 一、-----------------------------------
var num = 10;
fun();
function fun() {
  console.log(num);  // undefined
  var num = 20;
}
//二、-----------------------------------
var a = 18;
f1();
function f1() {
  var b = 9;
  console.log(a);  // undefined
  console.log(b);  // 9
  var a = '123';
}
// 三、-----------------------------------
f1();
console.log(c);  // 9
console.log(b);  // 9
console.log(a);  // 報錯
function f1() {
  var a = b = c = 9;  // 等價於 var a; a=9; b=9; c=9;
  console.log(a);  // 9
  console.log(b);  // 9
  console.log(c);  // 9
}

對象

現實生活中:萬物皆對象,對象是一個具體的事物,一個具體的事物就會有行爲和特徵。
JavaScript中的對象:

  • JavaScript中的對象其實就是生活中對象的一個抽象
  • JavaScript的對象是無序屬性的集合。
    • 其屬性能夠包含基本值、對象或函數。對象就是一組沒有順序的值。咱們能夠把JavaScript中的對象想象成鍵值對,其中值能夠是數據和函數。
    • 對象的行爲和特徵:
      • 特徵---屬性,事物的特徵在對象中用屬性來表示。
      • 行爲---方法,事物的行爲在對象中用方法來表示。

對象建立方式

  1. 對象字面量
var o = {
  name: 'cjr',
  age: 18,
  sex: male,
  sayHi: function () {
    console.log(this.name);
  }
};
  1. new Object()建立對象
var person = new Object();    // 也可使用 var person = {}; 相似數組 var a=[];
person.name = 'cjr';
person.age = 25;
person.job = 'IT';
person.sayHi = function(){
  console.log('Hello,everyBody');
}
  1. 工廠函數建立對象
function Dog(name,age){
  var dog = new Object();
  dog.name = name;
  dog.age = age;
  dog.bark = function(){
    console.log("嗚嗚嗚嗚嗚~~~");
  };
  return dog;
}
var ahuang = Dog("阿黃", 3);
console.log(ahuang);  // {name: "阿黃", age: 3, bark: ƒ}
ahuang.bark();   // 嗚嗚嗚嗚嗚~~~
  1. 自定義構造函數
function Person(name,age,job){
  this.name = name;
  this.age = age;
  this.job = job;
  this.sayHi = function(){
    console.log('Hello,everyBody');
  }
}
var p1 = new Person('張三', 22, 'actor');
p1.sayHi(); // Hello,everyBody
console.log(p1 instanceof Person); // true,p1 是否是 Person 對象
  • 屬性和方法
    • 若是一個變量屬於一個對象全部,那麼該變量就能夠稱之爲該對象的一個屬性,屬性通常是名詞,用來描述事物的特徵。
    • 若是一個函數屬於一個對象全部,那麼該函數就能夠稱之爲該對象的一個方法,方法是動詞,描述事物的行爲和功能

new 關鍵字

構造函數 ,是一種特殊的函數。主要用來在建立對象時初始化對象, 即爲對象成員變量賦初始值,總與new運算符一塊兒使用在建立對象的語句中。

  1. 構造函數用於建立一類對象,首字母要大寫。如,Person
  2. 構造函數要和 new 一塊兒使用纔有意義。如 var zhangsan = new Person();
  3. new在執行時會作四件事情:
    1. new會在內存中開闢空間,存儲建立一個新的空對象
    2. new 會讓 this 指向這個新的對象
    3. 執行構造函數 目的:給這個新對象加屬性和方法
    4. new 會返回這個新對象

this 詳解

JavaScript中的this指向問題:

1. 函數在定義的時候 this 是不肯定的,只有在調用的時候才能夠肯定
2. 通常函數直接執行,內部 this 指向全局 window
3. 函數做爲一個對象的方法,被該對象所調用,那麼 this 指向的是該對象
4. 構造函數中的 this 實際上是一個隱式對象,相似一個初始化的模型,全部方法和屬性都掛載到了這個隱式對象身上,後續經過 new 關鍵字來調用,從而實現實例化

對象的使用

  1. 遍歷對象的屬性:經過for..in語法能夠遍歷一個對象
var obj = {};
for (var i = 0; i < 10; i++) {
  obj[i] = i * 2;
}   // obj[key] 直接調用,兩種方式均可以,可是沒有屬性的時候用這個
for(var key in obj) {
  console.log(key + "==" + obj[key]);  // key 是 obj 的鍵
}   // obj.key 若是有 key 就是調用,沒有就是建立
  1. 刪除對象的屬性
function fun() { 
  this.name = 'bob';
}
var obj = new fun(); 
console.log(obj.name);   // bob 
delete obj.name;
console.log(obj.name);   // undefined

簡單類型和複雜類型的區別

  • 原始數據類型:Number,String,Boolean,Null,Undefined,Object
    • 基本類型又叫作值類型:number,string,boolean ;簡單數據類型,基本數據類型,在存儲時,變量中存儲的是值自己,所以叫作值類型。棧 中存儲
    • 複雜類型又叫作引用類型:object ;複雜數據類型,在存儲是,變量中存儲的僅僅是地址(引用),所以叫作引用數據類型。棧和堆 中存儲
    • 空類型:undefined,null
  • 堆和棧
    • 棧(操做系統):由操做系統自動分配釋放 ,存放函數的參數值,局部變量的值等。其操做方式相似於數據結構中的棧;
    • 堆(操做系統): 存儲複雜類型(對象),通常由程序員分配釋放, 若程序員不釋放,由垃圾回收機制回收,分配方式卻是相似於鏈表。
    • 注意:JavaScript中沒有堆和棧的概念,此處用堆和棧來說解,目的方便理解和方便之後的學習。

 

基本類型在內存中的存儲
基本類型在內存中的存儲

 

 

複雜類型在內存中的存儲
複雜類型在內存中的存儲

 

 

基本類型做爲函數的參數
基本類型做爲函數的參數

 

 

複雜類型做爲函數的參數
複雜類型做爲函數的參數

 

function Person(name,age,salary) {
  this.name = name;
  this.age = age;
  this.salary = salary;
}
function f1(person) {
  person.name = "cccc";
  person = new Person("aaaa",18,10);   // 此時 person 存儲的不是 p 的地址了,是新的地址
}
var p = new Person("bbbb",18,1000);
console.log(p.name);  // bbbb
f1(p);
console.log(p.name);  // cccc

JSON

JSON(JavaScript Object Notation, JS 對象簡譜) 是一種輕量級的數據交換格式。它基於 ECMAScript (歐洲計算機協會制定的js規範)的一個子集,採用徹底獨立於編程語言的文本格式來存儲和表示數據。簡潔和清晰的層次結構使得 JSON 成爲理想的數據交換語言。 易於人閱讀和編寫,同時也易於機器解析和生成,並有效地提高網絡傳輸效率。

JSON 語法規則

任何支持的類型均可以經過 JSON 來表示,例如字符串、數字、對象、數組等。可是對象和數組是比較特殊且經常使用的兩種類型:

  • 對象表示爲鍵值對,花括號保存對象
  • 數據由逗號分隔,方括號保存數組

JSON 鍵/值對
JSON 鍵值對是用來保存 JS 對象的一種方式,和 JS 對象的寫法也大同小異,鍵/值對組合中的鍵名寫在前面並用雙引號 "" 包裹,使用冒號 : 分隔,而後緊接着值:
{"firstName": "Json"}
等價於這條 JavaScript 語句:{firstName : "Json"}

JSON 與 JS 對象的關係

JSON 是 JS 對象的字符串表示法,它使用文本表示一個 JS 對象的信息,本質是一個字符串。

var obj = {a: 'Hello', b: 'World'}; //這是一個對象,注意鍵名也是可使用引號包裹的
var json = '{"a": "Hello", "b": "World"}'; //這是一個 JSON 字符串,本質是一個字符串

JSON 和 JS 對象互轉:

  • 對象轉換爲 JSON 字符串,使用 JSON.stringify() 方法:
    • var json = JSON.stringify({a: 'Hello', b: 'World'}); //結果是 '{"a": "Hello", "b": "World"}'
  • 從 JSON 轉換爲對象,使用 JSON.parse() 方法:
    • var obj = JSON.parse('{"a": "Hello", "b": "World"}'); //結果是 {a: 'Hello', b: 'World'}

內置對象

JavaScript中的對象分爲3種:內置對象、瀏覽器對象(web api)、自定義對象
JavaScript 提供多個內置對象:Math/Array/Number/String/Boolean...
對象只是帶有屬性方法的特殊數據類型。
能夠經過 MDN 查看。

Math 對象

Math對象不是構造函數,它具備數學常數和函數的屬性和方法,都是以靜態成員的方式提供。跟數學相關的運算來找Math中的成員(求絕對值,取整)

console.log(Math.PI); // 3.141592653589793
console.log(Math.abs(null)); // 0
console.log(Math.abs(undefined)); // NaN
console.log(Math.ceil(10.33);) // 11
Math.floor(10.9999);  // 10
Math.max(10,20,3,50,-12); // 50
Math.min(10,-5,60,20); // -5
Math.pow(2,3);  // 8
Math.fround(1.36498);   // 1.3649799823760986
Math.random();  // 僞隨機數在範圍 [0,1),包括0,可是不包括1。
Math.round(20.5514654);  // 21
Math.sign(-256);   // -1
Math.sqrt(9);  // 3

Date 對象

Date 對象基於1970年1月1日(世界標準時間)起的毫秒數。

var utcDate1 = new Date(Date.UTC(96, 1, 2, 3, 4, 5));
console.log(utcDate1.toUTCString());  // Fri, 02 Feb 1996 03:04:05 GMT
Date.now();  // 1547013241828
Date.parse('01 Jan 1970 00:00:00 GMT');  // 0
var birthday = new Date('August 19, 1975 23:15:30');
birthday.getDate(); // 19
birthday.getDay(); // 2 一週的第幾天,0 表示星期天。
birthday.getFullYear(); // 1975
birthday.getHours();  // 23
birthday.getMinutes();  // 15
birthday.getMonth();  // 7返回指定的日期對象的月份,0表示一月
birthday.getSeconds();  // 30
birthday.getTime();  // 177693330000,返回一個時間的格林威治時間數值。
birthday.toDateString();  // "Tue Aug 19 1975"
birthday.toString(); // "Tue Aug 19 1975 23:15:30 GMT+0800 (中國標準時間)"
birthday.toJSON(); // "1975-08-19T15:15:30.000Z"
birthday.toLocaleDateString();  // "1975/8/19"

String 對象

String 全局對象是一個用於字符串或一個字符序列的構造函數。

var x = "Mozilla";
x.length;  // 7
x.charAt(1);  // o
x.charCodeAt(1);  // 111,字符的 UTF-16 代碼單元值的數字
x.codePointAt(1);  // 111 返回 一個 Unicode 編碼點值的非負整數。
x.concat(",Hello ","world!");  // "Mozilla,Hello world!"
x.endsWith("lla");  // true
x.indexOf("o");  // 1
x.lastIndexOf("l");  // 5 返回指定值在字符串中最後出現的位置,0開始\
x.match(/[a-lA-L]/gi);  // (4) ["i", "l", "l", "a"]
x.search(/[a-lA-L]/gi);  // 3 第一次出現的索引
x.repeat(3);  // "MozillaMozillaMozilla"
x.replace(/[a-lA-L]/gi, "???");  // "Moz????????????"
x.slice(2,4);  // "zi"
x.split("");  // (7) ["M", "o", "z", "i", "l", "l", "a"]
x.startsWith("M");  // true
x.substring(3,0);  // "Moz"
x.toLocaleLowerCase();  // "mozilla"
x.toLocaleUpperCase();  // "MOZILLA"
x.toLowerCase();  // "mozilla"
x.toUpperCase();  // "MOZILLA"
var y = " w h a t ";
y.trim();   // "w h a t"
y.trimLeft();  // "w h a t "
y.trimRight();   // " w h a t"
var z = new String("mozilla");   typeof z;  // "object"
typeof z.indexOf();   // "number"
z.indexOf("i");  // 3
"aacsac".localeCompare("bbdasd");  // -1
"bbasdas".localeCompare("aacvadsfa");  // 1
String.fromCharCode(0x404); // "Є" 返回Unicode值序列建立的字符串。
String.fromCodePoint(0x404);  // "\u0404" 使用 Unicode 編碼建立的字符串。

Array 對象

JavaScript 的 Array 對象是用於構造數組的全局對象,數組相似與列表的高階對象。

var fruits = ['Apple', 'Banana'];
fruits.length;  // 2
Array.from(fruits);  // (2) ["Apple", "Banana"]
Array.isArray(fruits);   // true
Array.of(7);   // [7]
Array(7);   // (7) [empty × 7]
fruits.concat("Strawberry");  // (3) ["Apple", "Banana", "Strawberry"]
var array1 = [1, 2, 3, 4];
console.log(array1.fill(0, 2, 4));  // [1, 2, 0, 0]
var filtered = [12, 5, 8, 130, 44].filter(function (element) {
  return element >= 10;
});   // (3) [12, 130, 44]
fruits.find(function (e){ return e == "Banana";});  // "Banana"
fruits.findIndex(function (e){ return e == "Banana";});  // 1
fruits.forEach(function(e){ console.log(e);});  // Apple Banana
fruits.includes("Banana");   // true
fruits.indexOf("Banana");   // 1
fruits.keys();    // Array Iterator {}
for(let key of fruits.keys()){ console.log(key);};   // 0 1
fruits.map(function(e) { return e + "Pen";});    // (2) ["ApplePen", "BananaPen"]
fruits.pop();   // "Banana"
fruits.push("Banana","Strawberry");   // (3) ["Apple", "Banana", "Strawberry"]
[0, 1, 2, 3, 4].reduce(function(accumulator, currentValue, currentIndex, array){
  return accumulator + currentValue;
});    // 0 + 1 + 2 + 3 + 4 10
fruits.reverse();    // (3) ["Strawberry", "Banana", "Apple"]
fruits.shift();   // "Strawberry"
fruits.unshift("Strawberry");   // 3 (3) ["Strawberry", "Banana", "Apple"]
fruits.slice(0,2);   // (2) ["Strawberry", "Banana"]
fruits.sort(function (a,b){ return a>b;});   // (3) ["Apple", "Banana", "Strawberry"]
var months = ['Jan', 'March', 'April', 'June'];
months.splice(1, 0, 'Feb');   // ['Jan', 'Feb', 'March', 'April', 'June']
months.splice(4, 1, 'May');   // ['Jan', 'Feb', 'March', 'April', 'May']
相關文章
相關標籤/搜索