《你不知道的JavaScript》:this 基础

2019-08-29 14:54:48 浏览数 (1)

《你不知道的JavaScript》第二部分this和对象原型第 1 篇。

本篇来看下js中的this关键字。

刚接触this关键字的时候,一脸懵逼,看字面意思很好理解,日常英语中的this指代“这个”,有指向的意思,难道这个关键字意思也是如此?作为纯自学起来的我,在踩了那么多坑后,已然条件反射般的感觉不对劲。果不其然,在新手阶段,我是看概念懵、抄demo懵、用起来更懵,完全不知什么鬼,这个this到底指向哪?关于这个this,硬啃了好久,经常一会懂一会懵的,工作中想用还不敢用了。后来勉强算熟手了,才算慢慢用起来,边用边理解,发现果然坑还是很多,但等到确实理解后,发现也没什么可怕的。人一胆大,就是一句话了:不要怂,就是干~~

好,先从最开始看这个this

在全局作用域中,this指向全局变量;此外函数中的this关键字并不指向函数本身,以浏览器环境为例:

代码语言:javascript复制
var count = 0;
function fn(num){
    console.log("fn:"   num);
    console.log(this);      // window
    this.count  ;
}
fn.count = 0;
for(var i=0; i<5; i  ){
    fn(i);
}
console.log(fn.count);  // 0
console.log(count);     // 5
// for循环中fn函数执行5次
/*
fn:0
fn:1
fn:2
fn:3
fn:4
*/

从上例输出可以看到:

  • 函数调用时,函数体内的this并不指向自身,因为函数fn中的this打印结果指向的是全局对象window,全局对象的属性count值最后打印为5;函数fn多次调用后函数属性count值依然是0,而非如预期的5。
  • 函数体内的this不是指向函数本体,而是指向调用函数的对象。

那么针对上例,如果我想把函数中的this指向函数本身呢?可以使用js中的另一个神奇的武器:callapply来修改this指向。

代码语言:javascript复制
function fn(num){
    console.log("fn: "   num);
    console.log(this);
    this.count   ;
}
fn.count = 0;
for(var i=0; i<5; i  ){
    fn.call(fn, i);     //这里将fn函数内的this指向由指向全局对象window改为指向fn函数
}
console.log(fn.count);  // 5
console.log(count);     // ReferenceError: count is not defined

瞧,在fn函数调用时,通过call来修改fn函数内的this指向来达到递增fn函数属性count的目的。

上面两个小例子,只是this使用的起始,想用好this,先理解this的机制:

this是在运行时进行绑定的,并不是在编写时绑定的,它的上下文取决于函数调用时的条件。this的绑定和函数声明的位置没有任何关系,只取决于函数的调用方式。一句话:this其实是在函数被调用时发生的绑定,它指向什么完全取决于函数在哪里被调用。

关于上下文,很多人一直不理解或者似懂非懂,我觉得下面这段话讲的很到位:

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

0 人点赞