javascript this学习
js的this指向问题一直让人头大,一般情况下 谁调用 this就指向谁
先来看几个例子,看看this分别指向什么(浏览器环境下)
- 在全局环境中this指向全局对象(浏览器:window,node:global)
console.log(this === window) // true
a = 1
console.log(window.a) // 1
console.log(this.a) // 1
this.b = 'jsong'
console.log(window.b) // jsong
console.log(b) // jsong
- 在函数内部,this的值取决于函数的调用方式。f1()虽然没有人调用,默认指向window,但是在严格模式下’use strict’,f2()是直接调用的,this就是undefined
console.log(this === window) // true
function f1() {
return this;
}
console.log(f1() === window) // true
function f2() {
'use strict'
return this;
}
console.log(f2() === window) // false
console.log(f2() === undefined) // true
- 如果要把this的值从一个环境传到另一个,可以用call或apply
var obj = {
a: 'obj-a'
}
var a = 'window-a'
function whatsThis(arg) {
return this.a // this 的值取决于函数的调用方式
}
console.log(whatsThis()) // window-a
console.log(whatsThis.call(obj)) // obj-a
console.log(whatsThis.apply(obj)) // obj-a
- fn.call(obj [, arg1[, arg2, [arg3]]])
fn.apply(obj [, argArray])
call和apply函数都是原型链中自带的方法,都可以改变执行函数的this指向,只不过接收的参数不同,call可以接收多个参数,apply接收数组参数。
简单的说,就是给obj增加一个fn属性并调用他
function add(c, d) {
return this.a + this.b + c + d
}
var obj = {
a: 1,
b: 2
}
// 给obj增加add属性,并调用它 add中的lthis指向obj
console.log(add.call(obj, 5, 6)) // 1+2+5+6=14
console.log(add.apply(obj, [10, 20])) // 1+2+10+20=32
- bind方法 fn.bind(obj) 也相当于给obj增加了一直fn属性,返回一个方法,并且这个方法的指向永远是obj
function fn() {
return this.a
}
var bindFn = fn.bind({
a: 'jsong'
})
console.log(bindFn()) // jsong
var againFn = bindFn.bind({
a: 'haha'
})
console.log(againFn()) // jsong bind只生效一次!
var obj = {
a: 22,
f1: bindFn(),
f2: againFn()
}
console.log(obj.a, obj.f1, obj.f2) // 22, jsong, jsong
- 箭头函数 ,this与封闭词法环境的this保持一致,也就是被创建时的环境
const globalThis = this
const fn = () => this
console.log(fn() === globalThis) //true
const obj = {
fn: fn
}
// 无论怎么改变fn的调用方式,this的指向始终保持不变
console.log(obj.fn() === globalThis) // true
console.log(fn.call(obj) === globalThis) // true
console.log(fn.apply(obj) === globalThis) // true
const fnn = fn.bind(obj)
console.log(fnn() === globalThis) // true