let me = {
name: 'seymoe'
}
function toUpperCase() {
return this.name.toUpperCase()
}
toUpperCase.call(me) // 'SEYMOE'
可以不使用this
// 通过传参的形式
let me = {
name: 'seymoe'
}
function toUpperCase(person) {
return person.name.toUpperCase()
}
toUpperCase(me) // 'SEYMOE'
this的调用栈和调用点
function baz() {
// 调用栈是‘baz’,调用点是全局作用域
console.log('baz')
bar() 2. // bar的调用点
}
function bar() {
// 调用栈是‘baz - bar’,调用点位于baz的函数作用域内
console.log('bar')
}
baz() // 1. baz的调用点
this的指向问题
- 默认绑定
var a = 2
function foo() {
console.log(this.a)
}
function bar() {
foo()
}
foo() // 2
bar() // 2
// foo 是一个直白的毫无修饰的函数引用调用,
// 所以默认绑定了全局对象,
// 当然如果是严格模式 "use strict" this 将会是 undefined。
var a = 2
function foo() {
console.log(this.a)
}
(function (){
"use strict";
foo() // 2
})()
// 注意: 虽然是基于调用点,
但只要foo的内容没在严格模式下,那就默认绑定全局对象。
- 隐含绑定
function foo() {
console.log(this.a)
}
let obj = {
a: 2,
foo: foo
}
obj.foo() // 2
var a = 3
function foo() {
console.log(this.a)
}
let obj = {
a: 2,
foo: foo
}
let bar = obj.foo
bar() // 3
// 另一种微妙的情况
function doFoo(fn) {
fn && fn()
}
doFoo(obj.foo) // 3
- 明确绑定(call apply bind)
function foo() {
console.log(this.a)
}
let obj = {
a: 2
}
foo.call(obj) // 2
var obj = {
a: 2
}
function foo(something) {
console.log(this.a, something)
return this.a + something
}
var bar = foo.bind(obj)
bar(' is a number.') // 2 ,'is a number.'
- new绑定
new 操作符调用时会创建一个全新对象,连接原型链,并将这个新创建的对象设置为函数调用的 this 绑定,(默认情况)自动返回这个全新对象。
function Foo(a) {
this.a = a
}
let bar = new Foo(2)
console.log(bar.a) // 2
- this的一般流程
如果是 new 调用,this 是新构建的对象;
call、apply 或bind ,this 是明确指定的对象;
是用环境对象(或容器)调用的,this 是这个容器;
默认绑定,严格模式为 undefined,否则是global(全局)对象。
- 箭头函数的this
因为箭头函数不会像普通函数去使用 this, 箭头函数的 this 和外层的 this 保持一致。这种保持一致是强力的,无法通过 call、apply 或 bind来改变指向。
const obj = {
a: () => {
console.log(this)
}
}
obj.a() // window
obj.a.bind({})() // window
网友评论