javaScript中的高級技巧

函數綁定

函數綁定這個是一個很是流行的一個對函數的一種使用技巧,它經過在特定的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+新的方法來實現,這裏就不去作那些麻煩的講解了。

這篇博客也是我學習的一個記錄,若是以爲對你有所幫助的話,點個贊呀!!

相關文章
相關標籤/搜索