friends use this questions on work.
这里为全局作用域 GO (Global Object)
console.log(this);
function foo() {
console.log(this);
};
foo();
问题来了明明function是有作用域的为什么this 还是 window呢?
答:因为this指向与使用地无关
先记住几个概念:
one: 单独函数调用this指向就是window(默认绑定)
two: 谁引用this就指向谁(隐式绑定)
three: 通过 call、apply、bind(显示绑定)
four: 通过 new 关键字绑定(new绑定)
const obj = {
oname: 'obj',
fn: foo
};
obj.fn(); 注意此时 this 就隐式绑定到 obj 上了(所以foo函数内输入this此时是obj)
obj.fn.call();
obj.fn.call(1);
obj.fn.apply(1);
const newFn = obj.fn.bind(1);
newFn();
共同点:都可以绑定 this 并传递参数
雷同点:都可以不传参数不绑定 this 直接调用函数
不同点:
call: 传递参数时以逗号分隔(与正常调用函数传递实参一致)
apply: 传递参数时必须是一个数组数组内对应的每个元素就是一个参数
bind: 传递参数时也是使用逗号分隔和call类似但是不同的是 bind 可以在两个地方传递参数
例:const newFn = xxx.bind(this, ...params);
newFn(...params)
其实内部就是形成了一个天然的闭包(不懂什么是闭包? 可以看一下我上一篇文章)
但需要注意的是箭头函数是没有作用域的所以如果在箭头函数内使用 this 会一层一层的找出去找到谁 谁就是this
所以这也就是说为什么上篇文章我说能访问外部变量的函数就是闭包
const obj = {
name: 'susu',
eating() {
},
running() {
var name = '鸭鸭'
},
studying() {
console.log(this);
console.log(`${this.name}在学习`);
}
};
obj.studying.apply(obj.running);
下篇文章讲 call - apply - bind 的实现原理
深度解析
function foo() {
console.log(this, '被调用了');
}
var obj = {
Symbol: 'obj'
}
foo();
foo.call();
foo.apply();
foo.call(obj);
foo.apply(obj);
foo.call('bbb');
foo.apply('bbb');
var newFoo = foo.bind('aaa');
newFoo();
function bar(number1, number2) {
console.log(number1 + number2, this);
}
var newBar = bar.bind();
newBar();
bar.call('call', 20, 20);
bar.apply('apply', [20, 20]);
function Person(name, age) {
this.name = name;
this.age = age;
}
var p1 = new Person('susu', 18);
console.log(p1);
var p2 = Person('susu', 18);
console.log(p2);