this 是执行上下文环境的一个属性,解析器在调用函数时会将 this 做为参数隐式传入函数内部,根据函数调用方式的不同 this 会指向不同的对象(即函数执行时决定)
window.auntie = '漂亮阿姨';
function callAuntie () {
console.log('call:', this.auntie);
// function 內的 function
function callAgainAuntie () {
console.log('call again:', this.auntie);
}
callAgainAuntie();
}
callAuntie();
//无论在哪一层,纯粹的调用方式 this 都会指向 window。
顶层对象
顶层对象(浏览器环境指 window、Node.js 环境指 Global)的属性和全局变量属性的赋值是相等价的,使用 var 和 function 声明的是顶层对象的属性,而 let 就属于 ES6 规范了,但是 ES6 规范中 let、const、class 这些声明的全局变量,不再属于顶层对象的属性。
function demo(){
console.log(this.a); // 1
}
var a = 1;
demo();
function demo(){
console.log(this.a); // undefined
}
let a = 1;
demo();
2.隐式绑定 ->> 以方法的形式调用
this 是调用方法的对象
function callName() {
console.log(this.name);
}
var name = '全域阿婆';
var auntie = {
name: '漂亮阿姨',
callName: callName
// 這裡的 function 指向全域的 function,但不重要
}
callName() // '全域阿婆'
auntie.callName() // '漂亮阿姨',以方法的形式调用时,this是调用方法的对象
function child() {
console.log(this.name);
}
let parent = {
name: 'zhangsan',
child,
}
let parent2 = parent.child;
var name = 'lisi';
parent2(); // 'lisi'
3.new绑定 ->> 以构造函数的形式调用
this是新创建的那个对象
function Fruit(name){
this.name = name;
}
const f1 = new Fruit('apple');
const f2 = new Fruit('banana');
console.log(f1.name, f2.name); // apple banana
4.显示绑定
使用 call()、apply()、bind()等方法,强制绑定调用
function fruit(...args){
console.log(this.name, args);
}
var apple = {
name: '苹果'
}
var banana = {
name: '香蕉'
}
fruit.call(banana, 'a', 'b') //'苹果' [ 'a', 'b' ]
fruit.apply(apple, ['a', 'b']) // '香蕉' [ 'a', 'b' ]
function fruit(){
console.log(this.name);
}
var apple = {
name: '苹果'
}
fruit = fruit.bind(apple);
fruit(); // 苹果
优先级
new 绑定 -> 显示绑定 -> 隐式绑定 -> 默认绑定
箭头函数
箭头函数没有单独的 this 值,导致内部的 this 就是外层代码块的 this
const obj = {
x: 1,
hello: function(){
// 這邊印出來的 this 是什麼,test 的 this 就是什麼
// 在宣告它的地方的 this 是什麼,test 的 this 就是什麼
console.log(this)
const test = () => {
console.log(this.x)
}
test()
}
}
obj.hello() // 1
const hello = obj.hello
hello() // undefined
不要在原型链上定义箭头函数,可能会造成 this 对象的错误理解
function Fruit(name) {
this.name = name;
}
Fruit.prototype.info = () => {
console.log(this.name);
}
var name = 'Banana'
const f1 = new Fruit('Apple');
f1.info(); //'Banana'
箭头函数的一些特征:
- 没有 this
- 没有 arguments
- 不能使用 new 进行调用,箭头函数没有[[Construct]]方法,所以不能被用作构造函数
- 不存在 prototype 这个属性
- 没有 super
箭头函数
=>
没有创建任何绑定。箭头函数只是没有this
。this
的查找与常规变量的搜索方式完全相同:在外部词法环境中查找。