HIHI,又来每週一篇惹,上礼拜的[笔记][JavaScript]认识JavaScript中的「this」大致上说明了JavaScript中的「this」,但是这个「this」是可以在呼叫function的时候用函式重新指定的,那些函式就是call()
、apply()
和bind()
,也是这次要说的主题。
首先说明call()
,他再呼叫function的时候可以使用多个参数,第一个为要为这个function指定的「this」,第二个开始会传进去该function内当作引数,例如:
//首先宣告两个物件var objA = { Name:'A',};var objB = { Name:'B', writeName:function(age){ console.log(this.Name + ' is ' + age + ' years old.'); },};//呼叫objB的function并给他参数objB.writeName(17); //会得到'B is 17 years old.'//这时候我们利用call()来呼叫objB内的function并指定他的this为objAobjB.writeName.call(objA,19); //会得到'A is 19 years old.'
当我们用call()
去呼叫objB.writeName()
时,第一个参数放进objA,代表我将「this」指定给objA,所以他的this.Name
会变成objA.Name
,而第二个参数开始,会依序传进funciton内当作引数,所以17会被objB.writeName()
的age接收,最后印出「A is 19 years old.」
再来我们用apply()
来呼叫objB.writeName()
看看,apply()
比较不同的是他只有两个参数,第一个依然是为执行的function去指定「this」,而第二个参数必须提供阵列,阵列里面每个位置的值依然会被依序传入function内当作引数,例如:
objB.writeName.apply(objA,[20]); //会得到'A is 20 years old.'
当我们用apply()
去呼叫objB.writeName()
时,第一个参数一样是指定「this」为objA,而第二个阵列中的所有项目会依序被传入function内当作引数,所以阵列中第一个值20,会被传进objB.writeName()
的age里面,最后印出最后印出「A is 20 years old.」。
最后来试看看bind()
,给他的参数内容就和使用call()
一样,第一个参数指定「this」,第二个参数开始则会依序传入被呼叫的function内当作引数,但是不一样的是bind()
他会创建一个新的函式,例如:
//把用bind创建的函式给变数func,这时候bind设定的「this」(objA)和参数(20)会同时被指定到func中var func = objB.writeName.bind(objA,22);func(); //执行后会得到'A is 22 years old.'//也可以只设定「this」不设定其他参数值,等到呼叫的时候再给var func1 = objB.writeName.bind(objA);//执行func1,并给参数值func1(24); //执行后会得到'A is 24 years old.'
当我们使用bind()
的时候,他并不会执行呼叫的函式,而是会创建一个新的函式,而你可以在bind()
的时候同时设定「this」或其他参数值给新函数。
所以用以下三种方式去改变objB.writeName()
的「this」值所得到的结果都是相同的:
//call()objB.writeName.call(objA,19);//apply()objB.writeName.apply(objA,[19]);//bind()var func = objB.writeName.bind(objA,19);func();//也可以这么写var func1 = objB.writeName.bind(objA);func1(19);//都会回传'A is 19 years old.'
以上就是这三个函式的使用方法,如果我有观念错误或解释不清楚的地方,还麻烦各位大大指点了,谢谢大家!