资讯专栏INFORMATION COLUMN

JS中this的指向问题

shery / 3392人阅读

摘要:前几天在牛客网上做题,遇到一道关于指向的问题,以前就对一知半解的我瞬间懵逼,下面我们来看看这道题,顺便讲解一下中的指向问题。这个时候中的就指向临时调用它的对象了,自然得到的就是大白。

前几天在牛客网上做题,遇到一道关于this指向的问题,以前就对this一知半解的我瞬间懵逼,下面我们来看看这道题,顺便讲解一下js中this的指向问题。

题目:填写内容让下面代码支持a.name = “name1”; b.name = “name2”;

function obj(name){
    _______
}
obj._____ = "name2";
var a = obj("name1");
var b = new obj;

在做这道题之前,我们先来学习一下this的知识。首先我们必须要明白的是,在javascript中this的指向是在函数被调用时才能确定的,在定义时是不能够确定的this指向的,准确一点说this最终指向的是调用它的对象。下面我们举例说明:

1.作为多带带的函数被调用
1    var name = "小黑";    // 全局变量name
2    function Func() {
3        var name = "大白";    // 局部变量name
    
4        console.log(this);
5        console.log(this.name);
6    }

8    Func();

9    console.log(window.Func() === Func())    //true

上面的代码中,当我们调用Func()函数时,实际上Func()是作为window对象的方法被调用的(第9行代码可以可以验证),因此this指向的就是全局对象window,第4行代码打印出来的也就是window,第5行代码打印出来的自然也就是全局变量name(所有的全局变量都作为window的属性)。

2.作为对象的方法被调用

还是先看下面的示例代码:

1    var Obj = {
2       name: "大白",
3        getName: function() {
4            console.log(this.name)
5        }
6    }

7    Obj.getName();           // 大白
8    window.Obj.getName();    // 大白

这段代码中getName()作为对象Obj的方法被Obj调用,因此这个时候this指向的便是Obj对象,自然this.name得到的就是"大白"。那么在第8行代码中window调用了getName()为什么不是指向window呢?因为window实际上是通过调用Obj间接调用getName()的,所以this还是指向直接调用它的Obj。

3.作为构造函数被调用
function Func() {
    this.name = "大白";
}

var fn = new Func();
console.log(fn.name)    // 大白

当我们通过new关键字构造一个实例对象的过程中,构造函数中的this一般情况下指向我们构造出来的实例化对象(特殊情况后面有多带带讲解),因此在构造过程中this.name = "大白"这句代码就相当于给实例对象fn创建了一个name属性并赋值"大白"。

使用apply()/call()改变this的指向
1    function getName() {
2        console.log(this.name);
3    }

4    var Obj = {
5        name: "大白"
6    }

7    getName.apply(Obj);    // 大白
8    console.log(Obj);    //{ name: "大白" }

这里用到了apply()方法改变this的指向(不知道apply()用法的自行百度),第7行代码中我们可以理解成将getName()函数临时绑定在Obj对象上作为Obj对象的方法,同时调用这个方法。这个时候getName()中的this就指向临时调用它的Obj对象了,自然this.name得到的就是"大白"。注意这里并没有改变Obj对象,如第8行代码所示。

最后要解决前面留下的题,我们还需要讲个知识点:当构造函数中的this遇到return时的情况。

//示例1
function Fn1() {
    this.name = "大白";
    return { name: "小黑" };    // 返回一个空对象
}
var fn1 = new Fn1();
console.log(fn1.name);    // 小黑

//示例2
function Fn2() {
    this.name = "大白";
    return true;    // 返回true
}
var fn2 = new Fn2();
console.log(fn2.name);    // 大白

你可能会奇怪,一模一样的代码为什么得到的值不一样呢? 注意!这里两段代码是区别的,示例1中函数返回值是一个对象,示例2中的返回值是true,当构造函数中返回值是一个对象时,this指向的就是返回的那个对象,如果返回值不是对象时,返回值指向的就是构造函数的示例对象,因此实例1中的this.name得到的是小黑而不是大白。

现在我们就可以来做上面的题了:填写内容让下面代码支持a.name = “name1”; b.name = “name2”;

     //创建全局函数
1    function obj(name){
2         if(name) {        // 区分普通调用和实例化调用
            this.name = name;
          }
          return this;    // 返回this引用,调用时this指向window
3    }

4    obj.prototype.name = "name2";    // 设置原型对象
5    var a = obj("name1");    //直接调用函数,a等于window,name为window的属性。
6    var b = new obj;    //调用函数实例化对象,this指向obj的实例化对象。

上面第4行代码涉及到对象原型的知识,如果对这方面还有疑问的可以看看我总结的另一篇文章:javaScript原型及原型链详解(一)

以上内容都是我个人的理解,难免会有理解不到位的地方,希望各位不吝赐教!大家一起进步。

文章版权归作者所有,未经允许请勿转载,若此文章存在违规行为,您可以联系管理员删除。

转载请注明本文地址:https://www.ucloud.cn/yun/83104.html

相关文章

  • JS this指向

    摘要:当碰到时呵呵再看一个呵呵再来呵呵呵呵呵呵呵呵什么意思呢如果返回值是一个对象,那么指向的是构造函数的实例但是并没有被返回,如果返回值不是一个对象那么还是指向构造函数创建的实例。 为什么要学习this?如果你学过面向对象编程,那你肯定知道干什么用的,如果你没有学过,那么暂时可以不用看这篇文章,当然如果你有兴趣也可以看看,毕竟这是js中必须要掌握的东西。 1. this指向调用他的对象 首先...

    KavenFan 评论0 收藏0
  • 总结jsthis指向问题

    摘要:下面只探讨在浏览器中的指向,有兴趣的也可以把后面的例子在中跑一下。 我们知道js中有个全局对象就是window,如果在顶层声明一个变量如 var a=1 //就相当于window.a=1 同时有了node以后,js也可以在服务端运行了,官方解释为Node.js 是一个基于 Chrome V8 引擎的 JavaScript 运行环境。通俗说node是一个支持js语法的容器,直接写js就可...

    lieeps 评论0 收藏0
  • js继承从入门到理解

    摘要:问题修改实例的,即修改了构造函数的原型对象的共享属性到此处,涉及到的内容大家可以再回头捋一遍,理解了就会觉得醍醐灌顶。 开场白 大三下学期结束时候,一个人跑到帝都来参加各厂的面试,免不了的面试过程中经常被问到的问题就是JS中如何实现继承,当时的自己也是背熟了实现继承的各种方法,回过头来想想却不知道__proto__是什么,prototype是什么,以及各种继承方法的优点和缺点,想必有好...

    不知名网友 评论0 收藏0

发表评论

0条评论

shery

|高级讲师

TA的文章

阅读更多
最新活动
阅读需要支付1元查看
<