js中有三個改變this指針的方法,分別是 apply,call,bind。很多人只知道能改變的this,但是具體的適用場景不是太清楚。我也是遇到坑後不斷的實踐發現了區別。 call ,apply方法: 在Food類中,因為使用了call改變類Product的類的this執向。所以這個時候在Prod ...
js中有三個改變this指針的方法,分別是 apply,call,bind。很多人只知道能改變的this,但是具體的適用場景不是太清楚。我也是遇到坑後不斷的實踐發現了區別。
call ,apply方法:
1 function Product(name, price) { 2 this.name = name; 3 this.price = price; 4 } 5 6 function Food(name, price) { 7 Product.call(this, name, price);
8 this.category = 'food'; 9 } 10 11 console.log(new Food('cheese', 5).name); 12 // expected output: "cheese"
在Food類中,因為使用了call改變類Product的類的this執向。所以這個時候在Product 中this定義的兩個私有屬性卻成了Food類new出來對象的。這種方式實現了類似繼承的概念,這種方式叫做call繼承。
其中call第一個參數表示的是修改的類的this指向值,後面兩個name,price都是做為參數傳遞到Product中。最後在執行這條語句的時候,會執行一下Product這個類(函數)。也就是call就會執行一下 ‘’.‘’ 符號之前的類或者函數。
apply相對call來說也是執行了一下函數或者類,只是參數傳遞進行了組裝。如果要進行apply修改,第7句話就可以表達為 Prpduct.apply(this,[name,price]); 可以把要傳遞的參數進行數組化。
bind:
bind是es6中新推出的修改this的方法。但是他和傳統的call,apply區別就是函數或者類的this修改後沒有執行,而是在程式代碼檢測時已經對代碼的this指向進行了修改。那麼有什麼用呢?
比如我這個時候需要用DOM2級別的事件綁定 :
document.addEventListener('click',fn); fn(){ this.name='yangkun' } //這裡我們給document元素對象添加了一個點擊事件方法fn; var obj={name:'zhansan'}; fn.call(obj); 我們需要的是修改fn中的this,指向是obj中的name.是如果這樣做,會有一個問題就是,函數fn已經被執行了!實際上我們綁定的click事件對應的是一個函數返回值(這裡沒有返回值,實際上點擊事件綁定了null),而不是我們希望綁定的方法!
這個時候如果我們使用fn.bind(obj)就沒問題了。方法沒有執行。
後記:JavaScript早期版本沒有類,但是大家發現通過new可以實現類似後臺語言的語法方式。自然把進行new 的函數說成類。 js 函數有三態,普通函數,類,對象。這個是ES6之前函數的三態。