javascript中this详解

JS this 详解

为什么要用this

function foo(){
     console.log(`我本身属性a是   ${this.a}`)
 }
 
 var bar ={
     a:2,
     foo:foo
 }
 var baz={
     a:4,
     foo:foo
 }
 bar.foo();//我本身属性a是  2
 baz.foo()://我本身属性a是  4

foo()只定义了一次,去可以被不同的对象引用,实现了代码共享。

this的由来

javascript允许在函数体内,引用当前环境的其他变量

var fn = function(){
	console.log(x)
}

上面代码使用变量x,而变量x由当前的运行环境提供。

函数可以在不同的运行环境下执行,所以需要一种机制,可以在函数内部获取当前的运行环境(context),所以this就出现了,它的作用就是在函数体内部,指代当前的运行环境。

this的几种模式

this有以下几种情况

1.方法调用模式下,this总是指向调用它所在方法的对象,this的指向与所在方法的调用位置有关,而与方法的声明位置无关(箭头函数特殊)

2.函数调用下,this指向window,调用方法没有明确对象的时候,this指向window,如setTimeout,匿名函数等

3.构造函数调用模式下,this指向被构造的对象

4.apply、call、bind调用模式下,this指向第一个参数。

5.箭头函数,在声明的时候绑定this,而非取决于调用位置,换句话说就是指向它的上一层。

6.严格模式下,如果this没有被执行环境(execution context)定义,那this是为undefined。

方法调用模式

var fn = function(){
    console.log(this.x)
}
var x = "2"
var obj = {
    x:"1",
    fn:fn
}
//调用位置
obj.fn(); //1
//调用位置
fn(); //2

以上代码,可以看到,this指向调用它所在方法的对象,say方法在obj对象下,所以this指向obj,fn在window对象下,所以this指向window,也可以看出来this和声明位置无关,和调用位置有关。

函数调用模式

var x = "2"
//声明位置
var fn = function(){
    console.log(this.x)
}
//调用位置
fn();//2

匿名函数,setTimeout:

var that = this;
(function(){
    console.log(this === that) //true
})()
setTimeout(() => {
    console.log(this === that) //true
}, 0);

可以看出以上所有情况,this指向window

call,apply,bind模式下

var obj = {
    name: 'q1'
    getName: function(){
        console.log(this.name)
    }
}
var otherObj = {
    name:'q2'
}
var name = 'q3'
obj.getName() //q1
obj.getName().call() //q3
obj.getName().call(otherObj) //q2
obj.getName().apply() //q3
obj.getName().apply(otherObj) //q2
obj.getName().bind(this)() //q3
obj.getName().bind(otherObj)() //q2

构造函数模式下

var flag = undefined
function Fn(){
    flag = this;
}
var obj = new Fn()
console.log(flag == obj)

其实,这个this指向obj,内部原理还是用apply把this指向obj的。

严格模式

"use strict"
var fn = function(){
    return this
}
fn() == undefined; //true

可以看出,在严格模式下,fn是直接被调用的,并没有被执行环境所定义,也就是说不是作为对象的属性或方法调用的(如window.fn())

箭头函数

//声明位置
var fn = (()=>{
	console.log(this.x)
})
var x = "2"
var obj = {
    x:"1",
    fn:fn
}
//调用位置
obj.fn(); //2
//调用位置
fn(); //2

以上可以看出,箭头函数在定义时就绑定了this,而非取决于调用位置了,同样的call, apply,bind都无法更改this

var globalObject = this
var foo = (() => this)
console.log(foo() === globalObject)  // true
var obj = {foo: foo}
// 尝试用call来设定this
console.log(foo.call(obj) === globalObject) // true
// 尝试使用bind来设定this
foo = foo.bind(obj);
console.log(foo() === globalObject); //true

  • 9
    点赞
  • 7
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值