一、理解 this
1、this 在定义时无法确定值,要在执行时才能确定。
2、箭头函数使 this 指向全局对象。
当前,在chrome浏览器下测试一下代码,当前的 url 地址为 https://www.baidu.com
同理,也可以放在本地 Node 环境中测试
let a = {
origin: 'A',
fn1: function() {
console.log(this, this.origin) //定义时
},
//
fn2() {
console.log(this, this.origin)
},
// 使用箭头函数
fn3: () => {
console.log(this, this.origin)
},
}
a.fn1() //执行结果: A; this === a
a.fn1.call({origin: 'B'}) //执行结果: B; this === {origin: 'B'}
//
a.fn2() //执行结果: A; this === a
a.fn2.call({origin: 'B'}) //执行结果: B; this === {origin: 'B'}
// 箭头函数
a.fn3() //执行结果:https://www.baidu.com; this === window
a.fn3.call({origin: 'B'}) //执行结果:https://www.baidu.com; this === window
// 更改执行者
let fn4 = a.fn1
fn4() //执行结果:https://www.baidu.com; this === window
复制代码
this 指向
this指向「其所在的{}」的归属者(往上层找,最近的一个对象),唯独箭头函数除外
let a = {
name: 'A',
b: {
name: 'B',
fn: function () {
// 若此处改为箭头函数,this则指向全局对象
console.log(this.name)
}
},
fn: function () {
console.log(this.name)
}
}
a.fn() //执行结果: A; this === a
a.b.fn() //执行结果: B; this === b
复制代码
注意
箭头函数中this的上下文
二、this 的用途
1、作为构造函数执行
2、作为对象属性执行
3、作为普通函数执行
4、call & apply & bind
2.1 作为构造函数执行
function People(name, age) {
this.name = name
this.age = age
}
var p = new People('A粒麦子', 17)
复制代码
2.2 作为对象属性执行
var p1 = {
name: 'P1',
age: 17,
printName: function () {
// 若此处改为箭头函数,this则指向全局对象
console.log(this.name)
}
}
复制代码
2.3 作为普通函数执行
function fn(name, age) {
console.log(name, age)
console.log(this) //
}
fn('A粒麦子', 17)
复制代码
2.4 call & apply & bind 三者的用法
对比三种的写法(效果相同),call、apply的写法最简易,而 bind 的写法最复杂。
推荐都用 call,除了传入的参数为数组时考虑用 apply。
function fn(name, age) {
console.log(name, age)
console.log(this)
}
fn('A粒麦子', 17) // this对应的执行结果:全局对象
fn.call({ctx: 'this in call'}, 'A粒麦子', 17) // this对应的执行结果:{ctx: "this in call"}
fn.apply({ctx: 'this in apply'}, ['A粒麦子', 17]) // this对应的执行结果:{ctx: "this in apply"}
let fn1 = function (name, age) {
console.log(name, age)
console.log(this)
}.bind({ctx: 'this in bind'})
fn1('A粒麦子', 17) // this对应的执行结果:{ctx: "this in bind"}
复制代码