轉載自 水歌博客,方便學習,順便前排觀望大佬!
JavaScript 是一門原生支持函數式編程範式的、基於原型的面向對象語言,也是一門弱類型動態腳本語言javascript
JavaScript 函數的
this
是由函數調用者在調用前肯定的 —— 繼承自 LISP 語言java
用 ECMAScript 6 解釋以下:編程
調用方式 | 調用者 | 等效代碼 |
---|---|---|
func(...params) |
JS 引擎 | func.apply(null, params) |
obj.func(...params) |
一個對象 | func.apply(obj, params) |
new func(...params) |
new 運算符 |
func.apply(Object.setPrototypeOf({ }, func.prototype), params) |
element.onclick = func |
DOM 事件回調 | func.call(element, event) |
上述最後一種實際上是運行時 API 級別的,與語言自己無關,用 JS 寫的公共庫須要回調函數時,也是庫內部調用時如上手動指定的。bash
通俗解釋:閉包
孩子靠着自創資產和本身可掌控的父母遺產,繼續活下去app
技術解釋:異步
局部做用域中建立的函數,若引用了其上級做用域中的變(常)量,又在上級做用域外有引用,上級做用域執行結束被銷燬時,此函數及其引用的數據造成一個不被銷燬的閉包。async
—— 繼承自 LISP 語言函數式編程
var closure = function () {
const privateData = { };
return {
set: function (key, value) {
privateData[key] = value;
},
get: function (key) {
return privateData[key];
}
};
};
closure.set('A', 1);
console.log( closure.get('A') ); // 1
複製代碼
閉包在 ECMAScript 5 及更早的時代,經常使用於模擬塊級做用域、模塊做用域,在 ECMAScript 6 引入這兩種新局部做用域後,它們又成了造成閉包的上級做用域之一。函數
基於原型的面嚮對象語言 可看做把 基於類的面嚮對象語言的運行時內部構造 開放了出來
類 | 原型 | |
---|---|---|
對象的建立 | 由 class 的構造函數修飾 this |
直接 new 一個函數做爲構造函數 |
對象的繼承 | 只知其然,不知因此然 | 對象內部引用構造函數的原型對象,在引用對象未定義成員時,在原型上找同名成員 |
類的繼承 | 只知其然,不知因此然 | Child.prototype = new Parent() |
私有成員 | 只知其然,不知因此然 | 用局部做用域「對外不可訪問性」保存的私有 Symbol (運行時惟一值)命名對象成員 |
異步函數先記下要作什麼(傳入的參數、回調函數)並交給 JS 引擎所在運行時平臺的其它線程,而後立馬返回,讓 JS 自身線程繼續執行完後面的同步代碼,再按異步任務完成的順序,一一用相應結果數據調用回調函數。
全部的異步任務內部都基於回調函數實現:
function asyncFunc(callback) {
setTimeout(callback, 1000);
}
asyncFunc(function () {
console.log('See you later')
});
複製代碼
但須要回調函數的不必定是異步任務:
function syncFunc(callback) {
console.log('See you ' + callback());
}
syncFunc(function () {
return 'now';
});複製代碼