Javascript this 关键字:
    面向对象语言中 this 表示当前对象的一个引用。但在 JavaScript 中 this 不是固定不变的,它会随着执行环境的改变而改变。

    this的指向在函数定义的时候是确定不了的,只有函数执行的时候才能确定this到底指向谁实际上this的最终指向的是那个调用它的对象。

    函数中使用 this(默认)
    在函数中,函数的所属者默认绑定到 this 上。
    在浏览器中,window 就是该全局对象为 [object Window]:

    1. function myFunction() {
    2. return this;
    3. }

    函数中使用 this(严格模式)
    严格模式下函数是没有绑定到 this 上,这时候 this 是 undefined

    1. "use strict";
    2. function myFunction() {
    3. return this;
    4. }
    1. var o = {
    2. user:"追梦子",
    3. fn:function(){
    4. console.log(this.user); //追梦子
    5. }
    6. }
    7. window.o.fn(); // 相同于:o.fn();
    1. var o = {
    2. a:10,
    3. b:{
    4. fn:function(){
    5. console.log(this.a); //undefined
    6. }
    7. }
    8. }
    9. o.b.fn();
    1. var o = {
    2. a:10,
    3. b:{
    4. a:12,
    5. fn:function(){
    6. console.log(this.a); //undefined
    7. console.log(this); //window
    8. }
    9. }
    10. }
    11. var j = o.b.fn;
    12. j();

    this永远指向的是最后调用它的对象,也就是看它执行的时候是谁调用的,例子中虽然函数fn是被对象b所引用,但是在将fn赋值给变量j的时候并没有执行,所以最终指向的是window。

    1. function Fn(){
    2. this.user = "追梦子";
    3. }
    4. var a = new Fn();
    5. console.log(a.user); //追梦子

    这里之所以对象a可以点出函数Fn里面的user是因为new关键字可以改变this的指向,将这个this指向对象a,为什么我说a是对象,因为用了new关键字就是创建一个对象实例。

    this碰到return时:
    new 后面的构造函数可以不加括号。

    1. // 例子1:
    2. function fn()
    3. {
    4. this.user = '追梦子';
    5. return {};
    6. }
    7. var a = new fn();
    8. console.log(a.user); //undefined
    9. // 例子2:
    10. function fn()
    11. {
    12. this.user = '追梦子';
    13. return function(){};
    14. }
    15. var a = new fn();
    16. console.log(a.user); //undefined
    17. // 例子3:
    18. function fn()
    19. {
    20. this.user = '追梦子';
    21. return 1;
    22. }
    23. var a = new fn();
    24. console.log(a.user); //追梦子
    25. // 例子4:
    26. function fn()
    27. {
    28. this.user = '追梦子';
    29. return undefined;
    30. }
    31. var a = new fn();
    32. console.log(a.user); //追梦子

    如果返回值是一个对象,那么this指向的就是那个返回的对象,如果返回值不是一个对象那么this还是指向函数的实例。
    **
    还有一点就是虽然null也是对象,但是在这里this还是指向那个函数的实例,因为null比较特殊。

    1. function fn()
    2. {
    3. this.user = '追梦子';
    4. return null;
    5. }
    6. var a = new fn;
    7. console.log(a.user); //追梦子

    知识点补充:
      1.在严格版中的默认的this不再是window,而是undefined。
      2.new操作符会改变函数this的指向问题,虽然我们上面讲解过了,但是并没有深入的讨论这个问题,网上也很少说,所以在这里有必要说一下。

    1. function fn(){
    2. this.num = 1;
    3. }
    4. var a = new fn();
    5. console.log(a.num); //1

    注意:在严格模式下(strict mode),全局对象将无法使用默认绑定,即执行会报undefined的错误.

    1. function foo() {
    2. "use strict";
    3. console.log( this.a );
    4. }
    5. var a = 2;
    6. foo(); // Uncaught TypeError: Cannot read property 'a' of undefined


    1. function foo() {
    2. console.log( this.a );
    3. }
    4. var a = 2;
    5. var obj = {
    6. a: 3,
    7. foo: foo
    8. };
    9. setTimeout( obj.foo, 100 ); // 2

    同样的道理,虽然参传是obj.foo,因为是引用关系,所以传参实际上传的就是foo对象本身的引用。对于setTimeout的调用,还是 setTimeout -> 获取参数中foo的引用参数 -> 执行 foo 函数,中间没有obj的参与。这里依旧进行的是默认绑定。

    1. function foo() {
    2. console.log( this.a );
    3. }
    4. var a = 2;
    5. var obj1 = {
    6. a: 3,
    7. };
    8. var obj2 = {
    9. a: 4,
    10. };
    11. var bar = function(){
    12. foo.call( obj1 );
    13. }
    14. setTimeout( bar, 100 ); // 3
    15. bar.call( obj2 ); // 3


    1. function foo() {
    2. console.log( this.a );
    3. }
    4. var a = 2;
    5. foo.call( null ); // 2
    6. foo.call( undefined ); // 2

    这种情况主要是用在不关心this的具体绑定对象(用来忽略this),而传入null实际上会进行默认绑定,导致函数中可能会使用到全局变量,与预期不符。
    所以对于要忽略this的情况,可以传入一个空对象ø,该对象通过Object.create(null)创建。这里不用{}的原因是,ø是真正意义上的空对象,它不创建Object.prototype委托,{}和普通对象一样,有原型链委托关系。

    扩展:箭头函数
    最后,介绍一下ES6中的箭头函数。通过“=>”而不是function创建的函数,叫做箭头函数。它的this绑定取决于外层(函数或全局)作用域。

    1. function foo(){
    2. console.log( this.a );
    3. }
    4. var a = 2;
    5. var obj = {
    6. a: 3,
    7. foo: foo
    8. };
    9. obj.foo(); //3
    1. var foo = () => {
    2. console.log( this.a );
    3. }
    4. var a = 2;
    5. var obj = {
    6. a: 3,
    7. foo: foo
    8. };
    9. obj.foo(); //2
    10. foo.call(obj); //2 ,箭头函数中显示绑定不会生效


    1. function foo(){
    2. return function(){
    3. console.log( this.a );
    4. }
    5. }
    6. var a = 2;
    7. var obj = {
    8. a: 3,
    9. foo: foo
    10. };
    11. var bar = obj.foo();
    12. bar(); //2
    1. function foo(){
    2. return () => {
    3. console.log( this.a );
    4. }
    5. }
    6. var a = 2;
    7. var obj = {
    8. a: 3,
    9. foo: foo
    10. };
    11. var bar = obj.foo();
    12. bar(); //3

    通过上面两个列子,我们看到箭头函数的this绑定只取决于外层(函数或全局)的作用域,对于前面的4种绑定规则是不会生效的。它也是作为this机制的一种替换,解决之前this绑定过程各种规则带来的复杂性。

    https://www.cnblogs.com/pssp/p/5216085.html