学习this关键字(一)

this关键字是JavaScript中最复杂的机制之一。以至于我使用多年也很难说清它到底指向什么,我们有必要好好学习一下。this也是我们学习和使用JavaScript中的一座大山,我们必须翻过这座山。

为什么要使用this

先看一段代码如下:

var foo = {
    name:'tom',
    age:'24',
    say:function(){
        console.log('name: ' + this.name + ', age: ' + this.age);
    }
}
foo.say(); //name: tom, age: 24
var bar = {
    name:'cat',
    age:'25'
}
foo.say.call(bar); //name: cat, age: 25
复制代码

这段代码在不同的上下文对象(foobar)中重复使用了函数say(),不用写不同版本的函数。如果不使用this那么就需要给函数say()显示传入一个上下文对象。

 say:function(context){
        console.log('name: ' + context.name + ', age: ' + context.age);
    }
复制代码

this隐式的传递了一个对象的引用,因为我们可以将通用模块和API方法设计的更加易用和简洁。

什么是this

this指向函数自身

在开始工作的时候很容易把this理解成指向函数自身,不过我们现在来分析下,this是不是指向函数自身。思考下面一段代码:

function foo(){
    this.name = 'tom';
}
foo.name = 'cat';
foo();
console.log(foo.name); //'cat'
复制代码

最终打印的是cat,显然this不是指向函数自身。执行foo.name=cat,是向对象foo添加一个name属性,但是函数内部代码this.name中的this并不是指向那个函数对象。

遇到这样的问题,我们会采用其他的方式来达到目的,比如创建另一个带有name属性的对象。

function foo(){
    obj.name = 'tom';
}
var obj = {
    name:'cat'
}
foo();
console.log(obj.name); //'tom'
复制代码

虽然这种方式确实解决了问题,其使用的是另一种我们比较熟悉的技术词法作用域,并没有使用this解决。

另一种方法是强制this指向foo函数对象。

function foo(){
    this.name = 'tom';
}
foo.name = 'cat';
foo.call(foo);
console.log(foo.name);//'tom'
复制代码

这次我们没有回避this,而且使用call()来帮助我们使用this

this指向它的作用域

this的另一个误区就是,指向函数的作用域。这个问题有点复杂,因为在某种情况下它是正确的,但是在其他情况下它却是错误的。需要说明的是,this在任何情况下都不指向函数的词法作用域。

javaScript中,作用域确实和对象类似,可见的标识符都是它的属性。但是作用域“对象”无法通过 javaScript代码访问,它存在于javaScript引擎内部。(详细的可以参考之前的文章)

思考下面一段代码:

function foo() { 
    var a = 1;  
    this.bar(); 
}
function bar() { 
    console.log(this.a);
}
foo(); //undefined
复制代码

这段代码看起来像是故意为之,但实则反映出对this的不了解。调用bar()最常用的方法是省略前面的this,直接使用词法引用标识符。这段代码还试图通过thisfoo()函数中联动bar()函数访问变量a。这也是不可能的,不能使用this来引用一个词法作用域内部的变量及函数。

this到底是什么

this是在运行时进行绑定的,并不是在编写时绑定,它的上下文取决于函数调用时的各种条件。this 的绑定和函数声明的位置没有任何关系,只取决于函数的调用方式。

当一个函数被调用时,会创建一个执行环境(也叫执行上下文)。执行环境中的活动对象会包含函数在哪里被调用(调用栈)、函数的调用方法、传入的参数等信息。this就是记录的其中一个属性,会在函数执行的过程中用到。(详细的可以参考之前的文章)

总结

this 实际上是在函数被调用时发生的绑定,它指向什么完全取决于函数在哪里被调用。

参考

转载于:https://juejin.im/post/5ce0e6ff51882525d55d2d7d

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值