美文网首页jsJS
JavaScript:this的指向

JavaScript:this的指向

作者: 前小小 | 来源:发表于2021-05-08 17:38 被阅读0次

this 的默认绑定

  • 全局环境下的 this 指向了 window
console.log(this); // window
  • 函数独立调用,函数内部的 this 也指向了 window,函数默认被挂载到 window 上
function fn() {
  console.log(this);
}
fn(); // window   // 相当于window.fn();
  • 被嵌套函数独立调用时,this 默认指向了 window
var obj = {
  a: 2,
  // 函数当做对象的方法来调用 this指向了obj
  fn: function () {
    function test() {
      console.log(this); // window
    }
    test();
  },
};
obj.fn(); // 此时test()函数自己去执行,相当于函数独立调用, 所以此时的this也是window
  • 立即执行函数的 this 指向 window
(function () {
  console.log('自执行函数中内部的this: ' + this); //window
})();
  • 闭包中 this 默认指向了 window
// 闭包就是能够读取其他函数内部变量的函数。下面的test函数就是闭包
var a = 0;

var obj = {
  a: 2,
  foo: function () {
    var c = this.a;
    return function test() {
      console.log(this); // window
      return c;
    };
  },
};
var fn = obj.foo();
console.log(fn()); // 2
  • 函数调用链(一个函数又调用另外一个函数),此时每个函数相当于独立调用,this 指向 window
function test1() {
  console.log(this); // window
  test2();
}

function test2() {
  console.log(this); // window
}
test1();
  • 内置函数 setTimeout()和 setInterval()第一个参数的回调函数中的 this 默认指向了 window
// 1.
setTimeout(function () {
  console.log(this); // window
}, 1000);
// 2.
var a = 10;
function foo() {
  console.log(this.a);
}
var obj = {
  a: 1,
  foo: foo,
};
setTimeout(obj.foo, 1000); // 10
// 以上代码相当于
setTimeout(function foo() {
  console.log(this.a);
}, 1000); // 10

this 的隐式绑定

// 1. 当函数当做对象的方法来调用,this指向了直接对象
function foo() {
  console.log(this.a);
}
var obj = {
  a: 1,
  foo: foo,
  obj2: {
    a: 2,
    foo: foo,
  },
};
// foo()函数的直接对象是obj, this会隐式的被绑定到obj对象上
obj.foo(); // 1
// foo()函数的直接对象是obj2, this会隐式的被绑定到obj对象上
obj.obj2.foo(); // 2

this 的显示绑定

  • 通过 call() apply() bind() 绑定 this 对象
var a = 0;
function foo() {
  console.log(this.a);
}
var obj = {
  a: 2,
};
foo(); // 0
foo.call(obj); // 2
foo.apply(obj); // 2
var fn = foo.bind(obj);
fn(); // 2
  • 如果 this 被硬绑定, 那么 this 不能再被改变
var a = 0;
function foo() {
  console.log(this.a);
}
var obj = {
  a: 2,
};
var bar = function () {
  foo.call(obj);
};
bar();
setTimeout(bar, 2000);
// 硬绑定后bar无论怎么调用,都不会影响foo函数的this绑定
bar.call(window); // 2
  • 数组的 forEach (还有 map() filter() some() every()等函数)
// 因为默认情况下传入的函数是独立调用的(默认绑定)
var id = 'window';
var obj = {
  id: 'fn',
};
var arr = [1, 2, 3];
arr.forEach(function (item) {
  console.log(item, this.id); // 打印了三次"window"
});
// 如果要改变该函数的this指向, 就给forEach的第二个参数传递一个对象
var id = 'window';
var obj = {
  id: 'fn',
};
var arr = [1, 2, 3];
arr.forEach(function (item) {
  console.log(item, this.id); // 打印了三次"fn"
}, obj);

this 的 new 绑定

// 如果是new关键字来调用函数 相当于构造函数来实例化对象,那么内部的this指向了当前实例化的对象
// 创建Person
function Person() {
  console.log(this); // Person {}
}

var p = new Person();
console.log(p); // Person {}

this 的隐式丢失

  • 函数别名
var a = 0;
function foo() {
  console.log(this.a);
}
var obj = {
  a: 1,
  foo: foo,
};
obj.foo(); // 1
// 因为foo最终被调用的位置是bar,而bar在进行调用时没有绑定任何的对象,也就没有形成隐式绑定,此时为默认绑定情况,里面的this指向了window
var bar = obj.foo;
bar(); // 0
  • 参数传递
var a = 0;
function foo() {
  console.log(this.a);
}
var obj = {
  a: 1,
  foo: foo,
};
obj.foo(); // 1
// 因为foo最终被调用的位置是bar,而bar在进行调用时没有绑定任何的对象,也就没有形成隐式绑定,此时为默认绑定情况,里面的this指向了window
var bar = obj.foo;
bar(); // 0
  • 间接调用
function foo() {
  console.log(this.a);
}
var a = 2;
var obj = {
  a: 3,
  foo: foo,
};
var p = { a: 4 };
// 隐式绑定,函数当做对象中的方法来使用,内部的this指向了该对象
obj.foo(); // 3

// 赋值(obj2.foo = obj1.foo)的结果是foo函数;
// foo函数被直接调用,那么是默认绑定
(p.foo = obj.foo)(); // 2

// 将obj.foo函数赋值给p.foo函数, 之后p.foo()函数再执行,其实是属于p对象的方法的执行,this指向了当前的p对象
p.foo = obj.foo;
p.foo(); // 4

ES6 箭头函数中的 this 指向

MDN 官方文档:「箭头函数不会创建自己的 this,它只会从自己的作用域链的上一层继承 this。」

var obj = {
  a: () => {
    console.log(this);
  },
};
// 对象是不能产生作用域的,a方法实际是被定义在了全局作用域下,里面的this指向的是window
obj.a(); // window
// 不能用call方法改变箭头函数的this指向
var obj = {
  a: () => {
    console.log(this);
  },
};
obj.a.call({ name: 'zhangsan' }); // window

严格模式下的 this 指向

// 1. 严格模式下, 独立调用的函数内部的this指向了undefined
function fn() {
  'use strict';
  console.log(this); // undefined
}
fn();
// 2. 严格模式下, 函数apply()和call()内部的this始终是它们的第一个参数
function fn() {
  'use strict';
  console.log(this); // 第一个输出null,第二句输出undefined
}
showColor.call(null);
showColor.call(undefined);

相关文章

  • 关于js函数中this的指向的问题

    @(javascript)[JavaScript中this的指向] 关于js函数中this的指向的问题 javas...

  • javascript this 指向

    我在文章《javascript 执行上下文》中介绍了 javascript 代码在执行时,会相应地创建对应执行上下...

  • javascript this指向

    首页,js默认的对象是Window,调用一个函数是,如果不去改变它的调用对象的话,this基本上都会指向Windo...

  • JavaScript this的指向

    在 JavaScript 中 this 取什么值,是在函数真正被调用执行的时候确定的,函数定义的时候确定不了,因为...

  • JavaScript:this的指向

    this 的默认绑定 全局环境下的 this 指向了 window 函数独立调用,函数内部的 this 也指向了 ...

  • JavaScript this的指向问题

    原文参考toddmotto 1. 关于This执向问题,有三个要点: this的指向跟函数本身没有关系,取决于函数...

  • javascript的this指向问题

    例子1: 这题考到了 this 的指向, 还有一个小坑, 在 window 下, 默认有一个 name 属性, 这...

  • javascript中的this指向

    写在前面 本文转自深入浅出 JavaScript 中的 this 在java等面向对象的语言中,this关键字的含...

  • Javascript 中 this 的指向

    大家好,我是IT修真院武汉第10期学员,一枚正直、纯洁、善良的前端程序员。 今天给大家分享一下,修真院官网任务...

  • JavaScript中的this指向

    1.概念 在JavaScript中,this 是指当前函数中正在执行的上下文环境,因为这门语言拥有四种不同的函数调...

网友评论

    本文标题:JavaScript:this的指向

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