普通函数this绑定有哪几种方式以及指向
- 默认绑定
- 隐私绑定
- 显示绑定
- new绑定
默认绑定
// 默认绑定: 独立函数调用,在浏览器中一般指向window
// 1.案例一:
// function foo() {
// console.log(this)//window
// }
// foo()
// 2.案例二:
// function foo1() {
// console.log(this)
// }
// function foo2() {
// console.log(this)
// foo1()
// }
// function foo3() {
// console.log(this)
// foo2()
// }
// foo3()
// 3.案例三:
// var obj = {
// name: "why",
// foo: function() {
// console.log(this)
// }
// }
// var bar = obj.foo
// bar() // window
4.案例四:
function foo() {
console.log(this)
}
var obj = {
name: "why",
foo: foo
}
var bar = obj.foo
bar() // window
// 5.案例五:
function foo() {
function bar() {
console.log(this)
}
return bar
}
var fn = foo()
fn() // window
隐私绑定
// 隐式绑定: object.fn()
// object对象会被js引擎绑定到fn函数的中this里面
// 一般是谁调用谁那么this就指向谁
function foo() {
console.log(this)
}
// 独立函数调用
// foo()
// 1.案例一:
// var obj = {
// name: "why",
// foo: foo
// }
// obj.foo() // obj对象
// 2.案例二:
// var obj = {
// name: "why",
// eating: function() {
// console.log(this.name + "在吃东西")
// },
// running: function() {
// console.log(obj.name + "在跑步")
// }
// }
// // obj.eating()
// // obj.running()
// var fn = obj.eating
// fn()
// 3.案例三:
var obj1 = {
name: "obj1",
foo: function() {
console.log(this)
}
}
var obj2 = {
name: "obj2",
bar: obj1.foo
}
obj2.bar()
显示绑定
// function foo() {
// console.log("函数被调用了", this)
// }
// 1.foo直接调用和call/apply调用的不同在于this绑定的不同
// foo直接调用指向的是全局对象(window)
// foo()
// var obj = {
// name: "obj"
// }
// call/apply是可以指定this的绑定对象
// foo.call(obj)
// foo.apply(obj)
// foo.apply("aaaa")
// 2.call和apply有什么区别?
function sum(num1, num2, num3) {
console.log(num1 + num2 + num3, this)
}
sum.call("call", 20, 30, 40)
sum.apply("apply", [20, 30, 40])
// 3.call和apply在执行函数时,是可以明确的绑定this, 这个绑定规则称之为显示绑定
function foo() {
console.log(this)
}
// foo.call("aaa")
// foo.call("aaa")
// foo.call("aaa")
// foo.call("aaa")
// 默认绑定和显示绑定bind冲突: 优先级(显示绑定)
var newFoo = foo.bind("aaa")
newFoo()
newFoo()
newFoo()
newFoo()
newFoo()
newFoo()
var bar = foo
console.log(bar === foo)
console.log(newFoo === foo)
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)
var p2 = new Person("kobe", 30)
console.log(p2.name, p2.age)
var obj = {
foo: function() {
console.log(this)
}
}
总结:
- 默认绑定(函数独自调用),在浏览器当中this一般指向window
- 隐式绑定, this一般指向谁调用,就指向谁
- 显示绑定, this指向call,apply,bind这三个函数中的第一个参数
- new绑定,this是指向调用这个构造器时创建出来的对象