箭头函数体内的this
对象,就是定义该函数时所在的作用域指向的对象,而不是使用时所在的作用域指向的对象。
1.执行环境:特指运行时产生的作用域
11.默认绑定:
function foo(fn) {
fn() // 运行时的作用域
}
function bar() {
console.log(this)
}
foo(bar) // 独立函数-隐式调用
12. 隐式绑定:
function foo() { // function 会保留this
console.log(this) // this 会从自己作用域网上找this
}
var obj = {
name: 'tom',
foo
}
obj.foo() // 带主语的调用
function foo() {// 先用自己作用域,没有才往上找
console.log(this); // obj1对象
}
var obj1 = {
name: "obj1",
foo: foo
}
var obj2 = {
name: "obj2",
obj1: obj1
}
obj2.obj1.foo();
13.显式绑定:call apply bind
function foo() {
console.log(this);
}
var obj = {
name: "why"
}
var bar = foo.bind(obj);
bar(); // obj对象
bar(); // obj对象
bar(); // obj对象
14.内置函数,默认绑定的window
setTimeout() 中的this //源码apply了 window
() => {console.log(this)} // this window
forEach(fn) 中的this // 默认情况下 fn是自动调用函数(默认绑定)
var a = [1,2,3]
var obj = {name: 'tom'}
a.forEach(function(item) { //箭头函数 this就是window
console.log(item, this)
}, obj)
//div的点击,回调内部是点击项
var box = document.querySelector(".box");
box.onclick = function() {
console.log(this); // box对象
}
15.new绑定
var name = 'lt' // new绑定过程:
function Person(name) {// 第二步执行函数:函数中的this指向新{}
// 第三步设置:将新{}的construct设置为构造函数名Person,
// 新{}的_proto_指向构造函数的prototype属性
this.name = name
console.log('this.name',this.name)
}
var p = new Person('tom') // 第一步:创建一个新{} -> {}.Person()
console.log('p',p) // 第四步:将初始化完毕的新对象地址,保存到等号左边的变量中
// 注意:若构造函数中没有返回值或返回值是基本类型(Number、String、Boolean)的值,则返回新实例对象;若返回值是引用类型的值,则实际返回值为这个引用类型。
优先级:new绑定 > 显示绑定(bind)> 隐式绑定 > 默认绑定
试一试:
var name = 'window'
var person1 = {
name: 'person1',
foo1: function () {
console.log(this.name)
},
foo2: () => console.log(this.name),
foo3: function () {
return function () {
console.log(this.name)
}
},
foo4: function () {
return () => {
console.log(this.name)
}
}
}var person2 = { name: 'person2' }
person1.foo1(); // person1
person1.foo1.call(person2); // person2person1.foo2(); // window
person1.foo2.call(person2);// person2 window
// 箭头函数只受父级作用域影响,本身不能实现绑定 callperson1.foo3()();// window
person1.foo3.call(person2)();// person2 window
// return 出来一个独立的函数,不是对象牵引的函数
person1.foo3().call(person2); //person2person1.foo4()(); // window person1
person1.foo4.call(person2)(); // window person2 // 箭头函数找上级作用域
person1.foo4().call(person2); // person2 person1 // 受父级作用域影响
var name = 'window'
function Person (name) {
this.name = name
this.obj = {
name: 'obj',
foo1: function () {
return function () {
console.log(this.name)
}
},
foo2: function () {
return () => {
console.log(this.name)
}
}
}
}
var person1 = new Person('person1')
var person2 = new Person('person2')person1.obj.foo1()() // person1 window
person1.obj.foo1.call(person2)() // person2 window
person1.obj.foo1().call(person2) // person2person1.obj.foo2()() // window obj
person1.obj.foo2.call(person2)() // window person2
person1.obj.foo2().call(person2) // window obj
// 不容易啊不容易......