JavaScript中的this指向问题及this指向的修改

面向对象语言中 this 表示当前对象的一个引用。

但在 JavaScript 中 this 不是固定不变的,它会随着执行环境的改变而改变。

  • 在方法中,this 表示该方法所属的对象。
  • 如果单独使用,this 表示全局对象。
  • 在函数中,this 表示全局对象。
  • 在事件中,this 表示接收事件的元素。
  • 在显式函数绑定时,我们可以自己决定this的指向
实例
var person = {
  firstName: "LeBron",
  lastName : "James",
  id       : 8888,
  fullName : function() {
    return this.firstName + " " + this.lastName;
  }
};

方法中的 this

在对象方法中, this 指向调用它所在方法的对象。

在上面一个实例中,this 表示 person 对象。

fullName 方法所属的对象就是 person。

fullName : function() {  return this.firstName + " " + this.lastName; }

单独使用 this

单独使用 this,则它指向全局对象。

在浏览器中,window 就是该全局对象为 [object Window]:

在node中,指向的是一个{}

var x = this;

函数中使用 this(默认)

在函数中,函数的所属者默认绑定到 this 上。

在浏览器中,window 就是该全局对象为 [object Window]:

在node中,指向的就是global对象

function myFunction() {  return this; }

事件中的 this

在 HTML 事件句柄中,this 指向了接收事件的 HTML 元素:

<button onclick="this.style.display='none'"> 点我后我就消失了 </button>

显式函数绑定

在 JavaScript 中函数也是对象,对象则有方法,apply 和 call 就是函数对象的方法。这两个方法异常强大,他们允许切换函数执行的上下文环境(context),即 this 绑定的对象。

在下面实例中,当我们使用 person2 作为参数来调用 person1.fullName 方法时, this 将指向 person2, 即便它是 person1 的方法:

var person1 = {
  fullName: function () {
    return this.firstName + " " + this.lastName;
  }
}
var person2 = {
  firstName: "Zach",
  lastName: "Muyi",
}
var name = person1.fullName.call(person2);  // 返回 "Zach Muyi"
console.log(name);

修改this指向

构造函数的原型prototype中,有call(), apply(), bind()方法来修改this指向。

call(执行环境对象,实参列表);

调用call方法,第一个参数就是要把b添加到哪个环境中,简单来说,this就会指向那个对象。

var Person = {
    name: "zhangsan",
    age: 19
}

function aa(x, y) {
    console.log(x + "," + y);
    console.log(this);
    console.log(this.name);

}

aa(4, 5); //this指向window--4,5  window  空

aa.call(Person, 4, 5); //this指向Person--4,5  Person{}对象  zhangsan
apply(执行环境对象,实参列表数组);

apply方法和call方法有些相似,它也可以改变this的指向,同样apply也可以有多个参数,但是不同的是,第二个参数必须是一个数组

var Person = {
    name: "zhangsan",
    age: 19
}

function aa(x, y) {
    console.log(x + "," + y);
    console.log(this);
    console.log(this.name);

}

aa.apply(Person, [4, 5]); //this指向Person--4,5  Person{}对象  zhangsan
bind(执行环境对象)(实参列表);

同样bind也可以有多个参数,并且参数可以执行的时候再次添加,但是要注意的是,参数是按照形参的顺序进行的,且bind返回一个修改this后的函数,需声明变量接收手动调用。

var obj = {
  name: 'Diana',
  sayName: function (a,b,c) {
    console.log(this.name);
    console.log(a,b,c); // 1,2,3
  }
}
var b = obj.sayName;
b.bind(obj); // 代码没有被打印,这就是bind和call、apply方法的不同,实际上bind方法返回的是一个修改过后的函数。
// 新建一个变量c来接收bind修改后的函数
var c = b.bind(obj, 1, 2);
console.log(c); // 发现c是一个[Function: bound sayName]函数
// 执行c
c(3); // Diana

总结:call和apply都是改变上下文中的this并立即执行这个函数,bind方法可以让对应的函数想什么时候调就什么时候调用,并且可以将参数在执行的时候添加,这是它们的区别,根据自己的实际情况来选择使用。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值