this是什么
this是函数运行时内部生成的对象,只能在函数内部使用,总是指向调用它的对象
this指向
- 一般函数
this总是指向调用它的最近一级对象,在函数执行时不可以改变this指向
var o = {
a:10,
b:{
fn:function(){
console.log(this.a); //undefined
}
}
}
o.b.fn(); // undefined
var c = o.b.fn;
c() // undefined
- 箭头函数
箭头函数在函数定义时就已经确定了this指向,箭头函数没有自己的this,永远继承父级作用域的this
function Person() {
this.name = 'lili'
setTimeout(()=>{
console.log(this)
}, 1000)
}
Person() // window
function Person() {
this.name = 'lili'
setTimeout(()=>{
console.log(this)
console.log(this.name)
}, 1000)
}
let p = new Person()
// Person {name:'lili'}
// lili
如何改变this指向
- 默认绑定
var name = 'lili'
function person(){
console.log(this, this.name) // window, lili
}
- 隐式绑定
var o = {
a:10,
b:{
fn:function(){
console.log(this.a); //undefined
}
}
}
o.b.fn(); // undefined
var c = o.b.fn;
c() // undefined
- new绑定
function Person(name){
this.name = name;
console.log(this)
}
let person = new Person('lili') // person {name: 'lili'}
- 显式绑定
下面三种修改this指向的方法都是接收2个参数,第一个参数是新的this指向,第二个参数是函数接受的参数,
function Person(...arg) {
console.log(this, arg)
}
let obj = {
name: 'lili'
}
call(this指向,参数列表) 修改this指向后函数都会立即执行
Person.call(obj, 1,2,3) // {name: 'lili'} 1,2,3
apply (this指向,参数数组)修改this指向后函数都会立即执行
Person.apply(obj, [1,2,3]) // {name: 'lili'} [1,2,3]
bind(this指向,参数列表)修改this后不会立即执行
let bindFn = Person.bind(obj)
bindFn(1,2,3)
严格模式和非严格模式this的区别
严格模式下(‘use strict’)没有调用函数的对象,this是undefined
非严格模式下 没有调用函数的对象,this是window
延伸:es6中新增的super与this的区别
this是自身的一个对象
super可以理解为是指向离自己最近的超父类对象的一个指针