[[toc]]
普通函数this指向什么?
普通函数的this指向哪里?
- this指向调用它的对象
- 函数定义无法确定,只有函数执行时才能确定
普通函数有哪些?
- 没有调用者的函数
- 对象内函数
- 使用apply
// 没有调用者的函数: this(非严格)指向全局window
function test(){
console.log('this=',this) // this=window
}
test()
// 对象内函数: 只有1层,this指向调用者对象
const school = {
name: 'abc',
course(){
console.log('this=',this) // this= school
console.log('name=',this.name) // name=abc
}
}
school.course()
// 对象内函数: 有多层对象,this指向最近调用者对象
const outer = {
name: 'outer',
inner:{
name: 'inner',
fn(){
console.log('this=',this) // this= inner
console.log('name=',this.name) // name=inner
}
}
}
outer.inner.fn()
// 使用apply: 方法fun内部的this为apply参数1,如果参数1为null,则默认全局对象
const obj1 = {name: '对象1'}
function fn(a){
console.log('a=',a)
console.log('this=',this)
console.log('name=',this.name)
}
// TEST
fn.apply(obj1,['haha'])
// a= haha
// this=obj1
// name= 对象1
fn.apply(null,['haha'])
// a= haha
// this=window
// name= undefined
箭头函数的this指向什么?
箭头函数的this指向哪里?
- this最终指向定义它的作用域的this,
- 如果没有定义时所在作用域this,则向上查找父级作用域的this
- 考虑: 在箭头函数之前考虑this即可;
箭头函数有哪些?
- 全局箭头函数
- 普通对象下的箭头函数
- 普通函数下的箭头函数
- 箭头函数下的箭头函数
- 使用apply
确定箭头函数的this的办
- 是在箭头函数定义之前打印this
console.log(this) // 此时的this就是箭头函数的this
const fun = () => { ... }
// 1. 全局箭头函数: this(非严格)指向全局window
const test = ()=>{
console.log('this=',this) // this=window
}
test()
// 2.1 一层普通对象下的箭头函数: 相当于fn上层的this
const outer = {
fn: () =>{
console.log('this=',this)
}
}
outer.fn() // this=window
// 2.2 多层普通对象下的箭头函数: 相当于fn上层的this
const outer = {
inner:{
fn: () =>{
console.log('this=',this)
}
}
}
outer.inner.fn() // this=window
// 3.1 普通函数下的箭头函数: 取决于普通函数作用域,fn2中的this取决于fn1,fn1中的this所在作用域是outer
const outer = {
fn1 () {
const fn2 = () => {
console.log('this=', this) // this=outer
}
return fn2()
}
}
outer.fn1()
// 3.2 箭头函数下的箭头函数: 取决于上层箭头函数作用域, fn2中的this取决于fn1,fn1中的this所在作用域是window
const outer = {
fn1: () => {
const fn2 = () => {
console.log('this=', this) // this=window
}
return fn2()
}
}
outer.fn1()
// 4.1 使用apply: apply只会影响函数调用者,不会影响定义者,因此apply对箭头函数this无影响
const obj1 = {name: '对象1'}
const fn = (a) => {
console.log('a=',a)
console.log('this=',this)
console.log('name=',this.name)
}
// TEST
fn.apply(obj1,['haha'])
// a= haha
// this=window
// name= undefined
fn.apply(null,['haha'])
// a= haha
// this=window
// name= undefined
// 4.2 使用call: 和apply类似
// 定义name变量: 全局对象和普通对象
window.name = '111'
const obj = {name: '222'}
// 普通函数
function getNameCommon(){
console.log(`name=${this.name}, this=`,this)
}
// 箭头函数
const getNameArrow = () =>{
console.log(`name=${this.name}, this=`,this)
}
// TEST
getNameCommon() // name=111, this=window
getNameArrow() // name=111, this=window
getNameCommon.call(obj) // name=222, this=obj
getNameArrow.call(obj) // name=111, this=window
构造函数this指向什么?
构造函数
- 没有return语句, this指向实例变量
- 有return && return是基本类型(如数字,字符串,null),return无效,this指向原本实例变量
- 有return && return是对象,则return之前this指向实例变量,return之后this指向return的对象
// 没有返回: this指向对象实例
function device1(name){
this.name=name
console.log('this=',this) // this=device1
}
// 返回基本类型: this指向对象实例
function device2(name){
this.name=name
console.log('this=',this) // this=device2
return 1
}
// 返回引用类型: return之前this指向对象实例,return之后this指向返回对象
const obj = {name:'对象1'}
function device3(name){
this.name=name
console.log('this=',this) // this=device3
return obj
}
// TEST
let d1 = new device1('111')
console.log('d1.name=',d1.name) // 111
let d2 = new device2('222')
console.log('d2.name=',d2.name) // 222
let d3 = new device3('333')
console.log('d3.name=',d3.name) // 对象1 不是333