js之this指向规则


1.在浏览器环境中,this在全局作用域下指向window对象,nodejs里面指向global对象

2.函数中三种不同的指向

// 定义一个函数
function foo() {
  console.log(this);
}

不同的环境指向不同的对象

// 直接调用
foo(); //window/global对象
// 放在对象里使用
let obj = {
  name:"why",
  foo:foo
}
obj.foo(); //obj对象
// 通过call/apply调用
foo.call("abc"); // String{"abc"}对象

3.绑定方式

    3a 默认绑定,也就是独立的函数调用this或者函数作为参数传入另外一个函数,这时候this都是默认绑定的全局对象

function test1() {
  console.log(this); // window
  test2();
}

function test2() {
  console.log(this); // window
  test3()
}

function test3() {
  console.log(this); // window
}
test1();

     3b 隐式调用,也就是某个对象发起的函数调用this。

function foo() {
  console.log(this);
}

var obj1 = {
  name: "obj1",
  foo: foo
}

var obj2 = {
  name: "obj2",
  obj1: obj1
}

obj2.obj1.foo(); // obj1

     注意下面的调用方式是默认绑定

var bar = obj1.foo;
bar();

     3c 显示绑定

     也就是通过call和apply方法来绑定this。但是注意调用的对象内部有一个函数的引用,否则会报错

function foo() {
  console.log(this);
}

foo.call(global); // 全局对象
foo.call({name: "aaa"}); // {name: "aaa"}
foo.call(123); // Number对象,存放是123

    bind函数(其实就是Function.prototype.bind)可以将一个函数显示绑定到一个对象上

function foo() {
  console.log(this);
}
var obj = {
  name: "aaa"
}
var bar = foo.bind(obj);
bar(); // obj对象
bar(); // obj对象

    3d 特殊的内置函数

    在JS的一些内置函数里面,this指向会有一些不一样。

    setTimeout的函数参数里面的this指向的是全局对象,forEach默认下也是全局对象,但是可以传入第二参数来指定this绑定的对象。

    还有在Dom操作中,操作函数中的this指向的是节点对象

var box = document.querySelector(".box");
box.onclick = function() {
  console.log(this); // box对象
}

      3e new关键字绑定

使用new关键字调用函数时,创建的新对象会被执行prototype连接,然后绑定到函数调用的this上,如果函数没有返回其他对象,表达式会返回这个新对象。

// 创建Person
function Person(name) {
  console.log(this); // Person {}
  this.name = name;
}

var p = new Person("aaa");
console.log(p); // Person {name: "aaa"}

4 优先级

默认绑定最低,显示大于隐式,new高于隐式和显示。

5 其他情况

   5.1显示绑定时传入的是null或者undefined,那么这个显示绑定就被忽略使用默认绑定

   5.2 间接函数引用,使用默认绑定

         首先知道(num1=num2)的结果是num2

function foo() {
  console.log(this);
}
var obj1 = {
  name: "obj1",
  foo: foo
};
var obj2 = {
  name: "obj2"
}
obj1.foo(); // obj1对象
// ()里面的结果是foo函数
(obj2.foo = obj1.foo)();  // window/global

    5.3 箭头函数

   箭头函数没有作用域,不使用上述规则,而是根据外层作用域来决定this的指向

几个面试题地址:https://mp.weixin.qq.com/s/hYm0JgBI25grNG_2sCRlTA

相关