摘要:上一章前端教學講義基礎閉包高階函數閉包是一種打通兩個作用域的能力,在和中都有類似的功能,中的閉包和他們沒有太大的差別。在中任何函數都可以當作構造函數并搭配關鍵詞使用。再將作為運行構造函數。
上一章:前端教學講義:JS基礎
閉包、高階函數閉包是一種打通兩個作用域的能力,在 Java 和 OC 中都有類似的功能,JS 中的閉包和他們沒有太大的差別。
不過因為 JS 的函數是一等公民,所以使用起來會更加靈活。
在數學和計算機科學中,高階函數是至少滿足下列一個條件的函數:
接受一個或多個函數作為輸入
輸出一個函數
下面的例子就是個典型的高階函數
const multiple = function(a, b) { return a * b; } const plus = function(a, b) { return a + b; } const express = function(operator, a, b) { return operator(a)(b); } [ [plus, 1, 2], [multiple, 3, 4], ].map(function(formula) { return express.apply(null, formula) }); // [3, 12]call,apply,bind
在 JS 中經常會遇到 this 指向錯亂的問題:
var obj = { value: 1234, log: function() { console.log(this.value) } } var log = obj.log; log(); // 這個函數執行的時候沒有上下文,this 會默認為 window 或者 global // undefined
JS 提供了兩個方法,call 和 apply,能夠指定一個函數執行時候的上下文
log.call(obj); // 1234 log.apply(obj); // 1234
call 和 apply 同時還可以指定傳給函數的參數是什么,他們的區別就是后面的傳參數形式不一樣;
function fn(arg1, arg2){} fn.call(obj, arg1, arg2) fn.apply(obj, [arg1, arg2]) // apply 是將參數當作數組傳入
bind 函數通過閉包的形式,來強制的將某個上下文綁定到函數上:
log = bind(log, obj); // 返回一個新函數,此函數的 this 強制被綁定為 obj log() 1234
bind 的實現大概如下(省略傳參的功能):
function bind(fn, ctx) { return function() { return fn.apply(ctx); } }
和上面舉例有點區別的是 JS 提供的 bind 方法是 Function 類的一個方法,調用方法如下:
function log() {} log = log.bind(obj)原型鏈
JS 的原型鏈(prototype chain)是為了實現面向對象而存在的,當訪問一個對象的方法的時候,首先會遍歷對象本身,是否存在這個鍵,然后在查找父類是否有這個鍵,再一直追溯到頂層。
「父類」中包含的方法和屬性,都存放在對象的 「__proto__」對象上(在舊的 JS 規范中,「__proto__」是隱藏屬性,但是 ES6 將它標準化并暴露出來了)。
var c = { somekey: 1, } var b = { __proto__: c, } var a = { __proto__: b } a.somekey // 1
當訪問 「a.somekey」 的時候,會沿著原型鏈一直向上查找,相當于做了如下計算:
function getValue(obj, key) { while (obj) { if (key in obj) { return obj[key] } if (obj.__proto__) { obj = obj.__proto__; } else { return undefined; } } } getValue(a, "somekey")類
在最早期的 JS 版本中是沒有類的,后來加入了原型鏈和 new 關鍵詞才實現了類。
function SubClass(value) { this.value = value; } SubClass.prototype = { log: function() { console.log(this.value); } } var sub = new SubClass(1234); sub.log(); // 1234
在 JS 中任何函數都可以當作構造函數并搭配 new 關鍵詞使用。
new 關鍵詞的作用就是新建一個空對象 a,然后把構造函數上的 prototype 值掛載到 a.__proto__ 上。
再將 a 作為 context 運行構造函數。
如果我們將 new 作為一個函數,它就是這樣:
function new(class, ...params) { var instance = {}; instance.__proto__ = class.prototype; var result = class.apply(instance, params); if (typeof result !== "undefined") { return result; } return instance; } var sub = new(SubClass, 1234);
從上面的代碼可以看出,在構造函數中,可以指定 new 關鍵詞返回的類型,也就是說 new A() 返回的結果不一定就是 A 的實例,這要看 A 的構造函數內部是如何實現的。
function A() { return 1234; } var a = new A(); console.log(a) // 1234
JS 用原型鏈的方式,曲線的實現了類的行為和寫法,所以在 JS 中,「類」就是構造函數。
instanceof如何判斷一個對象是否是一個類的實例呢?
JS 實現的方法很粗糙,就是判斷實例的原型鏈上是否存在類的原型。
function A() { } var a = new A(); a instanceof A true
我們甚至可以讓任意一個類成為實例的父類
function C() {} function A() {} var a = new A(); C.prototype = A.prototype; a instanceof A // true a instanceof C // true
我們甚至也可以讓一個父類不是實例的父類
function A() {} var a = new A(); A.prototype = {}; // 對原型重新賦值 a instanceof A false
總之就是很神奇
ES6 中對類的改進在 ES6 中新增了 class 關鍵詞,使得聲明一個類更加簡單,但只是寫法上有改變,運行機制還是一樣。
class A { constructor(value) { this.value = value; } log() { console.log(this.value); } } var a = new A(1234); a.log(); // 1234
文章版權歸作者所有,未經允許請勿轉載,若此文章存在違規行為,您可以聯系管理員刪除。
轉載請注明本文地址:http://specialneedsforspecialkids.com/yun/96139.html
摘要:春招前端實習面試記錄從就開始漸漸的進行復習,月末開始面試,到現在四月中旬基本宣告結束。上海愛樂奇一面盒模型除之外的面向對象語言繼承因為是視頻面試,只記得這么多,只感覺考察的面很廣,前端后端移動端都問了,某方面也有深度。 春招前端實習面試記錄(2019.3 ~ 2019.5) 從2019.1就開始漸漸的進行復習,2月末開始面試,到現在四月中旬基本宣告結束。在3月和4月經歷了無數次失敗,沮...
摘要:從最開始的到封裝后的都在試圖解決異步編程過程中的問題。為了讓編程更美好,我們就需要引入來降低異步編程的復雜性。異步編程入門的全稱是前端經典面試題從輸入到頁面加載發生了什么這是一篇開發的科普類文章,涉及到優化等多個方面。 TypeScript 入門教程 從 JavaScript 程序員的角度總結思考,循序漸進的理解 TypeScript。 網絡基礎知識之 HTTP 協議 詳細介紹 HTT...
摘要:可能因為先入為主,在編程之中,往往不由自主地以的邏輯編程思路設計模式進行開發。這是原型模式很重要的一條原則。關于閉包與內存泄露的問題,請移步原型模式閉包與高階函數應該可以說是設計模式的基礎要領吧。在下一章,再分享一下的幾種常用設計模式。 前 在學習使用Javascript之前,我的程序猿生涯里面僅有接觸的編程語言是C#跟Java——忽略當年在大學補考了N次的C與VB。 從靜態編程語言,...
講義內容:JS 誕生的背景、基本類型、運算符 以下內容只涉及 ES5 標準,ES6 增加的新內容可以在網上查找到。 JS 誕生的背景 上世紀 90 年代網景公司開發的瀏覽器獨步天下 一個叫做 Brendan Eich 的工程師受命于開發一款腳本語言,來增強瀏覽器的功能。 這名工程師花費了 10 天時間設計出了第一個版本,名叫 LiveScript。 后來因為當時 Java 正紅,公司將其改名為 J...
摘要:引言本期開始介紹中的高階函數,在中,函數是一種特殊類型的對象,它們是。簡單來說,高階函數是一個接收函數作為參數傳遞或者將函數作為返回值輸出的函數。我們來看看使用它們與不使用高階函數的方案對比。引言 本期開始介紹 JavaScript 中的高階函數,在 JavaScript 中,函數是一種特殊類型的對象,它們是 Function objects。那什么是高階函數呢?本節將通過高階函數的定義來展...
閱讀 1660·2021-11-12 10:35
閱讀 1611·2021-08-03 14:02
閱讀 2655·2019-08-30 15:55
閱讀 2024·2019-08-30 15:54
閱讀 735·2019-08-30 14:01
閱讀 2421·2019-08-29 17:07
閱讀 2246·2019-08-26 18:37
閱讀 3028·2019-08-26 16:51