01-this的指向

111 阅读1分钟

1.默认绑定

规则: 独立的函数调用,指向全局window

function foo() {
  console.log(this)
}
foo() // window

function foo1() {
  function bar() {
    console.log(this)
  }
  return bar
}

var fn = foo1()
fn() // window

2.隐式绑定

规则: 通过对象发起的函数调用,指向这个对象

// 例1
function foo() {
  console.log(this)
}
var obj = {
  name: "obj",
  foo: foo
}

obj.foo() // obj对象
// 例2
var obj1 = {
  name: "obj1",
  foo() {
    console.log(this)
  }
}

var obj2 = {
  name: "obj2",
  bar: obj1.foo
}

obj2.bar()  // obj2对象

3.显式绑定

规则:通过call、apply、bind(函数的原型方法)绑定this对象

function foo(num1, num2) {
  console.log(this, num1, num2);
}

foo.call('call', 1, 2); // [String: 'call'] 1 2
foo.apply('apply', [1, 2]); // [String: 'apply'] 1 2
var newFoo = foo.bind('bind', 1, 2);
newFoo(); // [String: 'bind'] 1 2

4.new绑定

规则: new关键字调用一个函数时(构造器), 指向创建出来的对象

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

class Animal {
  constructor(name) {
    this.name = name;
    console.log(this);
  }
}

var lily = new Person('lily'); // Person { name: 'lily' }
var cat = new Animal('cat'); // Animal { name: 'cat' }

规则优先级

new绑定 > 显式绑定 > 隐式绑定 > 默认绑定

// 显式和隐式比较
function foo() {
  console.log(this);
}

var obj = {
  name: 'obj',
  foo: foo.bind('bind'),
};

obj.foo(); // [String: 'bind']

// new绑定和显式比较
function foo1() {
  console.log(this);
}

var bar = foo1.bind('bind');

var obj = new bar(); // foo {}

特殊绑定

忽略显示绑定:apply/call/bind: 当传入null/undefined时, 自动将this绑定成全局window

function foo() {
  console.log(this);
}
var obj = {
  foo,
};

obj.foo.apply(null); // window
obj.foo.apply(undefined); // window
var bar = obj.foo.bind(null);
bar(); // window