this到底是谁

this的不同指向

this总是指向函数的直接调用者(而非间接调用者)
如果有new关键字,this指向new出来的那个对象
在事件中,this指向触发这个事件的对象,特殊的是,IE中的attachEvent中的this总是指向全局对象window
this关键字是一个非常重要的语法点。记住一点:this不管在什么地方使用,它永远指向一个对象。
下面是一个例子:

var person = {
    name: '张三',
    describe: function(){
        console.log('姓名: ' + this.name)
    }
}
person.describe()

上面代码中,this.name表示name属性所在的那个对象。this.name是在describe方法中调用的,而describe方法所在的当前对象是person,因此this.name指向person,this.name就是person.name。

由于对象的属性可以赋给另一个对象,所以属性所在的当前对象是可以改变的,所以this的指向也是可变的。

var A = {
    name: '张三',
    describe: function(){
        console.log('姓名: ' + this.name)
    }
}

var B = {
    name: '李四'
}

B.describe() = A.describe
B.describe()
// '姓名:李四'

上面代码,A.describe属性被赋值给B,于是B.describe()就表示describe方法所在的当前对象B,所以this.name就指向B.name

重构这个例子,this的指向就能看得更清楚

function f(){
    console.log('姓名:' + this.name)
}

var A = {
    name: '张三',
    describe: f
};

var B = {
    name: '李四',
    describe: f
};

A.describe() //姓名:张三
B.describe() //姓名:李四

上面代码中,函数f内部使用了this关键字,随着函数f所在的对象不同,this的指向也不同。

只要函数被赋给另一个变量,this`的指向就会发生改变。

var A = {
  name: '张三',
  describe: function () {
    console.log('姓名:'+ this.name);
  }
};

var name = '李四';
var f = A.describe;
f() // "姓名:李四"

上面代码中,`A.describe`被赋值给变量`f`,的内部`this`就会指向`f`运行时所在的对象。

JavaScript语言之中,一切皆对象,运行环境也是对象,所以函数都是在某个对象下运行的,`this`就是函数运行时所在的对象。

 this使用场合

(1)全局环境

全局环境使用this,它指的就是顶层对象window。

this === window //true

function f(){
    console.log(this === window)
}
f() //true

 (2)构造函数

 构造函数中的this,指的是实例对象

function F(){
    this.hello = function(){
        console.log('Hello'+this.name)
    }
}
var f1 = new F()
f1.name = '张三'
f1.hello()

var f2 = new F()
f2.name = '刘能'
f2.hello();

(3)对象的方法

方法在哪个对象下,this就指向哪个对象

var o1 = {
    s1: '123',
    f1:function(){
        console.log(this.s1)
    }
}

var o2 = {
    s1: '456',
    f1:o1.f1
}

o2.f1()

JavaScript提供了call,apply,bind这三个方法,来切换/固定`this`的指向。

call()方法、apply()方法、bind()方法

(1)call()方法

var lisi = {names: 'lisi'};
var zs = {names: 'zhangsan'};
function f(age){
    console.log(this.names)
    console.log(age)
}
f(23); // undefined
f.call(zs, 32); // zhangsan

call方法使用的语法规则

函数名称.call(obj,arg1,arg2...argN);

参数说明:

obj:函数内this要指向的对象,

arg1,arg2...argN :参数列表,参数与参数之间使用一个逗号隔开

(2)apply()方法

var lisi = {name:'lisi'}; 
var zs = {name:'zhangsan'}; 
function f(age,sex){
	console.log(this.name+age+sex); 
}
f.apply(zs,[23,'nan']);

函数名称.apply(obj,[arg1,arg2...,argN])

参数说明:

obj :this要指向的对象

[arg1,arg2...argN] : 参数列表,但是要求格式为数组

(3)bind()方法

bind方法用于将函数体内的this绑定到具体的某个对象上

this.x = 9; 
var module = {
  x: 81,
  getX: function() { return this.x; }
};

module.getX(); // 返回 81

var retrieveX = module.getX;
retrieveX(); // 返回 9, 在这种情况下,"this"指向全局作用域

// 创建一个新函数,将"this"绑定到module对象
// 新手可能会被全局的x变量和module里的属性x所迷惑
var boundGetX = retrieveX.bind(module);
boundGetX(); // 返回 81

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值