eg1:
var name = '小王', age = 17;
var obj = {
name: '小张',
objAge: this.age,
myFun: function(){
console.log(this.name+"年龄"+this.age)
}
}
obj.objAge; // 17
obj.myFun() ; // 小张年龄 undefined
eg2:
var fav = ‘啦啦’
function shows(){
console.log(this.fav);
}
shows(); // 啦啦
第一个打印里面的 this 指向 obj,第二个全局声明的 shows() 函数 this 是 window;
1. call()、apply()、bind()都是用来重新定义this这个对象的。
var name = '小王', age = 17;
var obj = {
name: '小张',
objAge: this.age,
myFun: function() {
console.log(this.name+"年龄"+this.age)
}
}
var db = {
name:'德玛',
age: 99,
}
obj.myFun.call(db); // 德玛年龄 99
obj.myFun.apply(db); // 德玛年龄 99
obj.myFun.bind(db)(); // 德玛年龄 99
2. 区别 :对比call()、bind()、apply()的传参
var name = '小王', age = 17;
var obj = {
name: '小张',
objAge: this.age,
myFun: function(from,to) {
console.log(this.name+"年龄"+this.age,"来自"+ from + "去往"+ to)
}
}
var db = {
name:'德玛',
age: 99,
}
obj.myFun.call(db,'成都','上海'); // 德玛年龄 99 来自成都去往上海
obj.myFun.apply(db,['成都','上海']); // 德玛年龄 99 来自成都去往上海
obj.myFun.bind(db,'成都','上海')(); // 德玛年龄 99 来自成都去往上海
obj.myFun.bind(db,['成都','上海'])(); // 德玛年龄 99 来自成都,去往 undefined
· call( ) 是接收一个及其以上的参数,第一个参数表示this要指向的对象,其余参数表示调用函数需要传入的参数,返回调用函数的返回结果,属于立即执行函数;
· apply( ) 是接收两个参数,第一个参数表示this要指向的对象,第二参数表示调用函数需要传入的参数所组成的数组,返回调用函数的返回结果,属于立即执行函数;
· bind( ) 是接收一个及其以上的参数,和call()一致,但是其返回是一个函数,而不是调用函数的返回结果;
当然,三者的参数不限定是 string 类型,允许是各种类型,包括函数 、 object 等等!
3. 作用
在js中,所有的函数在被调用的时候都会默认传入两个参数,一个是this,还有一个是arguments。在默认情况下this都是指当前的调用函数的对象。但是有时候我们需要改变this的指向,也就是说使函数可以被其他对象来调用,那么我们应该怎样做呢?这时候我们就可以使用call,apply和bind方法了。
在面向对象的JS中,我们了解到在JS中,一切都是对象。因为一切都是对象,我们开始明白我们可以为函数设置和访问其他属性。而this提供了一种更优雅的方式隐式“传递”一个对象的引用。
关于this,我们常见的误区:认为this指向函数本身
function f1() {
console.log(this)
}
f1() // window
函数的调用方式决定了this的值。它指向什么完全取决于函数在哪里被调用,也就是说,谁调用,谁负责。而bind()、apply()、call()则是可以更改this指向的方法。请看下面例子:
var a = {
user:"bahg",
fn:function(){
console.log(this.user);
}
}
var b = a.fn;
b(); //undefined
我们是想打印对象a里面的user却打印出来undefined是怎么回事呢?因为b()相当于window.b(),this指向window,如果我们直接执行a.fn()是可以的:
var a = {
user:"bahg",
fn:function(){
console.log(this.user);
}
}
a.fn(); //bahg
这里能够打印是因为,这里的this指向的是函数a,那为什么上面的不指向a?我们如果需要了解this的指向问题,请看 this指向问题_93 Million Miles-的博客-CSDN博客https://blog.csdn.net/m0_52545254/article/details/125758510?spm=1001.2014.3001.5501这篇文章。
虽然这种方法可以达到我们的目的,但是有时候我们不得不将这个对象保存到另外的一个变量中,那么就可以通过call、apply、bind方法。
4. 使用
(1). call
var a = {
user:"bahg",
fn:function(){
console.log(this.user);
}
}
var b = a.fn;
b.call(a); // bahg
此时打印的就不再是undefined了,通过call方法使得b的this指向a对象,而不是window。call方法除了第一个参数以外还可以添加多个参数,这些参数会传入函数,如下:
var a = {
user:"bahg",
fn:function(a,b){
console.log(this.user); //bahg
console.log(a+b); //3
}
}
var b = a.fn;
b.call(a,1,2);
(2). apply
apply方法和call方法有些相似,它也可以改变this的指向。区别在于传递多个参数时必须使用数组,如下:
var a = {
user:"bahg",
fn:function(a,b){
console.log(this.user); /bahg
console.log(a+b); //11
}
}
var b = a.fn;
b.apply(a,[10,1]);
注意:如果call和apply的第一个参数写的是null,那么this指向的是window对象
(3). bind
var a = {
user:"bahg",
fn:function(a,b,c){
console.log(this.user); //bahg
console.log(a,b,c); //10 1 2
}
}
var b = a.fn;
// b.bind(a); 不会输出任何结果
// var c = b.bind(a);
// console.log(c); 输出 function() { [native code] }
// var c = b.bind(a,10,1,2);
// c(); // 输出结果
bind方法可以让对应的函数想什么时候调就什么时候调用,并且可以将参数在执行的时候添加,这是它们的区别,可以根据自己的实际情况来选择使用。
-------------------------------------------------------------------------------------------------------------------------------
部分内容转载于JS中call()和apply()以及bind()的使用及区别 - BAHG - 博客园