call、apply、bind:將物件變成另一個函式中的this
[測試範例的 物件 和 函式]
物件:var objTest
函式:function test(a, b)
var objTest = { x: "xyz" } function test(a, b) { console.log("this.x=", this.x); console.log("a=", a); console.log("b=", b); console.log("arguments=", Array.from(arguments)); //console.log("arguments=", [...arguments]); }
test(1, 2); //this.x= undefined //a= 1 //b= 2 //arguments= [1, 2]
[call]
使用call,會直接執行function。test.call(objTest); //this.x= xyz //a= undefined //b= undefined //arguments= [] test.call(objTest, 10); //this.x= xyz //a= 10 //b= undefined //arguments= [10] test.call(objTest, 10, 20); //this.x= xyz //a= 10 //b= 20 //arguments= [10, 20]
[apply]
使用apply,會直接執行function。跟call不同,傳入的參數為陣列。test.apply(objTest); //this.x= xyz //a= undefined //b= undefined //arguments= [] test.apply(objTest, [10]); //this.x= xyz //a= 10 //b= undefined //arguments= [10] test.apply(objTest, [10, 20]); //this.x= xyz //a= 10 //b= 20 //arguments= [10, 20]
[bind]
使用bind,會回傳綁定後的function,綁定時可選擇是否綁定參數值,沒綁定的參數值,可使用時再傳入。
//只綁定this物件 var ff = test.bind(objTest); ff(); //this.x= xyz //a= undefined //b= undefined //arguments= [] ff(10); //this.x= xyz //a= 10 //b= undefined //arguments= [10] ff(10, 20); //this.x= xyz //a= 10 //b= 20 //arguments= [10, 20]
//綁定了this物件,和第一個參數a=10,則使用時,參數a不須也無法再傳值,a固定為10 var ff = test.bind(objTest, 10); ff(); //this.x= xyz //a= 10 //b= undefined //arguments= [10] ff(20); //已綁定了第一個參數a=10,所以剩下的參數只剩一個,此處傳的是b=20 //this.x= xyz //a= 10 //b= 20 //arguments= [10, 20] ff(50, 60); //多傳的參數60,不會用到 //this.x= xyz //a= 10 //b= 50 //arguments= [10, 50, 60]
//綁定了this物件,和第一個參數a=10,第二個參數b=10,則使用時,參數a、參數b不須也無法再傳值,a固定為10,b固定為20 var ff = test.bind(objTest, 10, 20); ff(); //this.x= xyz //a= 10 //b= 20 //arguments= [10, 20] ff(91, 92); //this.x= xyz //a= 10 //b= 20 //arguments= (4) [10, 20, 91, 92]
[應用]
- 處理偽陣列(類似陣列,但不是陣列的資料,當成陣列處理)
function aa() { //arguments 不是陣列,不能使用 slice、push... //arguments.slice(1) //Uncaught TypeError: arguments.slice is not a function console.log([].slice.call(arguments, 1)); } aa("a", "b", "c", "d"); //['b', 'c', 'd']
- 取陣列最大最小值
var arr = [5, 2, 8, -9]; //原本要處理成 Math.max(5, 2, 8, -9),剛好可用 apply 用陣列傳遞參數的特性。 //現在也可以使用 ...展開運算子(Spread syntax),直接寫成 Math.max(...arr)。 //Math.max.apply(null, arr),第一個物件參數沒用到,隨意傳個東西, //第一個物件參數傳null、undefined,在非嚴格模式(non-strict),會被置換成global object(在瀏覽器即為window物件) console.log(Math.max.apply(null, arr)); //8
參考:
- https://www.w3school.com.cn/js/js_function_call.asp
JavaScript 函数 Call - https://www.w3school.com.cn/js/js_function_apply.asp
JavaScript 函数 Apply - https://developer.mozilla.org/zh-TW/docs/Web/JavaScript/Reference/Global_Objects/Function/call
Function.prototype.call - JavaScript | MDN - https://developer.mozilla.org/zh-TW/docs/Web/JavaScript/Reference/Global_Objects/Function/apply
Function.prototype.apply() - JavaScript | MDN - https://developer.mozilla.org/zh-TW/docs/Web/JavaScript/Reference/Global_Objects/Function/bind
Function.prototype.bind() - JavaScript | MDN - https://segmentfault.com/a/1190000011389726
call, apply, bind 函数能干啥?如何在日常搬砖中使用?(全) - SegmentFault 思否 - https://developer.mozilla.org/en-US/docs/Glossary/Global_object
Global object - MDN Web Docs Glossary: Definitions of Web-related terms | MDN
沒有留言:
張貼留言