深入浅出js中的this(一)

Q:this是什么?

A:this是Javascript语言的一个要害字,它象征函数运行时,自动生成的一个内对象,在每个
function 中自行根据作用域(scope) 确定, 指向的是此次调用者。

 

Q:this的采用状况?

A:  1.寻常函数调用。

  2.当靶子的道来调用。

  3.用作构造函数调用。

  4.函数深受call,apply,bind调用的上。

 

栗子:

平常函数调用

function test1(){
  console.log(this);
}
test1();   // window

在非严格模式下,由于this必须是一个靶,所以就默认为对全局对象window。在从严模式下,上面的代码则会冒出不同的结果,如下:

function test1(){
  "use strict";
  console.log(this); 
} 
test1(); // undefined

再次省下面就段代码:

function test2(){
    this.x=2;
}
test2();
console.log(window.x);   // 2

由于日常函数的调用,this的值指向window。所以实行this.x的早晚一定给行了window.x,故window.x的价值吗2。

 

作为目标的法子来调用

var message = {
  content: "I'm a message!",
  showContent: function() {
    console.log(this.content);
  }
};

message.showContent();   // I'm a message!

  上面栗子是拿函数保存也目标的性质, 这样尽管转发为一个办法,
可以经过对象调用这个办法。而当函数被算对象的不二法门来调用时, 里面的 this
值就给设置为调用方法的目标。其实,不管受调用函数在声明时是属方法,还是函数,当最后作为靶子的章程来调用时,this都是负于方的调用者,即母体对象。看看下面的栗子你不怕了解了。

var obj = {
    x: 1,
    showX: function() {
        console.log(this.x)
    }
}
obj.showX();  // 1

var obj1={x:11};
obj1.showX=obj.showX;
obj1.showX();  // 11


show=function(){
    console.log('show'+this.x);    
}

obj1.showX=show;
obj1.showX();   // show11

  上面栗子中,在obj对象被,匿名函数在声明时即便当做obj对象的一个性,this直接指向obj对象。函数show在声明时是一个大局函数,函数里面的this指于window,但当最后当目标obj1的一个性质时,其this便对了针对象obj1。但是,请小心,并无是兼具函数作为靶子的方法来调用时,this都见面对调用者,如下:

var obj = {
    x : 100,
    y : function(){
        setTimeout(
            function(){ console.log(this.x); }    
         , 1000);
    }
};

obj.y();  // undefined

地方栗子中的this指向的是window对象,并无是咱们盼望的obj,所以会弹出undefined。所以于题这类似代码时,尽量避免这种写法,当然,你吗得以于调用的当儿将及时底this所针对的对象是一个变量里,等到定时器运行时又就此所抱的变量去调用x,如下:

var obj = {
    x : 100,
    y : function(){
        var that = this;
        setTimeout(
            function(){ console.log(that.x); }
         , 1000);
    }
};

obj.y();   // 100

 

用作构造函数调用

当一个函数作为构造器使用时(通过new关键字),它的this值绑定到新创建的不得了目标。

function Message(content){
   this.content = content;
   this.showContent = function(){
       console.log(this.content);
   };
}

var message = new Message("I'm a message!");
message.showContent();   // I'm a message!

 再望下面这个栗子。

function obj(){
    this.a=666;
    return 'abc';
}

var obj=new obj();
console.log(obj);  // obj{a: 666} 

有木有看出什么?当一个含有return返回值的函数作为组织器去new一个新的目标时,return的价值是吃忽视的。是匪是很神奇!

 

函数被call,apply,bind调用的上

具有的函数都发apply()和call()这片单道。我们得透过就点儿个方式来改变函数的上下文,
在旁时刻都使得, 用来显式地设置this的价值。

apply()方法接收两单参数:
第一独凡是若安装也this的特别目标,第二独参数是可选的,如果如传播参数,则封装为数组作为apply()的老二单参数即可。

call()方法与apply()基本上是平等的,除了后面的参数ECMAScript不是频繁组,而是散落开一个一个地附加在后头。

function warrior(speed, strength){
   console.log(
      "Warrior: " + this.kind +
      ", weapon: " + this.weapon +
      ", speed: " + speed +
      ", strength: " + strength
  );
}

var warrior1 = {
   kind: "ninja",
   weapon: "shuriken"
};

var warrior2 = {
   kind: "samurai",
   weapon: "katana"
};

warrior.call(warrior1, 9, 5);   // Warrior: ninja, weapon: shuriken, speed: 9, strength: 5
warrior.apply(warrior2, [6, 10]);   // Warrior: samurai, weapon: katana, speed: 6, strength: 10

  于上头,我们通过对组织器warrior()传入不同之参数创建不同品种的目标,
this将对我们由此call() 和/或 apply()传入的对象。

  在首先只函数调用中,我们用call() 方法来以this设置也warrior1对象,
并传入需要之旁参数, 参数间用逗号分隔。在第二单函数调用中,
其实都多, 只是传播的凡warrior2对象, 并将必要参数封装为一个数组。

  除了call()和apply()以外,ECMAScript
5尚多了bind()方法,在调用一个函数或方式时为足以透过bind方法来绑定this对象。让咱们看下的板栗:

function warrior(kind){
   console.log(
      "Warrior: " + kind +
      ". Favorite weapon: " + this.weapon +
      ". Main mission: " + this.mission
   );
}

var attributes = {
   weapon: "shuriken",
   mission: "espionage"
};

var ninja = warrior.bind(attributes, "ninja");

ninja();   // Warrior: ninja. Favorite weapon: shuriken. Main mission: espionage

当斯栗子中, bind()方法的使用办法尚是相近的,
但warrior.bind()创建了一个初的函数(方法体和作用域跟warrior()一样),并从未改动原来的warrior()函数。新函数的功效以及始终的相同,
只是绑定到了attributes对象。

注:bind方法和call,apply的分在,bind()
之后函数并无实行,可以传于另外函数,在有适当的时又调用。