摘要:聲明設計模式系列是來自設計模式與開發這本書的讀書筆記,會結合自身的理解和一些項目經驗做筆記,原書作者曾探前言什么是設計模式,設計模式就是在某種場合下對某個問題的一種解決方案。
前言聲明: 【JavaScript設計模式】 系列 是來自《JavaScript設計模式與開發》這本書的讀書筆記,會結合自身的理解和一些項目經驗做筆記,原書作者 曾探
什么是設計模式,設計模式就是在某種場合下對某個問題的一種解決方案。說通俗一點就是給一段代碼起個名字而已,比如一個用玻璃做的能裝水的東西,給它起個名字叫水杯,
大家一提到水杯就知道什么對象,具有什么功能,這樣大家一想到要喝水就找個水杯這么個東西,滿足需求
JavaScript是一門典型的動態類型語言。記住這一特性很重要,比如js有個數組類型Array,要是一個對象,這個對象具有length屬性,還擁有slic,splice方法,那也可以將這個對象當做數組來用。這完全是可以的,因為語言是動態的,我們可以面向接口編程,而不是面向實現編程。
2、多態也正因為js是動態類型語言,所以js本身具有多態的特性。
什么是多態呢:多態就是同一操作作用于不同對象,產生不同的結果
例子:
function fun(obj) { obj.log() } function Obj1() { } Obj1.prototype.log = function () { console.log("....Obj1......") } function Obj2() { } Obj2.prototype.log = function () { console.log("....Obj2......") } fun(new Obj1()) // ....Obj1...... fun(new Obj2()) // ....Obj2......
給函數 fun 傳遞不同對象,能得到不同的結果
這要是在Java就要設計成子類繼承同一個父類,調用的時候向上轉型才能調用同一個父類方法得到不同結果,多麻煩呀
JavaScript是一門動態語言,既沒有檢查創建的對象類型,也沒有檢查傳遞的參數類型,所以實現
多態就變得尤為簡單,不必諸如向上轉型的技術來實現多態
JavaScript是沒有私有變量和共有變量或共有方法的,但它有個函數作用域,我們可以利用這一特性來滿足這一點
例子:
var fun2 = (function () { var _name = "my name is 田生" return { name: _name, pubFun: function () { console.log(".....pubFun.....") } } })() console.log(fun2.name) // my name is 田生 console.log(fun2.pubFun()) //.....pubFun.....4、JavaScript中的原型繼承
JavaScript的對象不是通過實例化得到的,而是通過克隆原型對象Object.prototype得到的。
所以經常會預定一個面試題是,js 的 new 操作做了哪些工作?那你可以這樣回答,new 操作符是
執行一個構造函數,函數里面克隆了 Object.prototype 對象,并把新對象附上屬性值返回出去。
例子:
function Obj() { this.name = "田生" } var o1 = new Obj() console.log(o1.name) // 田生 // 相當于 function CloneObj() { var obj = new Object() // 從 `Object.prototype` 克隆一個新對象 obj.name = "田生" return obj } var o2 = CloneObj() console.log(o2.name) // 田生5、JavaScript中的原型璉
如果對象無法響應某個請求時,它會把這個請求委托給它的構造器的原型prototype去執行
例子:
function Obj() { this.name = "田生" } var o1 = new Obj() console.log(o1.toString()) // [object Object] console.log(o1)
上面例子克隆了個新的 對象Obj ,新對象沒有 toString 方法,所以在調用 toString 方法時,這個請求就會委托給他的原型對象 Object 的 prototype去執行
那你可能會疑惑,對象 Obj對象 是怎么和 Object 的 prototype對象掛上鉤的呢?
你可以試著在Chrome瀏覽器的開發者模式中輸入上面代碼,試著打印 console.log(o1)
會發現 Obj 有個 proto 的屬性指向了 Object對象,這就是它們連接的紐帶
當函數作為對象的方法調用時,this 指向改對象
例子:
var Obj = { name: "田生", fun: function () { console.log(this.name) // this 指向改 對象 } } Obj.fun() // 田生
當函數不作為對象的屬性被調用時,也就是常說的普通方法,此時this指向全局對象
var name = "田生....2" function fun1() { console.log(this.name) // fun1 當做普通函數,this指向全局 function fun2() { console.log(this.name) // fun2 也當做普通函數,this指向全局 } fun2() // "田生....2" } fun1() // "田生....2"
fun2 函數的this為什么也指向全局呢?有必要再強調一下,當函數不作為對象的屬性被調用時,也就是常說的普通方法,此時this指向全局對象!
當然在 ES6 strict 模式下 this為undefined
首先要明確一點,JavaScript 的 Function 實際上是功能完整的對象。那對象就可以調用方法。
所以在看到下面的例子就不要疑惑:
function fun(para) { } fun.length fun.apply(null, ["田生"]) fun.call(null, "田生") fun.toString()
為什么一個函數有屬性呢,為什么一個函數居然可以調用另一個方法呢,因為JavaScript 的 Function 實際上是功能完整的對象啊,對象就有屬性和方法啊
沒啥區別,就接受參數的方式不一樣而已,apply 接受的第二個參數是集合,call接受的參數不固定用逗號隔開。
但可以說 call 是包裝在 apply 的語法糖,內部實現也是將參數轉數組的形式,所以某種意義上講
apply的效率高一點。
改變this的指向:
function Obj() { this.name = "HI 田生~" function fun() { console.log(this.name) // undefined } fun() } new Obj()
上面小節也講了,fun 沒綁定到對象上,所以在這里被當做普通函數使用,this指向全局對象,那咱們要
this.name正常輸出怎么辦:
// 方法一:傳統的 _this 傳遞 function Obj() { this.name = "HI 田生~" var _this = this function fun() { console.log(_this.name) // HI 田生~ } fun() } new Obj() // 方法二:借助 apply 或 call function Obj() { this.name = "HI 田生~" function fun() { console.log(this.name) // HI 田生~ } fun.apply(this) } new Obj()
哪種方法好用我就不多說了
借用其他對象方法
var arr = [] Array.prototype.push.apply(arr,[1, 2, 3]) console.log(arr) // [1, 2, 3]三、閉包和高階函數 1、閉包
閉包這個概論總是不好理解,你可以簡單的理解為 閉包就是能夠讀取其他函數內部變量的函數
例子:
var func = function () { var a= 1 return function () { a++ console.log(a) } } var fun = func() fun() // 2 fun() // 3 fun() // 4
變量 a 是函數 func 的局部變量,外部函數或對象無法訪問,但 func 內部的匿名函數能訪問,那就這個匿名函數就是一個閉包 ,將閉包返回出去,相當于將訪問權給了外部環境,外部環境就可以訪問一個函數的
局部變量了。
上面第一小點順帶講了閉包能使外部環境訪問局部變量,是作用點之一。閉包還可以延續局部變量的壽命
例子:
// 方式1 var report = function (src) { var img = new Image() img.src = src } report("http://wwww.tiansheng.logo.png") // 方式2 var report = (function () { var img return function (src) { img = new Image() img.src = src } })() report("http://wwww.tiansheng.logo.png")
利用方式1有可能圖片還沒加載完數據就丟失了,因為 report 方法執行完局部變量就銷毀了,而方法2
利用閉包的方式延長了變量的壽命
高階函數至少需要滿足以下條件之一:
函數可以作為參數傳遞
函數可以作為返回值輸出
我們經常寫的帶有對調函數就是一個高階函數
例子:
/** * 高階函數 * @param name * @param callBack */ function fun(name, callBack) { // do something ... callBack() }
函數作為返回值輸出,其實就是一種閉包的表現
下面一個單例模式的例子:
var getSingle = function (fn) { var ret; return function () { return ret || (ret = fn.apply(this, arguments)) } } var getScript = getSingle(function () { // ... }) var script1 = getScript() var script2 = getScript() console.log(script1 === script2) // true小結:
本小結寫了 【面向對象的JavaScript】、【this、call 和 apply】、 【閉包和高階函數】 ,為接下去的JavaScript 設計模式做鋪墊
文章版權歸作者所有,未經允許請勿轉載,若此文章存在違規行為,您可以聯系管理員刪除。
轉載請注明本文地址:http://specialneedsforspecialkids.com/yun/88725.html
摘要:設計模式是以面向對象編程為基礎的,的面向對象編程和傳統的的面向對象編程有些差別,這讓我一開始接觸的時候感到十分痛苦,但是這只能靠自己慢慢積累慢慢思考。想繼續了解設計模式必須要先搞懂面向對象編程,否則只會讓你自己更痛苦。 JavaScript 中的構造函數 學習總結。知識只有分享才有存在的意義。 是時候替換你的 for 循環大法了~ 《小分享》JavaScript中數組的那些迭代方法~ ...
摘要:首先,需要來理清一些基礎的計算機編程概念編程哲學與設計模式計算機編程理念源自于對現實抽象的哲學思考,面向對象編程是其一種思維方式,與它并駕齊驅的是另外兩種思路過程式和函數式編程。 JavaScript 中的原型機制一直以來都被眾多開發者(包括本人)低估甚至忽視了,這是因為絕大多數人沒有想要深刻理解這個機制的內涵,以及越來越多的開發者缺乏計算機編程相關的基礎知識。對于這樣的開發者來說 J...
摘要:深入之繼承的多種方式和優缺點深入系列第十五篇,講解各種繼承方式和優缺點。對于解釋型語言例如來說,通過詞法分析語法分析語法樹,就可以開始解釋執行了。 JavaScript深入之繼承的多種方式和優缺點 JavaScript深入系列第十五篇,講解JavaScript各種繼承方式和優缺點。 寫在前面 本文講解JavaScript各種繼承方式和優缺點。 但是注意: 這篇文章更像是筆記,哎,再讓我...
摘要:函數式編程前端掘金引言面向對象編程一直以來都是中的主導范式。函數式編程是一種強調減少對程序外部狀態產生改變的方式。 JavaScript 函數式編程 - 前端 - 掘金引言 面向對象編程一直以來都是JavaScript中的主導范式。JavaScript作為一門多范式編程語言,然而,近幾年,函數式編程越來越多得受到開發者的青睞。函數式編程是一種強調減少對程序外部狀態產生改變的方式。因此,...
摘要:閱讀小札一閱讀前自大學課上,就開始接觸設計模式,但對設計模式卻鮮有研究與實踐。第二部分是核心部分,由淺到深講解個設計模式。設計模式遵循的原則所有設計模式罪訓的一條原則就是找出程序中變化的地方,并將變化封裝起來。 閱讀小札 · 閱讀前 自大學Java課上,就開始接觸設計模式,但對設計模式卻鮮有研究與實踐。最近向公司反映和游說技術提升,得以獲得公司提供購書機會,借此認真學習前端學習之路的...
摘要:是文檔的一種表示結構。這些任務大部分都是基于它。這個實踐的重點是把你在前端練級攻略第部分中學到的一些東西和結合起來。一旦你進入框架部分,你將更好地理解并使用它們。到目前為止,你一直在使用進行操作。它是在前端系統像今天這樣復雜之前編寫的。 本文是 前端練級攻略 第二部分,第一部分請看下面: 前端練級攻略(第一部分) 在第二部分,我們將重點學習 JavaScript 作為一種獨立的語言,如...
閱讀 3384·2023-04-25 20:37
閱讀 3142·2021-09-07 09:59
閱讀 1665·2019-08-29 12:43
閱讀 1185·2019-08-28 18:27
閱讀 479·2019-08-26 13:50
閱讀 2025·2019-08-26 10:33
閱讀 3591·2019-08-23 18:39
閱讀 2390·2019-08-23 18:09