学习笔记=>《你不知道的JavaScript(上卷)第二部分》第一章:关于this

时间:2021-10-28 14:49:36

为什么要使用this

  通过一个例子来看看为什么要使用this:

var me = {
        name:'lebron james'
}

var you = {
        name:'杨少侠'
}

function bar(){
        return this.name;
}

function baz(){
        return '----->' + bar.call(me).toUpperCase();
}

console.log(bar.call(me));    //'lebron james'

console.log(bar.call(you));   //'杨少侠'

console.log(baz());   //'----->LEBRON JAMES'

  这段代码可以在不同的上下文对象(me和you)中重复使用函数bar和baz,不用针对每个对象编写不同版本的函数。

  如果不使用this就得显示的传递一个上下文对象给bar和baz:

function bar(context){
       return context.name;
}

function baz(context){
       return '------>' + context.name.toUpperCase();
}

console.log(bar(you));

console.log(baz(me));

  然而this提供了一种更优雅的方式来‘隐式’传递一个对象引用。

 

对this的误解:

  1,指向自身

bar.count = 0;

function bar(num){
        console.log(num);
        this.count ++;
}

for(var i=0;i<3;i++){
       bar(i);
}

console.log(bar.count);     //0

//0,1,2

  实际上bar是执行了3次的,最后打印bar.count还是为0,显然指向自身是不正确的。

  其实this.count中的this并不是执行bar这个函数对象,虽然名字相同但是其实根对象并不相同。

  (this.count ++;其实最后在全局的作用下创建了一个变量count)

  另一种解决办法使用bar标识符代替this:

bar.count = 0;

function bar(num){
     console.log(num);    //0,1,2
     bar.count ++;
}

for(var i=0;i<3;i++){
     bar(i);
}

console.log(bar.count);    //3

  这种方式完全依赖bar的词法作用域。

  另一种方式是强制this指向bar函数对象:

bar.count = 0;

function bar(num){
     console.log(num);    //0,1,2
     this.count ++;
}

for(var i=0;i<3;i++){
      bar.call(bar,i);
}

console.log(bar.count);  //3

 

  2,它的作用域,书中描述:

需要明确的是,this在任何情况下都不会指向函数的词法作用域,在JavaScript内部,作用域确实和对象类似,可见的标识符都是它的属性,但是作用域‘对象’无法通过JavaScript代码访问,它存在于JavaScript引擎内部。

每当你想要把词法作用域的查找和this混合使用时,一定要提醒自己,这是无法实现的。

 

this到底是什么:

  this是在运行的时候进行绑定的,并不是在编写的时候绑定。它的上下文取决于函数调用时的各

  种条件。this的绑定和函数声明的位置没有任何关系,只取决于函数的调用方式