js thiskeyword

相信大家都接触过this了,那么 this究竟是什么意思呢?看其字面意思就是个代词。指代其它的一些东西。

那么我们在程序其中,事实上也是一样。this也是个代词。

比方我们在java其中,this的keyword是指代当前class 的本身。不管this身处何处,this都指向当前class,它的作用域是作用域整个class的。

只是我们今天不是讲后台。我们的重点是讲js。那么js中的thiskeyword的作用域是怎么样的呢?和java有什么差别呢?

1,第一种情况

var person= function(){

       this.name = "spring";

       this.age = 25;

      alert(this); //output: window

}

这段代码的thiskeyword指向的是全局window对象.



2,另外一种情况

var person= function(){
       this.name = "spring";
       this.age = 25;
       console.log(this); //output: person本身
}

new person(); //解释:实例化this指代person对象

那么如上所看到的,实例化该person对象之后。this指向的是当前person的本身。


3。第三种情况

var person = {

name:"spring",

       age: 25,

       eat: function(){

                alert(this.name+"正在吃饭"); //output: spring 正在吃饭

      }

}

person.eat();//解释:this指代当前person对象


4。第四种情况:

var person = {
              name:"spring",

              age: 25,

              sex:{
                     male:"男",

                     getMale: function(){
                               console.log(this); //output:  sex object
                       }
             }

};

person.sex.getMale(); //解释:this指代sex object



------------------------------------------------------------------------------------------------------------

好了写到这里。各位看明确了没有?请注意红色部分字体。

new person(); //this指代person对象


person.eat();//this指代当前person对象


person.sex.getMale(); //this指代sex对象


依据这个规律,我们能够得出一个结论:

           谁调用的this就指代谁。


5,第五种情况:回调函数

function test(){
         var person = {
                name:"spring",
                age: 25,
                 getAge: function(callback){

                          console.log(this); //output: person object
                          callback(this.age); 
                }
          }

         alert(this); //output: test object
         person.getAge(function(age){
                  alert(age);//output: 25

                  //xxx
                  alert(this);//output: window object
        });
}
new test();

注意看上面回调函数里面的this(// xxx以下那一行),却指向了window全局对象,哎。

怎么是这样。为什么不是person对象呢?为什么不是test对象呢?

那么按照我们上面的结论,谁调用指向谁。那么我们看是谁调用的?

噢,找到了,声明了一个匿名函数当做參数传递给了getAge(callback)方法。然后运行了callback(this.age); 

那么我们又想一下,这个匿名函数又是谁呢?好像谁都不属于,那么该匿名函数就是指向window对象啦。

soga,原来是这样。似乎有点点懂了。

结论:回调函数的时候,this的上下文发生了变化,也就是this的指针发生了变化。

只是我们一般会这样做:

         alert(this); //output: test object

         var self = this; //self 保存this作用域
         person.getAge(function(age){
                  alert(age);//output: 25

                  alert(this);//output: window object

                  alert(self);//output: test object;
        });


噢。原来这样用self变量去储存当前this(也就是test)对象。


6.第六种情况prototype

//编写一个string的insert method

String.prototype.insert = function(){
            console.log(this);  //output > String {0"1"1"2"2"3"3"4"4"5"5"6"length6insertfunction}

                                             //这里this代表的是String.prototype > object对象
            console.log(this.toString()); //output string "123456"
}


test();
function test(){
            var str = "123456";
            str.insert(); //调用insert method

}


然后我们再看另外一段代码:

function Person(name){

       console.log(this);//output > Person

       this.name = name;

}

Person.prototype.getName = function(){

       console.log(this);//output > Person

       return this.name;

};

var person = new Person("spring"); //实例化this代表自身

person.getName(); // output > spring


上面这种写法等同于以下这种写法:

function Person(name){

       this.name = name;

}

Person.prototype = {

       getName: function(){

              console.log(this);//output > Person

              return this.name;

       }

};



7.第七种情况call、apply

function base(){
            this.add = function(){
                console.log(this);//output > test {add: function}  ,this指针发生了变化
            }

}
function test(){
          console.log(this);//output > test {}
          base.call(this);   //call方法会把这个base中的this对象用这个this(也就是test对象)取代,

                                         //取代之后,自然base对象中的this.add 方法就变成了test的方法属性了

          //call方法把别人的东西变成自己的。 other.call(yourself)。yourself对象会取代other中的this对象

          console.log(this) //output > test {add: function}
}
var result = new test();
console.log(result);//output > test {add: function}
result.add();//调用,调用之后,发现this的指针发生了变化。

this不再是base对象而是变成了test对象了。


call带參数的情况:

function base(d1,d2){
            alert(d1+d2); //output > 123456
            this.add = function(){
                console.log(this);//output > test {add: function}

            }
}
function test(){
            base.call(this,"123","456");//多个參数用逗号隔开:"123","456","789"……
}
var result = new test();



apply method:

call 和apply的差别就是參数类型不同

function base(d1,d2){ //非常惊奇的发现,本来传给我的參数是一个数组呀。按道理来说我应该接收的是一个数组嘛,但是却被拆分成两个对象。


            alert(d1+d2); //output > 123456
            this.add = function(){
                console.log(this);//output > test {add: function}
            } 

}
function test(){
            base.apply(this,["123","456"]); //參数是数组:["123","456","789"……]
}
var result = new test();


改动下变成:

function base(d1,d2){
            alert(d1+d2);//output > 123456
            this.add = function(data){
                alert(data);//output > ADD
            }

}
function test(){

}
var result = new test();
base.apply(result,["123","456"]);
result.add("ADD")
















原文地址:https://www.cnblogs.com/tlnshuju/p/6893710.html