買一送一
:本系列可以讓你掌握函數語言程式設計
,並且附贈 underscore
技能
日常BB
面對日新月異的程式語言
都展開了函數語言程式設計大戰,靈活古老的javascript
怎麼不參戰?javascript
可是天然支援函式基礎的元老人物。想要成為一名高逼格的程式設計師不管你是前端,還是後臺,亦或是全棧,不管你開發web
或hybrid
,怎麼能不掌握呢?筆者主要是java
從業者,物件導向思想根深蒂固,讓我們以javascript
為基石,破而後立,重新學習javascript
,進行函式程式設計,感受非同一般的程式設計樂趣。
要說javascript
的函式程式設計
Jquery
可以少,但是underscore
是必不可少的,不管你是否掌握underscore
,後續系列文章可能會大量使用此庫。
不得不說的第一課
call()
和apply()
掌握call()
和apply()
不是學好函式程式設計的關鍵,而是基石,先簡單講下:
其實call
和 apply
的存在目的只有一個:改變函式整體內部this
的指向,this 這裡就不老生常談了,完全浪費大家時間,聽說不舉例子都是耍流氓,我舉還不行嘛...
/**
* Created by Venda-GM on 2017/10/18.
*/
function Peaple() {}
Peaple.prototype = {
name:'小明',
say:function(){
alert(this.name);
}
}
var Peaple1 = {
name:'小強'
}
var peaple = new Peaple();
peaple.say.call(Peaple1); //小強
peaple.say.apply(Peaple1);//小強
//******************知識點0.0***************
Fn1並沒有say這個方法,但是fn原型有,那麼fn.call...
複製程式碼
可以看出來:
其中的this
被指向了,name
並不是原來Peaple
中的小明
了
- 結論:
不管是call 還是 apply 都改變了函式的 this 物件
那兩個函式總有差距,具體差距呢↓
--接受引數不一樣
--
call()方法中的[其餘的]引數必須直接傳給函式
apply()接收兩個引數:一個引數是執行時的作用域,
另一個是引數陣列、或arguments等
複製程式碼
arguments
是什麼?
和call
,appply一樣,都是每個function
內建的方法,arguments
是屬性,可以獲取到傳遞到這個方法的全部變數。一般在庫中極為常見
問底註解①_.toArray
就用了。
- 瞭解了之後我們組合起來做一個例子:
我們製造一個函式
:它 接受一個函式,返回一個函式,並用apply
執行返回來的函式。
function splat(fun){
return function(array){
return fun.apply(console,array);
}
}
var addArray = splat(function(x,y){
this.log(x,y)
return x+y;
})
addArray([1,2]); //3
```
先自己想1分鐘,然後我來解析一下發生了啥?
![](https://user-gold-cdn.xitu.io/2017/10/19/3147f656dc04af503316778871056470)
我們呼叫`addArray`的時候`addArray`呼叫了`splat()`函式並向他傳遞了一個`函式`(我們簡稱`解決方案`吧),而他也沒幹啥好事,最終`splat()`返回的函式說:`“我也解決不了,你的方案不錯,就用你的做吧。”` 說完大筆一揮, `fun.apply() `[同意!] 並且把你提交的`[1,2]`,按照你的解決方案執行了後還給你。
- 並且發現
最終`addArray`內部的`this`物件由`window`轉變為了`console`。有人問這有個吊用?下面舉例
複製程式碼
function splat(fun){
return function(array){
var math_π =[1,4,1,5,9,2,6,5];
return fun.apply(math_π,array);
}
}
var addArray = splat(function(x,y){
this.push(x+y)
console.log(this); //[1,4,1,5,9,2,6,5,3]
return x+y;
})
addArray([1,2]); //3
```
複製程式碼
我們有一個私有屬性math_π
,並不想設為全域性,並且在執行addArray
的匿名方法是還想讓他對math_π
搞事情,那麼我們可以吧指標通過apply
指向它,處理一些事情
我以前講的物件導向程式設計
說過,私有的物件導向處理方法是,製造原型鏈設定get/set
方法,在new
一個物件,get
到即可,物件導向是容易理解,但是是不是有點向java
一樣繁瑣了呢。
剛才例子講了啥?健忘症又犯了! 講了我們實現了一個函式它接受了一個函式,並且返回了一個函式,返回的函式執行了接受的函式,並且改變了作用域。
我們可以做一個相反的,若有這樣一個需求:
我有個方法只接受陣列,但是現在有個不可抗力讓我只能傳字串,傳多少個我也不知道,我該怎麼辦?
//原始方法
var F = function(array){
return array.join(' ')
}
複製程式碼
想傳的資料
1,2,3,4,5,7,7,zzz,www,ddd
複製程式碼
我們首先想到arguments
,那怎麼原封不動F實現需求呢?用call
!完全吻合
//做一個轉換器
var ParamsConvertor = function(fun) {
return function(){ //返回一個匿名函式
fun.call(this,_.toArray(arguments));①
}
}
複製程式碼
我們呼叫下:
ParamsConvertor(F)(1,2,3,4,5,7,7,'zzz','www','ddd');
複製程式碼
列印結果:
1 2 3 4 5 7 7 zzz www ddd
複製程式碼
完美!
這還只是摸到了函式式的一些邊緣就已經很興奮了,正式開始進行程式設計會怎麼樣呢?
今天太晚了就先寫到這裡
ps:①_.toArray
是underscore
的一個函式,
toArray_.toArray(list)
把list(任何可以迭代的物件)轉換成一個陣列,在轉換 arguments 物件時非常有用。
(function(){ return _.toArray(arguments).slice(1); })(1, 2, 3, 4);
=> [2, 3, 4]
複製程式碼
我們看到其實他也是運用了arguments
物件。
資料:underscore中文文件
與underscore
可以配合使用的還有lodash中文文件
目前先掌握underscore
即可。
以後部落格將首發到這個git
庫中,並寫一個列表,感興趣可以點下star
,點star
不迷路,github
有歸檔。
接下來會正式踏足函數語言程式設計
,準備好了麼,另外設計模式
也會盡力持續更新,本來打算一個系列一個系列更新,但是根本按耐不住想寫其他的,其實我最近更想寫的是java,還想用Electron
封裝一個elasticsearch
客戶端、繼續維護爬蟲框架
、想做的事情很多,慢慢來吧。