准备把重心放到前端,把前端之前留的一些问题,从头整理明白
this指向问题
this绑定方式
- 默认绑定
- 隐式绑定
- 硬绑定
- new绑定
默认绑定,在不能应用其它绑定规则时使用的默认规则,通常是独立函数调用。
//在非严格模式下,this指向全局变量,严格模式this指向undefined
function sayHi(){
console.log('Hello,', this.name);
}
var name = 'demo';
sayHi();
隐式绑定,听名字感觉最为复杂
<!--通过obj.fun()隐式绑定-->
function sayHi(){
console.log('Hello,', this.name);
}
var person = {
name: 'demo',
sayHi: sayHi
}
var name = 'Wiliam';
person.sayHi();
<!--虽然sayHi()在外部声明,在执行person.sayHi()方法时,会将this隐式绑定到上下文对象person上-->
<!--输出Hello,demo-->
<!--对象属性链中只有最后一层会影响到调用。-->
function sayHi(){
console.log('Hello,', this.name);
}
var person2 = {
name: 'Christina',
sayHi: sayHi
}
var person1 = {
name: 'demo',
friend: person2
}
person1.friend.sayHi();
<!--输出Hello,Christina-->
<!--来一个陷阱-->
function sayHi(){
console.log('Hello,', this.name);
}
var person = {
name: 'demo',
sayHi: sayHi
}
var name = 'Wiliam';
var Hi = person.sayHi;
Hi();
<!--Hi()指向sayHi并没有person什么关系,sayHi中的this此时为默认绑定,指向全局name-->
<!--输出Hello,Wiliam-->
<!--再来一个陷阱,回调函数-->
function sayHi(){
console.log('Hello,', this.name);
}
var person1 = {
name: 'demo',
sayHi: function(){
setTimeout(function(){
console.log('Hello,',this.name);
})
}
}
var person2 = {
name: 'Christina',
sayHi: sayHi
}
var name='Wiliam';
person1.sayHi();
setTimeout(person2.sayHi,100);
setTimeout(function(){
person2.sayHi();
},200);
<!--输出Hello,Wiliam // 回调函数默认绑定-->
<!--输出Hello,Wiliam //person2.sayHi为变量赋值,this为默认绑定-->
<!--输出Hello,Christina //隐式绑定-->
硬绑定 call,apply,bind
<!--使用call,apply,bind方法直接改变this指向-->
function sayHi(){
console.log('Hello,', this.name);
}
var person = {
name: 'demo',
sayHi: sayHi
}
var name = 'Wiliam';
var Hi = person.sayHi;
Hi.call(person); //Hi.apply(person)
<!--输出Hello,demo-->
<!--硬绑定出现绑定丢失情况-->
function sayHi(){
console.log('Hello,', this.name);
}
var person = {
name: 'demo',
sayHi: sayHi
}
var name = 'Wiliam';
var Hi = function(fn) {
fn();
}
Hi.call(person, person.sayHi);
<!--输出Hello,Wiliam-->
<!--//当为参数使用时,应注意到底是person.sayHi还是person.sayHi(),此时对应的上下文是不一样的-->
new绑定
<!--this直接绑定到创建对象上-->
绑定优先级
new绑定 > 显式绑定 > 隐式绑定 > 默认绑定
箭头函数中的this
<!--箭头函数中的this继承于外层代码中的this.-->