call
- 浏览器在执行点击事件时,默认点击事件函数的call参数为,引发点击事件的元素(button,div)
function f(){
console.log(this)
console.log(arguments)
}
f.call() // window
f.call({name:'frank'}) // {name: 'frank'}, []
f.call({name:'frank'},1) // {name: 'frank'}, [1]
f.call({name:'frank'},1,2) // {name: 'frank'}, [1,2]
fn.call()发生了三件事
- call stack发生了入栈
- this被传递
- arguments被传递
this
- this的创造意图是让某个字段/函数与某个对象相关联
- 在函数声明的时候我们并不知道this是谁,只知道this使该函数与某个对象相关联
- this是fn.call()的第一个参数
实例
var person = {
name: 'frank',
sayHi: function(person){
console.log( this.name)
}
}
person.sayHi()//等效于person.sayHi.call(person)
person.sayHi.call({name:'Lisi'})
//Lisi,注意'person.'只是用于访问到sayHi所必需的一个前缀,当call无参数时,浏览器默认person为与sayHi相关联的对象
var fn=person.sayHi
fn.call(person)//frank
fn.call()//undefined
window.name='xxx'
fn.call()//等效于fn.call(window)
call与apply
- 当你不确定参数(arguments)的个数时,就使用 apply
function sum()
{
var m=0
for(var i=0;i<arguments.length;i++)
{
m+=arguments[i]
}
console.log(m)
}
var arr=[1,2,3,4.......100]
sum.call(undefined,arr[0],arr[1],arr[2].....arr[99])
//等效于sum.apply(undefined,arr)
bind与call
- bind与call等效
this.num = 9;
var module = {
num: 81
};
function getNum(n,m)
{
console.log(this.num+n+m)
}
//下列四种写法等效
getNum.call(module,1,2)//84
getNum.bind(module)(1,2)//84
getNum.bind(module).call(module,1,2)//84
getNum.bind.call(getNum,module)(1,2)//84
bind的演变史
<html lang="en">
......
<body>
<div id="div1">123</div>
</body>
</html>
<script>
var module={
name:'Lier',
age:8
}
var fn=function()
{
console.log(this.name)
}
/*设置点击事件*/
</script>
假如我们想给div1设置监听事件,使得点击div1后控制台打印出"Lier",该如何实现?
我们可以这样写
document.getElementById('div1').onclick=function fm()
{
fn.call(module)
}
js之父不喜欢fm这个函数,于是他用bind符号制定了一个等价规则以省略fm
fn.bind(module)=function fm()
{
fn.call(module)
}
现在我们可以这么写
document.getElementById('div1').onclick=fn.bind(module)
网友评论