首页 > 其他 > 详细

this 指向

时间:2019-12-03 17:25:12      阅读:65      评论:0      收藏:0      [点我收藏+]

js中函数的几种调用方式:

  · 普通函数调用

  · 作为方法来调用

  · 作为构造函数来调用

  · 使用apply / call 方法来调用

  · Function.prototype.bind方法

  · ES6 箭头函数

不管函数是按哪种方法来调用,谁调用这个函数或方法,this关键字就指向谁。

· 普通函数调用:

eg①:

function person(){
     this.name="xl";
     console.log(this);    
     console.log(this.name);
}
person(); // output => window xl

  【解析】: 在这段代码中person函数作为普通函数调用,实际上person是作为全局对象window的一个方法来进行调用的,即 window.person();

  所以这个window对象调用了person方法,那么person函数当中的this即指window,同时window还拥有用另外一个属性name,值为xl。

 

eg②:

var name="xl";
function person(){
      console.log(this.name);
}
person(); // output => xl

  【解析】: 这里的person作为window的方法来调用。在代码的开始定义了一个全局变量name,值为xl。它相当于window的一个属性,即:window.name = “xl”,在调用person的时候this指向window。因此这里会输出xl。

 

· 作为方法来调用

eg①:

var name="XL";
var person = {
  name: "xl",
  showName: function(){
    console.log(this.name)
  }
}
person.showName(); // output => xl

 

  【解析】: person对象调用showName方法,很显然this关键字是指向person对象的,所以会输出xl。

 

eg②:

var name="XL";
var person = {
  name: "xl",
  showName: function(){
    console.log(this.name)
  }
}
var showNameA = person.showName;
showNameA(); // output => XL

 

 

  【解析】:这里将person.showName方法赋予showNameA变量。此时showNameA变量相当于window对象的一个属性。因此showName()执行的时候相当window.showNameA(),即window对象调用showNameA这个方法,所以this关键字指向window。

 

eg③:

 

var personA = {
     name: "xl",
     showName: function() {
         console.log(this.name);
     }
}
var personB = {
     name: "XL",
     sayName: personA.showName
}
personB.sayName(); // output => XL

 

  【解析】:虽然showName方法是在personA这个对象中定义,但是调用的时候却是在personB这个对象调用,因此this对象指向personB。

 

  

· 作为构造函数来调用

 

function Person(name){
    this.name=name;
}
var personA = Person("xl");  
console.log(personA.name);  // output => undefined
console.log(window.name);  // output => xl

 

  【解析】:上述代码没有进行new操作(没有实例化,相当于这个函数给了一个全局变量),相当于window对象调用Person(‘xl‘)方法。那么,并进行赋值操作window.name=“xl”。

 

· 使用apply / call 方法来调用

在js里函数也是对象,因此函数也有方法。从Function.proytotype上继承到Function.prototype.call/Function.prototype.apply方法。

call/apply方法最大的作用就是能改变this关键字的指向。

Obj.method.apply(AnotherObj, arguments);

 

var name = "WL";
var Person = {
         name: "xl",
         showName: function() {
               console.log(this.name);
         }
    }
Person.showName.call(); 

 

// call 方法后面的括号中的替换对象如果为空指代就是“window”。

  【解析】:这个call方法里面的第一个参数为空,默认指向window。

  虽然showName方法定义在Person对象里面,但是使用call方法后,将showName方法里面的this指向window。因此会输出“WL”。

当showName方法给到了window后,肯定是window执行这个方法,所以this的指向就是window。

 

 

· Function.prototype.bind()

var name="XL";
function Person(name){
      this.name=name;
      this.sayName=function(){
           setTimeout(function(){
               console.log("my name is "+this.name);
           },50)
       }
}
var person=new Person("xl");
person.sayName();  

  【解析】:这里的setTimeout()定时函数,相当于window.setTimeout(),由window这个全局对象调用。因此this指向为window,则this.name则为XL。

  setTimeout() 的默认指向是window。

怎样才能输出"my name is xl"呢?

 

var name="XL";
function Person(name){
      this.name=name;
      this.sayName=function(){
           setTimeout(function(){
               console.log("my name is "+this.name);
           }.bind(this),50) 
       }
}
var person=new Person("xl");
person.sayName();  // output => "my name is xl"

 

  【解析】:这里setTimeout函数,匿名函数使用bind(this)方法后创建了新的函数,这个新的函数不管在什么地方执行,this都指向Person,而非window,因此最后的输出都为“my name is xl”,而不是“my name is WL”。

  setTimeout()/ setInterval() / 匿名函数 执行的时候,this默认指向window。除非手动改变this的指向。【因为bind绑定了person函数,所以不管在哪儿引用这个方法,this的指向都是person。

 

 

怎样才能输出"my name is WL"?

 

var name = "WL";
function Person() {
       this.name = "xl";
       this.showName = function () {
   ·         console.log(this.name);
      }
      setTimeout(this.showName, 50);
 }
var person = new Person(); 

 

另一种输出"my name is xl"?

function Person() {
  this.name = "xl";
  var that = this;
  this.showName = function () {
    console.log(that.name);
  }
  setTimeout(this.showName, 50)
}
var person = new Person(); 

· ES6 箭头函数

 

        var x = 11;
        var obb = {
            x: 222,
            y: {
                x:333,
                obc: function f() {
                    console.log(this)
                    var x = 111;
                    var obj = {
                        x: 22,
                        say: () => {
                            console.log(this.x);
                        }
                    }
                    obj.say()
                }
            }
        }
        obb.y.obc()

 

  【解析】:输出结果是333。

        原因箭头函数没有this,剪头函数的this是继承父执行上下文里面的this ,这里箭头函数的执行上下文是函数f(),所以它就继承了f()的this,

 

this 指向

原文:https://www.cnblogs.com/Shouxi/p/11977873.html

(0)
(0)
   
举报
评论 一句话评论(0
关于我们 - 联系我们 - 留言反馈 - 联系我们:wmxa8@hotmail.com
© 2014 bubuko.com 版权所有
打开技术之扣,分享程序人生!