this 是执行上下文环境的一个属性,解析器在调用函数时会将 this 做为参数隐式传入函数内部,根据函数调用方式的不同 this 会指向不同的对象(即函数执行时决定)
window.auntie = '漂亮阿姨';function callAuntie () {console.log('call:', this.auntie);// function 內的 functionfunction 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() // 1const hello = obj.hellohello() // 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的查找与常规变量的搜索方式完全相同:在外部词法环境中查找。
