什麼是Javascript?
Javascript能作什麼?
瀏覽器中的Javascript能夠作什麼?
- 操做DOM(增刪改查)
- AJAX/跨域
- BOM
- ECMAScript
瀏覽器中的Javascript不能作什麼?
編程語言的能力取決於?
- 語言自己只是提供了定義變量、定義函數、定義類型、流程控制、循環結構之類的操做
- 取決於運行該語言的平臺(環境)
- 對於js來講,常常說的JS實際是ES,大部分能力都是由瀏覽器的執行殷勤決定
- BOM和DOM能夠說是瀏覽器開放出來的接口
- 好比:Cordova中提供JS調用攝像頭,操做本地文件的API
- Java既是語言也是平臺
- Java運行在Java虛擬機(跨操做系統)
- PHP是語言也是平臺
- C#語言,平臺:.net framework
- C#能夠運行在MONO這樣的平臺
- 由於有人須要將C#運行在Linux平臺,因此出現了MONO
Javascript只能夠運行在瀏覽器中嗎?
- 不是
- 能運行在哪裏,取決於這個環境有沒有特定的平臺
node是什麼?(Ryan Dahl)
- Node是javascript運行於服務端的運行環境
- 注意:是Node選擇了Javascript,不是Javascript發展出來一個Node ###Node的誕生
- 2008年左右,隨着AJAX的普及,WEB走向複雜化、系統化
- 2009年2月Ryan Dahl想要建立一個輕量級,適應現代WEB開的平臺
- 2009年5月Ryan Dahl在GitHub中開源了最第一版本,同年11月的JSConf就安排了NODE講座
- 2010年末Joyent公司資助,Ryan Dahl也加入了改公司,專門負責NODE的開發
- 2011年7月在微軟的支持下登陸Windows平臺
Node在web中的用途
- node開發的Application處理用戶的全部請求和給用戶的響應
- 分發數據(調用NODE服務器接口,再去調用傳統服務器)請求,渲染HTML頁面
總結:Node是Javascript的運行環境(平臺),不是一門語言,也不是Javascript的框架。javascript
環境配置
makdir .net->建立一個資源管理器不能建立的一些文件 node --use_strict->必須是嚴格模式css
匿名函數自執行的方式:
- (function(){console.log(1)})()
- +function(){console.log(1)}()
- !function(){console.log(1)}()
全局對象
- global(等價於客戶端javascript的window對象)
- process.stdin->標準輸入(採集用戶的輸入)
- process.stdout.write()->標準輸出相似console.log();
模板字符串``中間能夠隨意換行
- var msg='hello';
- var a=1;
- process.stdout.write(
${msg} world
);
- process.stdout.write(
${msg} world ${a}
);
Debug
- vs code編輯器裏面能夠調試
- node debug XXX.js能夠調試
- node-inspector執行後打開127.0.0.1:8080頁面調試(如:node-debug d.js此時會自動打開瀏覽器調試界面google)
- devtool XXX.js也是調試有BUG
練習
- ctrl+c終止當前進程
- 簡單的人際交互,如何在控制檯接收用戶的輸入,如:e.js
異步操做
- 現實
- 程序>一、setTimeout();二、$.ajax()
node中的異步操做
- Node採用Chrome V8引擎處理Javascript腳本,V8最大的特色就是單線程運行,一次只執行一個任務。
- Node大量採用異步操做(asynchronous operation),即任務不是立刻執行,而是插在任務隊列的尾部,等到前面的任務運行完成後再執行
- 提升代碼的影響能力
什麼是I/O
- I/O【input/output】
- 能夠理解爲從輸入到輸出之間的轉化過程
- 好比:敲鍵盤(輸入),看到編輯器出現字符(輸出)
- 移動鼠標(輸入),看到光標移動(輸出)
回調函數的設計
- 對於一個函數若是須要定義一個回調函數:
- 回調函數的必定做爲參數的最後一個參數出現:一、function getFile(name,job,callback){}
- 回調函數的第一個參數默認接收錯誤信息,第二個參數纔是真正的回調數據(便於外界獲取調用的錯誤狀況);如:getFile('jason','coding',function(error,data){if(error) throw error;console.log(data);});
- Node統一約定
- 強調錯誤優先,由於以後的操做大部分都是異步方式,沒法經過try catch捕獲異常,因此錯誤優先的回調函數第一個參數爲上一步的錯誤信息
非阻塞I/O-->其實就是Node的核心特性
事件驅動和非阻塞機制
- Node平臺將一個任務連同該任務的回調函數放到一個事件循環系統中
- 事件循環高效的管理系統池同時高效執行每個任務
- 當任務執行完成事後自動諮詢回調函數
非阻塞的優點
- 提升代碼的響應效率
- 充分利用單核CPU的優點
- 改善I/O的不可預測帶來的問題
- 如何提升一我的的工做效率
- 可是:目前大多數都是多核CUP
異步回調的問題(相對於傳統的代碼)
進程和線程
一、進程(XXX.exe)
- 每個正在運行的應用程序稱之爲進程
- 每個應用程序至少有一個進程
- 進程是用來給應用程序提供一個運行環境
- 進程是操做系統爲應用程序分配資源的一個單位
二、線程
- 用來執行應用程序中的代碼
- 在一個進程內部,能夠有多個線程
- 在一個線程內部,同事只能作一件事
- 並且傳統的開發方式大部分都是I/O阻塞的
- 因此須要多線程來更好的利用硬件資源
- 給人一種錯覺:線程越多越好
2、模塊化結構
- Node實現的CommonJS規範,因此可使用模塊化的方式組織代碼結構
- Node採用的模塊化結果是按照CommonJS規範
- 模塊與文件是一一對應關係,即加載一個模塊,實際上就是加載對應的一個模塊文件
CommonJS規範概述
CommonJS模塊的特色
- 全部代碼都運行在模塊做用域,不會污染全局做用域
- 模塊能夠屢次加載,可是隻會在第一次加載時運行一次,而後運行結果就被緩存了,之後再加載,就直接讀取緩存結果,要想讓模塊再次運行,必須清除緩存
- 模塊加載的順序,按照其在代碼中出現的順序
module對象
- Node內部提供一個Module構建函數,全部模塊都是Module的實例,屬性以下:
- module.id模塊的識別符,一般是帶有絕對路徑的模塊文件名
- module.filename模塊定義的文件的絕對路徑
- module.loaded返回一個布爾值,表示模塊是否已經完成加載
- module.parent返回一個對象,表示調用該模塊的模塊
- module.children返回一個數組,表示該模塊要用到的其餘模塊
- module.exports表示模塊對外輸出的值!
- 載入一個模塊就是構建一個Module實例
模塊的定義
- 一個新的JS文件就是一個模塊
- 一個合格的模塊應該是有導出成員的,不然模塊就失去了第一的意義
- 模塊內部是一個獨立(封閉)的做用域,模塊之間不會衝突
- 模塊之間必須經過導出導入的方式協同
- 導出方式:
- exports.name=value;
- module.exports={name:value};
- 此時就不必在模塊內部寫自執行函數了!!
- module.exports和exports
- module.exports是用於爲模塊導出成員的接口
- exports是指向module.exports的別名,至關於在模塊開始的時候執行:var exports=module.exports;
- 一旦爲module.exports賦值,就會切斷以前二者的相關性
- 最終模塊的導出成員以module.exports爲準
模塊的分類
- 文件模塊:就是咱們本身寫的功能模塊文件
- 核心模塊:Node平臺自帶的一套基本的功能模塊,也有人稱之爲Node平臺的API
- 第三方模塊:社區或第三方我的開發好的功能模塊,能夠直接拿來用
模塊化開發的流程
- 建立模塊:new some.js
- 導出成員:module.exports={}
- 載入模塊:var some=require('./some.js');
- 使用模塊:some.add(1,2);
模塊內全局環境(僞)
- 咱們以後的文件操做中必須使用絕對路徑
- __dirname:用於獲取當前文件所在目錄的完整路徑,在REPL環境無效
- __filename:用來獲取當前文件的完整路徑,在REPL環境一樣無效
- module:模塊對象
- exports:映射到module.exports的別名
- require():require.cache、require.extensions、require.main、require.resolve()
練習:命令行下的計算器,c.js和e.js
- c.js裏是非模塊化的
- e.js是模塊化的(CommonJS規範)
- module.exports={a,b,c};ES6的'自動屬性'
模塊的載入:require函數簡介
- node使用CommonJS模塊規範,內置的require函數用於加載模塊的文件
- require的基本功能是:讀取並執行一個javascript文件,而後返回該模塊的exports對象
- 若是沒有發現指定的模塊會報錯!
require擴展名:規則>描述的越詳細越準確,相似CSS的選擇器優先級
- require加載文件時能夠省略擴展名:require('./module1')
- 此時會默認先找require('./module1.js');
- 若是默認的.js文件不存在接下來會繼續默認找require('./module1.json');
加載文件規則
- 經過"./"或"../"開頭:則按照相對路徑熊當前文件所在文件夾開始尋找模塊:require('../xxx.js')>上級目錄下找xxx.js文件;
- 經過/開頭:則以系統根目錄開始尋找模塊:require('/Users/xxx/Documents/sss.js')>以絕對路徑的方式找,無心義!;
- 若是參數字符串不以"./"或者"/"開始,則表示加載的是一個默認提供的核心模塊(位於Node的系統安裝目錄中):require('fs')、require('http')、require('path')等等;
- 或者從當前目錄向上搜索node_modules目錄中的文件:require('my_module')>各級node_modules夾中搜索my_nodule.js文件;
- 若是require傳入的是一個目錄的路徑,會自動查看該目錄的package.json文件,而後加載main字段指定的入口文件
- 若是package.json文件沒有main字段,或者根本就沒有package.json文件,則默認找目錄下的index.js文件做爲模塊:require('./filesModule')>當前目錄下找filesModule目錄中的index.js文件;
注意require('filename'):
- 加載的模塊名字若是跟系統的模塊衝突,系統的優先級最高!
- 就近原則去找node_modules文件夾下的filename文件
require的實現機制:自定義的的$require,g.js和模塊module2.js
- 將傳入的模塊的ID經過加載規則找到對應的模塊文件
- 讀取這個文件裏面的代碼
- 經過拼接的方式爲該段代碼構建私有空間
- 執行該代碼
- 拿到module.exports返回
__dirname與__filename:如f.js
- __dirname當前文件所在目錄的完整路徑
- __filename當前文件的完整路徑 ###思考與練習:
- 一、如何定義和導入模塊?
- 二、如何使用模塊化的方式組織代碼結構?
- 三、載入模塊的規則
- 四、瞭解模塊的加載機制
- 五、自定義一個$require相似require,如$require下面的:index.js
模塊的緩存:如h.js
- 第一次加載某個模塊時,Node會緩存該模塊,之後再加載該模塊就直接從緩存取出該模塊的module.exports屬性(不會再次執行該模塊);
- 若是須要屢次執行模塊中的代碼,通常可讓模塊暴露行爲(函數)
- 模塊的緩存能夠經過require.cache拿到,一樣也能夠刪除
緩存是如何實現(如:i.js)
如何刪除緩存(如:i.js),通常不會刪除緩存
3、Node:核心模塊、文件操做、文件流、網絡操做
一、核心模塊
-
核心模塊的意義:html
- 若是隻是在服務器運行javascript代碼,意義不大,由於沒法實現任何功能(讀寫文件,訪問網絡)
- Node的用處在於它自己還提供的一系列功能模塊,用於操做系統運動
- 這些核心的功能模塊在Node中的內置
-
內置的有以下模塊java
Node Package
因爲Node是一套輕內核的平臺,雖然提供了一系列的內置模塊,可是不足以知足開發者的需求,因而出現了包(Package)的概念。與核心模塊相似,就是講一些預先設計好的功能或者API封裝到一個文件夾,提供給開發者使用node
1):包的加載機制
- 與內置模塊相同,一樣使用require方法,如:const express=require('express');
- 加載機制也和內置模塊加載機制相同
- 加載注意事項:
- 先在系統核心(優先級最高)的模塊中找
- 而後再到當前項目中的:node_mocules目錄中去找
2):如何管理好本身的包
- 因爲Node自己並無太多的功能性API。因此市面上涌現出大量的第三方人員開發出來的Package
- 包的生態圈一旦繁榮起來,就必須有工具去代替人腦或者文檔的方式去管理
- 此時NPM誕生了~
NPM(Node Package Manager)
1):安裝NPM
- NPM不須要單獨安裝,默認在安裝Node的時候會自動一塊兒安裝NPM
- 可是Node附帶的NPM可能不是最新版本,最好用下面的命令更新到最新版本:$ npm install npm -g
- 默認安裝到當前系統Node所在的目錄下
- 因爲以前使用NVM的方式安裝的Node因此須要從新配置NPM全局目錄
2):配置NPM的全局目錄?
- npm config set prefix [filepath]
- 將NPM目錄配置到其餘目錄時,必須將該目錄放到環境變量中,不然沒法在全局使用
- npm config [ls|list|set|get] [name] [value]
- npm init [--yes|-y]
- npm search [name]
- npm info [name]
- npm install [--global|-g] [name]
- npm uninstall [--global|-g] [name]
- npm list [--global|-g]
- npm outdated [--global|-g]
- npm update [--global|-g] [name]
- npm run [task]
- npm cache [clean]
二、文件操做(important)
Node內核提供了不少與文件操做相關的模塊,每一個模塊都提供了一些最基本的操做API,在NPM中也有社區提供的功能包git
fs:
1):同步或者異步調用(如:day03/code/02.js)
- fs模塊對文件的幾乎全部操做都有同步和異步兩種形式
- readFile()
- readFileSync()
- 區別:
- 同步調用會阻塞代碼的執行,異步則不會
- 異步調用會將讀取任務下達到任務隊列,直到任務執行完成纔會回調
- 異常處理方面,同步必須使用 try catch 方式,異步能夠經過回調函數的第一個參數
- 同步比異步更加耗費時間
2):路徑模塊
在文件操做中,都必須使用物理路徑(絕對路徑),path模塊提供了一些列與路徑相關的APIgithub
3):什麼是緩衝區
- 緩衝區就是內存中操做數據的容器
- 只是數據的容器而已
- 經過緩衝區能夠很方便的操做二進制數據
- 並且在大文件操做時必須有緩衝區
若是讀取文件沒有指定編碼的話,默認讀取的是一個Buffer(緩衝區)
- Buffer的做用,對我們目前的狀況來講只不多使用場景
- 將圖片轉成BASE64編碼(code/04.js)
- 對文字進行BASE64編碼
4):爲什麼要有緩衝區
- JS是比較擅長處理字符串,可是早起的應用場景主要用於處理HTML文檔,不會有太大批次的數據處理,也不會接觸到二進制的數據
- 而在Node中操做數據、網絡通訊是沒辦法徹底以字符串的方式操做的
- 因此在Node中引入了一個二進制的緩衝區的實現:Buffer
- buf.toString([encoding[, start[, end]]])這裏也能夠設置編碼:如code/03.js