函數綁定這個是一個很是流行的一個對函數的一種使用技巧,它經過在特定的this環境下去指定參數的形式,去調用一個函數,這就稱做是函數綁定。java
在咱們用的最廣泛的一個地方,就是在React使用面向對象編程的時候,綁定一個點擊事件的狀況,就是屬於函數綁定的範疇。編程
函數綁定有什麼做用呢,一樣的咱們以一個點擊事件做爲例子數組
<button id = 'dd' name='anta'>點擊點擊點擊</button>
const test = {
name: 'nike',
click: function(){console.log(this.name)
}}
const bb = document.getElementById('dd')
bb.addEventListener('click', test.click) //anta
複製代碼
預期的話,咱們是要打印出來nike的,可是實際上由於javaScript裏面的this指向不是在定義的時候指向的,而是調用的時候纔有具體的只想,因此這裏的click函數裏面,this的指向其實是指向了button,因此打印出來的this.name是anta,因此打印出來的也是anta。安全
那麼要解決這種問題,就須要用到函數綁定了markdown
const bb = document.getElementById('dd')
bb.addEventListener('click', function(event){test.click(event)}) //nike
複製代碼
在React裏面咱們通常上來講是使用bind()這個方法來綁定函數this的指向也是能夠的。閉包
const bb = document.getElementById('dd')
bb.addEventListener('click', test.click.bind(test)) //nike
複製代碼
函數柯里化的意思,其實簡單點來講的話,就是使用一個閉包去返回一個函數,它跟函數綁定的原理是同樣的,惟一的區別就是返回的函數裏面還須要設置一些參數。app
用一個比較通俗一點例子來講明函數
function test1(num1, num2) {
return num1 + num2
}
function test2(num3) {
return test1(1, num3)
}
console.log(test2(2)) //3
複製代碼
雖然這個不是函數柯里化,可是意思就是那個意思。性能
那麼,咱們要怎麼去建立一個柯里化的一個函數呢,下面有一個比較通用的一個方法來幫助咱們建立一個柯里化函數。學習
function test1(fn) {
const arg = Array.prototype.slice.call(arguments, 1)
return function () {
const innerAge = Array.prototype.slice.call(arguments)
const str = innerAge.concat(arg)
return fn.apply(null, str)
}
}
複製代碼
它的意思也比較簡單,經過調用Array對象的slice方法,而後經過call將這個方法只想arguments,同時傳入一個1,也就是從第一位開始截取。
這裏的arguments是一個類數組,表示的意思就是函數傳進來的全部值的一個數組集合體。
而後你二個arguments對應的就是test1內部的function的傳值,接着上下兩個數組拼接起來,最後經過apply傳遞給fn去使用,這個fn就是指代外部傳進來的執行函數。
例如能夠這樣去使用這個柯里化函數:
function add(num1, num2) {
return num1 + num2
}
const data = test1(add, 5, 6)alert(data()) //11
複製代碼
柯里化函數能夠幫助咱們完成一些相對複雜的函數的建立,可是使用的時候仍是須要謹慎使用,由於存在閉包的關係,會對性能有必定的損耗。
由於javaScript是一門弱類型語言,也就意味着對象的篡改不像其它語言同樣有大量的限制,因此爲了防止對象被篡改,這裏介紹三種方法。
鎖定對象,或者能夠說是不可擴展的對象。
咱們知道,咱們是能夠隨時對一個對象進行擴容的,而沒有太多的限制。
const test = { name: 'nike',}
test.book = 'haha';
alert(test.book) //haha
複製代碼
可是若是把這個對象變成了不可擴展的,那麼就能夠避免這種事情發生。
方法是——Object.preventExtensions
它的使用效果就會把一個對象給變成不可擴展的狀態,例如
const test = { name: 'nike',}
Object.preventExtensions(test)
test.age =18alert(test.age) //undefined
複製代碼
上面介紹的方法,雖然可讓對象變成不可擴展的狀態,可是這時候的對象仍是能夠刪除,這時候要想把這個對象變成既不能夠擴展,也不能夠刪除的,要怎麼操做呢。
這時候就能夠借用這個方法——Object.seal()
這個方法的使用也跟上面的方法同樣。
const test = { name: 'nike',}
Object.seal(test)delete
test.namealert(test.name) // nike
複製代碼
若是說一個對象既不能夠擴展了,也不能夠刪除了,那麼還能夠幹嗎呢。
沒錯,就是修改,經過seal()這個方法的對象,它裏面的屬性依然是能夠外部直接修改的,那麼,要想讓一個對象屬性變成既不能夠被刪除,也不能夠擴展,同時還不能被修改,有沒有什麼辦法呢,答案固然是有的。
那就是冰凍對象——Object.freeze()
經過Object.freeze包裹後的對象,就會變成完全的冰凍住,不能對它作任何的改動了。
以上的方法,在對對象使用了以後,好比使用了Object.freeze() 而後依然去修改這個對象,在普通模式下,會返回一個undefinded,可是在嚴格模式下,是會報錯的,這裏是一個須要注意的地方。
一些高級技巧裏面還有一些相似安全做用域這些,後面均可以經過ES6+新的方法來實現,這裏就不去作那些麻煩的講解了。
這篇博客也是我學習的一個記錄,若是以爲對你有所幫助的話,點個贊呀!!