this的绑定(指向)规则

1.默认绑定: 独立函数调用

案列一
function foo() {
  console.log(this)
}

foo() //指向window
案列二
var obj = {
  name: "why",
  foo: function() {
    console.log(this)
  }
}

var bar = obj.foo
bar() // 指向window
案列三
function foo1() {
  console.log(this)
}

function foo2() {
  console.log(this)
  foo1()
}

function foo3() {
  console.log(this)
  foo2()
}

foo3() //也是指向window
案列四
function foo() {
  console.log(this)
}
var obj = {
  name: "why",
  foo: foo
}

var bar = obj.foo
bar() // window

2.obj对象调用指向调用的该对象

案列一
var obj = {
  name: "why",
  foo: foo
}

obj.foo() // obj对象
案例二
var obj = {
  name: "why",
  eating: function () {
    console.log(this.name + "在吃东西")
  },
  running: function () {
    console.log(obj.name + "在跑步")
  }
}

obj.eating() //obj 
obj.running() //obj
var fn = obj.eating
fn() //window
//打印结果
 	why在吃东西
	why在跑步
	undefined在吃东西
案例三
var obj1 = {
  name: "obj1",
  foo: function () {
    console.log(this)
  }
}

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

obj2.bar() //obj2

3.显示绑定apply,call,bind

1.foo直接调用和call/apply调用的不同在于this绑定的不同
foo直接调用指向的是全局对象(window)
call/apply是可以指定this的绑定对象

function foo() {
  console.log("函数被调用了", this)
}
foo() //window 

var obj = {
  name: "obj"
}
foo.call(obj) //函数被调用了 { name: 'obj' }
foo.apply(obj) //函数被调用了 { name: 'obj' }
foo.apply("aaaa") //函数被调用了 [String: 'aaaa']

2.call和apply有什么区别?
两者在传参的时候 apply的参数是需要放到数组里面的 而call的直接,写下去

function sum(num1, num2, num3) {
  console.log(num1 + num2 + num3, this)
}

sum.call("call", 20, 30, 40) //
sum.apply("apply", [20, 30, 40])

3.bind bind方法会返回一个新的函数
默认绑定和显示绑定bind冲突: 优先级(显示绑定)

function foo() {
  console.log(this)
}
var newFoo = foo.bind("aaa")
newFoo() //aaa

4.new绑定

我们通过一个new关键字调用一个函数时(构造器), 这个时候this是在调用这个构造器时创建出来的对象
this = 创建出来的对象
这个绑定过程就是new 绑定

function Person(name, age) {
  this.name = name
  this.age = age
}

var p1 = new Person("why", 18)
console.log(p1.name, p1.age) // why 18

var p2 = new Person("kobe", 30)
console.log(p2.name, p2.age) //kobe 30


var obj = {
  foo: function() {
    console.log(this)
  }
}
来源url
栏目