章節連結
Call, apply 和 bind 這三個內建函式,主要是用於設定 this 的範圍。當你呼叫一個函式時,你可以藉機改變 this 的範圍,將你想要的參數傳入。在你撰寫一些數學運算函式時,可以省去你重複撰寫的麻煩。
課程對應章節
Course 50 ~ Course 52 (全部一共有 85 Courses)
請注意:本系列文章為個人對應課程的消化吸收後,所整理出來的內容。換言之,並不一定會包含全部的課程內容,也有可能會添加其他資源來說明。課程連結網址:http://tinyurl.com/w7vrql6
內容
1. 這三者在呼叫時,都會將第一個傳入的物件當作 this 的新範圍。
2. 物件本身內的 this,會是指向物件本身。不過若你是在函數內使用 this,在預設的情況下,會指向 global object。這在使用上會容易造成誤解和困擾。
3. 若你在物件內的某項的回傳函式內,使用了 this,那麼 JavaScript 會將這個 this 指向 global object。因此,你會看見像是 self = this ,這樣的用法出現在物件中,就是為了保存當下 this 指向物件本身的狀態。
4. bind() :可在 function 後方直接使用,並代入新的物件當作 this 的新範圍。
5. call():第一個引數是新的物件範圍,後面可以緊接代入函數所需的(預設)參數。換言之,你不一定要給定所有參數,你可以用這個特性造出許多架構類似的函式,而不用一直重複撰寫。
6. apply():跟 call() 很像,但後頭的參數要以 array 代入。
7. bind()僅複製原本的函式架構,所以要啟用還是要加上()。不過 call() 和 apply () 則是會主動執行,所以就不用加 ()。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 |
/*Example*/ var person = { firstname: 'Andy', lastname: 'Lin', getFullName: function(){ var fullname = this.firstname + ' ' + this.lastname; return fullname; } } var person1 = { firstname: 'Sandy', lastname: 'Wang', } /*1. error happened */ var logName = function(location1,location2){ console.log('Logged: ' + this.getFullName()); }; logName() // error, it can't find getFullName() in global object /*2. solution */ logName.bind(person) // Logged: Andy Lin /*3. 你也可以這樣改寫*/ var logName = function(location1,location2){ console.log('Logged: ' + this.getFullName()); }.bind(person); logName() // bind本身只有複製函式,並不會自動觸發,所以要加() /*4.call()*/ var logName = function(location1,location2){ console.log('Logged: ' + this.getFullName()); console.log('Arguments: ' + location1 + ' ' + location2); }; logName.call(person,"Taipei","Taiwan") /*5.apply()*/ var logName = function(location1,location2){ console.log('Logged: ' + this.getFullName()); console.log('Arguments: ' + location1 + ' ' + location2); }; logName.call(person, ['Taipei','Taiwan']) /*6. function carrying*/ function multiple (a,b){ return a*b } var multipleByTwo = multiple.bind(this,2) var multipleByTest = multiple.bind(this,3,3) console.log(multipleByTwo(3)) // 6, due to 2*3 = 6 console.log(multipleByTest(5)) // 9, due to 3*3 = 9 console.log(multipleByTest(100)) // 9, due to 3*3 = 9 /*7. function borrowing*/ var person = { firstname: 'Andy', lastname: 'Lin', getFullName: function(){ var fullname = this.firstname + ' ' + this.lastname; return fullname; } } console.log(person.getFullname.apply(person2)) // Sandy Wang console.log(person.getFullname.call(person2)) // Sandy Wang console.log(person.getFullname.bind(person2)()) // Sandy Wang |