this的用法

在编写前端代码时会频繁的用到‘this’,所以今天就静下心来好好研究了一番,跟大家一起分享!

首先,先清楚一点,this的用武之地:

1、一般函数方法中

2、对象函数调用

3、构造函数调用

4、call、apply、bind调用


先看一般函数方法中的情况:

var name = "中国";

function getName(){

console.log(this.name)

}

getName();——结果为‘中国’;

解释:函数的赋值和定义都是在全局作用域内完成的(这里需要提前了解全局作用域是啥情况哦),而一般我们认为在浏览器环境中全局对象就是window。所以在执行getName函数时,this就是指向的window。而name又是全局变量,所以结果就为“中国”。


var name = "中国";

function getName(){

var name = "祖国”

console.log(this.name)

function getName2(){

console.log(this.name)

}

getName2()

}

getName()——结果为: 中国  中国。

解释:第一个打印可以上面的情况理解,为啥第二条打印结果也是“中国”呢?————因为getName2()也是独立调用的,调用对应是浏览器的全局对象window,所以this结果也是指向全局变量;

那那。。。怎样才能打印出我们想要的“祖国”呢?接下来继续看。。。。

(接下来这个是对象调用情况下this的指向)

var name = "中国”,

var nameObj = {

  name:"祖国”,

  getName:funtion(){

   console.log(this.name)

  }

}

nameObj.getName(); ———结果为:祖国。

解释:为啥这次就能打印出想要的结果呢?——与上面对比发现,后者的getName方法前面多了一个nameObj对象,前面加了对象,this的指向就发生了变化,就不再指向window了,而是被对象nameObj给拐了,而nameObj的作用域内name为“祖国”,所以打印出的结果就是对象中定义的name值。

那再加深一点看看。。。

var name = "中国”,

var nameObj = {

  name:"祖国”,

  newName:{

     name:"母亲",

     getNewName:function(){

      console.log(this.name)     

     }

  }

}

nameObj.newName.getNewName()——结果为 :母亲。

综合上面四个案例,可以得出结论如下:

一、如果一个函数中有this,但是它没有被上一级的对象所调用,那么this指向的就是window,但是在严格版中不是window。(简要概括就是函数独立调用都指向window)

二、如果一个函数中有this,这个函数有被上一级的对象所调用,那么this指向的就是上一级的对象。(简要概括就是函数作为一个对象被调用,那么this就指向这个对象)

三、如果一个函数中有this,这个函数中包含多个对象,尽管这个函数是被最外层的对象所调用,this指向的也只是它上一级的对象。(简要概括就是函数作为多层对象被调用,那么this就指向最近上一级对象)

另外,再说明一点:

在对象调用时使用声明函数和函数表达式的结果是不一样的;

为啥这么说呢?请看下面讲解:

还是结合上面第四个案例来看,我把函数声明形式改成函数表示式再执行:

var name = "中国”,

var nameObj = {

  name:"祖国”,

  newName:{

     name:"母亲",

     getNewName:function(){

      console.log(this.name)     

     }

  }

}

var nameNew = nameObj.newName.getNewName

 nameNew()——结果为 :中国。

这个时候是不是要怀疑人生了,this就是这么跳,让你难以驾驭。。。我也纳闷了好久。。。为啥呢为啥呢为啥呢?

解释一下吧:前面不是说过声明函数的声明和赋值都是在全局作用域内完成的嘛,匿名函数也一样,所以匿名函数的指向也是指向window的。而函数表达式是将函数传给一个变量,如果后面没有加括号那么就只是传递了一个函数(这里是匿名函数),而不是执行结果。即就是只将匿名函数的内存地址传给了变量,而这个匿名函数是指向window的,所以结果就是全局变量name的值。

感觉真的快要被this搞晕了。。。。

其实this都是指向的实例化对象,而全局作用域中的实例化对象都是window,所以那么多this都指向window其实都是因为只做了一次实例化,所以想改变this的指向就进行实例化。。

怎样实例化呢?一个关键字new就能解决;

那么接下来就看一看,this在构造函数中的使用情况:

function Person() {
this.name = '小米';
this.age = '5';
this.getPerson = function () {
console.log(this.name + '今年' +this.age + '岁')
}
}
var p1 = new Person();
p1.getPerson();——————————结果为:小米今年5岁
由此可见上面构造函数中的this指向的是对象p1。
解释:p1是创建了Person的实例对象,就相当于复制了一份Person到p1对象里面,此时是创建了一个新的对象,后面对象调用getPerson函数,根据上面的总结this指向上一级调用对象,所以this就指向了
person的复制版本中,因为Person中给name和age都赋值了,所以能够获取到结果。

再加一点说明:javascript中构造函数是不需要有返回值的,可以认为构造函数和普通函数之间的区别就是:构造函数没有 return 语句,普通函数可以有 return 语句;


最后来看看call、apply和bind中的调用:
 var x =0;
function test() {
console.log(this.x);
};
var ceshi = {
x:99
}
test.apply(); ——————————结果为0;
test.apply(ceshi); ——————————结果为99;
解释一下:call、apply、bind三者的第一个参数都是this要指向的对象;而第一种情况apply()里面对象是空就默认指向window,所以结果为0,
如果加了对象ceshi那this就指向了ceshi对象,所以结果为99;


好了,this的用法就先总结到这吧,如果我的解释不够清晰,推荐两个链接再学习下:https://blog.csdn.net/u012244479/article/details/79579984和https://www.cnblogs.com/sspeng/p/6633204.html

有什么不对的地方欢迎大家批评指正~~~~~



 
原文地址:https://www.cnblogs.com/jennydtt/p/9829087.html