目录
1. call,apply 可以立即执行。bind不会立即执行,因为bind返回的是一个函数需要加入()执行。
2:参数不同:第一个参数都是this新的指向对象。第二个参数,apply第二个参数是数组。call和bind有多个参数就需要挨个写。
3.call使用场景(除开apply,bind才能使用的场景)
1.共同点:功能一致
可以改变函数体内的this指向。
语法:函数.call() 函数.apply() 函数.bind()
2.区别:
1. call,apply 可以立即执行。bind不会立即执行,因为bind返回的是一个函数需要加入()执行。
<script>
var str = '你好'
var obj = {str:'这是obj对象内的str'};
function fun(){
console.log(this,this.str);
}
fun();
</script>
分析:易知道,这里的this指向window,所以this.str 就是 你好。
如果通过call,apply,bind修改this指向呢?
1.通过call 修改this指向 立即执行
<script>
var str = '你好'
var obj = {str:'这是obj对象内的str'};
function fun(){
console.log(this,this.str);
}
fun.call(obj); //立即执行
fun();
</script>
结果:
分析:修改成功,若没成功,this.str结果应该是:你好
2.通过apply修改this指向 立即执行
<script>
var str = '你好'
var obj = {str:'这是obj对象内的str'};
function fun(){
console.log(this,this.str);
}
fun.apply(obj); //立即执行
fun();
</script>
结果:
3.通过bind修改this指向 不会立即执行
<script>
var str = '你好'
var obj = {str:'这是obj对象内的str'};
function fun(){
console.log(this,this.str);
}
fun.bind(obj); //没有立即执行
console.log(fun.bind(obj)); //查看返回结果是一个函数
fun();
</script>
结果:
通过加入() 执行:
<script>
var str = '你好'
var obj = {str:'这是obj对象内的str'};
function fun(){
console.log(this,this.str);
}
fun.bind(obj)();
fun();
</script>
结果:
2:参数不同:第一个参数都是this新的指向对象。第二个参数,apply第二个参数是数组。call和bind有多个参数就需要挨个写。
1.call 有多个参数就需要挨个写
<script>
var str = '你好'
var obj = {str:'这是obj对象内的str'};
function fun(name,age){
this.name = name;
this.age = age;
console.log(this,this.str);
}
fun.call(obj,'张三',99); //参数'张三'和99 传入 fun函数里面
</script>
结果:
2.bind 有多个参数就需要挨个写
<script>
var str = '你好'
var obj = {str:'这是obj对象内的str'};
function fun(name,age){
this.name = name;
this.age = age;
console.log(this,this.str);
}
fun.bind(obj,'张三',99)();
</script>
3.apply第二个参数是数组
<script>
var str = '你好'
var obj = {str:'这是obj对象内的str'};
function fun(name,age){
this.name = name;
this.age = age;
console.log(this,this.str);
}
fun.apply(obj,['张三',99]);
</script>
3.使用场景
1.apply使用场景
eg:数组 [1,36,2,7,321] ,求其最大值?
<script>
let arr = [1,36,2,7,321];
let re = Math.max.apply(null,arr);
console.log(re); //321
</script>
分析:Math.max(1,36,2,7,321)这种可以得到最大值,但是是求数组中最大值,所以可以想到apply的第二个参数要求是数组来解决。为什么这里第一个参数填null,因为Math.max这里的运用是判断数组arr的最大值,并不是需要研究this指向。
2.bind 使用场景
<body>
<h1 id="h1">ish1</h1>
<button id="btn">1111111</button>
<script>
let h1 = document.querySelector('#h1');
let btn = document.querySelector('#btn');
btn.onclick = function(){
console.log(this.id); // btn
}
</script>
</body>
分析:这里this指向的是btn,因为是给btn绑定的点击事件,但是如果想让this指向 h1,然后点击按钮,打印出h1的id的话,就需要改变this指向。
1.选择用 箭头函数
<body>
<h1 id="h1">ish1</h1>
<button id="btn">1111111</button>
<script>
let h1 = document.querySelector('#h1');
let btn = document.querySelector('#btn');
btn.onclick = ()=>{
console.log(this);//window
console.log(this.id);// undefined
}
</script>
</body>
分析:此时this指向window达不到this指向h1要求
2.用call / apply
<body>
<h1 id="h1">ish1</h1>
<button id="btn">1111111</button>
<script>
let h1 = document.querySelector('#h1');
let btn = document.querySelector('#btn');
btn.onclick = function(){
console.log(this);
console.log(this.id);
}.apply(h1);
</script>
</body>
分析:可以实现 this指向 h1,但是实现不了 点击按钮,才打印出h1的id。这里还未点击按钮就直接打印出h1的id了。
3.使用bind
<body>
<h1 id="h1">ish1</h1>
<button id="btn">1111111</button>
<script>
let h1 = document.querySelector('#h1');
let btn = document.querySelector('#btn');
btn.onclick = function(){
console.log(this);
console.log(this.id);
}.bind(h1);
</script>
</body>
分析:可以实现 this指向 h1,也实现了 点击按钮,打印出h1的id。 它这里点击按钮,就相当于时给bind返回的函数添加了(),只有点击时才执行。