美文网首页IT修真院-前端
【成都第一百零七期】JS中this的指向

【成都第一百零七期】JS中this的指向

作者: 何华飒 | 来源:发表于2017-05-13 10:09 被阅读0次

    JS中this的指向

    【成都小课堂】

    1.背景介绍

    2.知识剖析

    3.常见问题

    4.解决方案

    5.编码实战

    6.扩展思考

    7.参考文献

    8.更多讨论

    1.背景介绍

    this是Javascript语言的一个关键字。它代表函数运行时,自动生成的一个内部对象。

    this是动态绑定的,它可以是全局对象、当前对象或者任意对象(这取决于函数的调用方式)。这就导致了this具备了多重含义,可以使得javascript更灵活的使用。但是,带来了灵活性的同时也会给我们初学者带来不少困惑。

    2.知识剖析

    全局环境中的this

    function test() {

    console.log(this);

    }

    test();

    总结:在全局作用域中它的this执行当前的全局对象(浏览器端是Window,node中是global)

    严格模式‘use strict’下的this

    'use strict';

    function test() {

    console.log(this);

    };

    test();

    // undefined

    原因:this并不会指向全局,而是undefined,这样的做法是为了消除js中一些不严谨的行为。

    在javascritp中,不一定只有对象方法的上下文中才有this, 全局函数调用和其他的几种不同的上下文中也有this指代。 它可以是全局对象、当前对象或者任意对象,这完全取决于函数的调用方式。JavaScript中函数的调用有以下几种方式:作为对象方法调用,作为函数调用,作为构造函数调用,和使用apply或call调用。

    1.作为对象方法调用:this被自然绑定到该对象,也就是说this就指这个上级对象

    var point = {

    x : 0,

    y : 0,

    moveTo : function(x, y) {

    this.x = this.x + x;

    this.y = this.y + y;

    }

    };

    point.moveTo(1, 1)//this绑定到当前对象,即point对象

    2.作为函数调用:this被绑定到全局对象

    function makeNoSense(x) {

    this.x = x;

    }

    makeNoSense(5);

    x;// x已经成为一个值为5的全局变量

    3.作为构造函数调用:this绑定到新创建的对象上,也就是说this就指这个新对象

    function Point(x, y){

    this.x = x;

    this.y = y;

    }

    注:构造函数不使用new调用,则和普通函数一样。一般地,构造函数首字母大写

    4.使用apply或call调用:在JavaScript中函数也是对象,对象则有方法,apply和call就是函数对象的方法。

    function Point(x, y){

    this.x = x;

    this.y = y;

    this.moveTo = function(x, y){

    this.x = x;

    this.y = y;

    }

    }

    var p1 = new Point(0, 0);

    var p2 = {x: 0, y: 0};

    p1.moveTo(1, 1);

    p1.moveTo.apply(p2, [10, 10]);

    3、常见问题

    问题一

    var obj = {

    name: 'qiutc',

    foo: function() {

    console.log(this);

    },

    foo2: function() {

    console.log(this);

    setTimeout(this.foo, 1000);

    }

    }

    obj.foo2();

    现象:两次打印的this不一样

    问题二

    'use strict';

    function foo() {

    console.log(this);

    }

    setTimeout(foo, 1);

    // window

    现象:加了严格模式,foo调用也没有指定this,应该是出来undefined,但是这里仍然出现了全局对象

    4、解决方案

    问题一起因是因为 setTimeout() 将 this.foo 作为了自身的参数,这时候 this.foo 是作为一个fun参数去获取全局的变量了。

    可以这么这么解决:利用闭包的特性来处理

    var obj = {

    name: 'qiutc',

    foo: function() {

    console.log(this);

    },

    foo2: function() {

    console.log(this);

    var _this = this;

    setTimeout(function() {

    console.log(this);  // Window

    console.log(_this);  // Object {name: "qiutc"}

    }, 1000);

    }

    }

    obj.foo2();

    可以看到直接用this仍然是Window;因为foo2中的this是指向obj,我们可以先用一个变量_this来储存,然后在回调函数中使用_this,就可以指向当前的这个对象了

    问题二

    setTimeout方法在调用传入函数的时候,如果这个函数没有指定了的this,那么它会做一个隐式的操作—-自动地注入全局上下文,等同于调用foo.apply(window)而非foo();

    5、编码实战

    对于内部函数,即声明在另外一个函数体内的函数,这种绑定到全局对象的方式会产生另外一个问题。我们仍然以前面提到的point对象为例,这次我们希望在moveTo方法内定义两个函数,分别将x,y坐标进行平移。结果可能出乎大家意料,不仅point对象没有移动,反而多出两个全局变量x,y

    var point = {

    x : 0,

    y : 0,

    moveTo : function(x, y) {

    //内部函数

    var moveX = function(x) {

    this.x = x;//this绑定到了哪里?

    };

    //内部函数

    var moveY = function(y) {

    this.y = y;//this绑定到了哪里?

    };

    moveX(x);

    moveY(y);

    }

    };

    point.moveTo(1, 1);

    point.x; //==>0

    point.y; //==>0

    x; //==>1

    y; //==>1

    这属于JavaScript的设计缺陷,正确的设计方式是内部函数的this应该绑定到其外层函数对应的对象上,为了规避这一设计缺陷,聪明的JavaScript程序员想出了变量替代的方法,约定俗成,该变量一般被命名为that。

    var point = {

    x : 0,

    y : 0,

    moveTo : function(x, y) {

    var that = this;

    //内部函数

    var moveX = function(x) {

    that.x = x;

    };

    //内部函数

    var moveY = function(y) {

    that.y = y;

    }

    moveX(x);

    moveY(y);

    }

    };

    point.moveTo(1, 1);

    point.x; //==>1

    point.y; //==>1

    6.扩展思考

    问题:如何理解this?

    当一个函数被调用时,拥有它的object会作为this传入。在全局下,就是window or global,其他时候就是相应的object。 也可以看到,call和apply就是利用这一点实现更改this值的

    7.参考文献

    参考一:深入浅出JavaScript中的this

    参考二:JavaScript中的this !

    参考三:JavaScript中的this用法与指向

    参考四:如何理解JavaScript中的this关键字?

    8、更多讨论

    this含义为何如此丰富?

    理解this的指向有何意义?

    答案链接

    小课堂视频:


    _2017-0512-1904-26_腾讯视频

    PPT链接

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

    技能树.IT修真院

    “我们相信人人都可以成为一个工程师,现在开始,找个师兄,带你入门,掌控自己学习的节奏,学习的路上不再迷茫”。

    这里是技能树.IT修真院,成千上万的师兄在这里找到了自己的学习路线,学习透明化,成长可见化,师兄1对1免费指导。快来与我一起学习吧 !

    http://www.jnshu.com/login/1/96029204

    相关文章

      网友评论

        本文标题:【成都第一百零七期】JS中this的指向

        本文链接:https://www.haomeiwen.com/subject/quhxxxtx.html