## 普通函數在不同的執行環境下,this指向
this是什么,是和執行上下文綁定的,也就是說每個執行上下文中都有一個 this。
### 1、在全局中,指向window
``` js
// 普通函數
function fn(){
console.log(this)
}
fn() // Window?{postMessage: ?, blur: ?, focus: ?, close: ?, parent: Window,?…}
```
``` js
// 箭頭函數
var fn = ()=>{
console.log(this)
}
fn() // Window?{postMessage: ?, blur: ?, focus: ?, close: ?, parent: Window,?…}
```
在全局中,指向就沒有什么可說的,都是window對象
### 2、普通對象下的函數,不同的執行環境
#### 2.1當普通函數被普通對象的屬性(方法)調用
``` js
// 普通函數
var obj = {
a: 123,
fn: function(){
console.log(this)
}
}
var obj2 = obj.fn
obj2() // Window?{postMessage: ?, blur: ?, focus: ?, close: ?, parent: Window,?…}
obj.fn() // {a: 123, fn: ?}
```
``` js
// 箭頭函數
var obj = {
a: 123,
fn: () => {
console.log(this)
}
}
var obj2 = obj.fn
obj2() // Window?{postMessage: ?, blur: ?, focus: ?, close: ?, parent: Window,?…}
obj.fn() // Window?{postMessage: ?, blur: ?, focus: ?, close: ?, parent: Window,?…}
```
當普通函數被普通對象的屬性(方法)調用,則this執行這個普通對象obj;
當箭頭函數被普通對象的屬性(方法)調用,則this指向window對象。
#### 2.2 注意高階函數,先后執行的環境有所變化時,this執行跟隨變化
注:可通過abc進行改變指向(apply、bind、call)
```
var a = 'window'
var obj = {
a: 123,
fn:function(){
console.log('fn的this:',this,this.a)
return function(){
console.log('匿名:',this,this.a)
}
},
cn:function (){
return ()=>{
console.log('匿名箭頭:',this,this.a)
}
}
}
var obj_fn = obj.fn
var obj_cn = obj.cn
obj_fn()() // 結果如下圖
obj_cn()()
obj.fn()()
obj.cn()()
```

#### 2.3定義_that指向fn的this
```
// 普通函數
var a = 'window'
var obj = {
a: 123,
fn:function(){
var _that = this
console.log('fn的this:',this,',this.a:',this.a)
return function(){
console.log('匿名:',',this: ',this,',_that: ',_that)
}
}
}
var obj2 = obj.fn
obj2()()
obj.fn()()
```

``` js
// 箭頭函數
var a = 'window'
var obj = {
a: 123,
fn:function(){
var _that = this
console.log('fn的this:',this,',this.a:',this.a)
return ()=>{
console.log('匿名:',',this: ',this,',_that: ',_that)
}
}
}
var obj2 = obj.fn
obj2()()
obj.fn()() // _that在這里最容易犯錯了
```

#### 2.4全局變量累計
```js
var a = 1;
window.b = 2
var obj = {
a: 2,
b: 4,
ab:function(){ // 此處換成箭頭函數,會怎么樣呢?
this.a+=5;
a+=8
this.b+=5
b+=8
console.log(a,b,this.a,this.b,'a-----b')
}
}
obj.ab(); // 9 10 7 9 "a-----b"
console.log('ab:',a,b,this.a,this.b) // ab: 9 10 9 10
var fn = obj.ab;
fn() // 22 23 22 23 "a-----b"
console.log('ab-fn:',a,b,this.a,this.b) // ab-fn: 22 23 22 23
```
分析:
1、`obj.ab(); `時,a和this.a區別就是一個全局window.a(既var a),一個普通對象obj.a(this.a);
2、`console.log('ab:',a,b,this.a,this.b) `時,可通過window===this、window.a=a理解,故都是a===this.a理解,記住此時a=9、b=10;
3、`var fn = obj.ab;fn() `時,*fn執行環境時window*,那此時this.a等于什么呢?又等于什么呢?可以這樣理解window.a=this.a=a,故a=9+5+8,b=10+5+8
ab函數換成箭頭函數,則函數內:`var a = window.a=this.a`了。
#### 2.5內層函數不會繼承上層函數this
```
var obj = {
ab:function(){
console.log('ab:',this)
function fn(){
console.log('fn:',this)
}
fn()
}
}
obj.ab() // 結果圖下 fn 不會繼承ab()的this
var out = obj.ab
out()
```

### 總結:
普通函數this指向,取決于調用時的環境在哪里;
箭頭函數this指向,取決于父級上下文環境在哪里;
注:箭頭函數并不會創建其自身的執行上下文,所以箭頭函數中的 this 取決于它的外部函數。
- 首頁
- 2021年
- 基礎知識
- 同源策略
- 跨域
- css
- less
- scss
- reset
- 超出文本顯示省略號
- 默認滾動條
- 清除浮動
- line-height與vertical-align
- box-sizing
- 動畫
- 布局
- JavaScript
- 設計模式
- 深淺拷貝
- 排序
- canvas
- 防抖節流
- 獲取屏幕/可視區域寬高
- 正則
- 重繪重排
- rem換算
- 手寫算法
- apply、call和bind原理與實現
- this的理解-普通函數、箭頭函數
- node
- nodejs
- express
- koa
- egg
- 基于nodeJS的全棧項目
- 小程序
- 常見問題
- ec-canvas之橫豎屏切換重繪
- 公眾號后臺基本配置
- 小程序發布協議更新
- 小程序引入iconfont字體
- Uni-app
- 環境搭建
- 項目搭建
- 數據庫
- MySQL數據庫安裝
- 數據庫圖形化界面常用命令行
- cmd命令行操作數據庫
- Redis安裝
- APP
- 控制縮放meta
- GIT
- 常用命令
- vsCode
- 常用插件
- Ajax
- axios-services
- 文章
- 如何讓代碼更加優雅
- 虛擬滾動
- 網站收藏
- 防抖節流之定時器清除問題
- 號稱破解全網會員的腳本
- 資料筆記
- 資料筆記2
- 公司面試題
- 服務器相關
- 前端自動化部署-jenkins
- nginx.conf配置
- https添加證書
- shell基本命令
- 微型ssh-deploy前端部署插件
- webpack
- 深入理解loader
- 深入理解plugin
- webpack注意事項
- vite和webpack區別
- React
- react+antd搭建
- Vue
- vue-cli
- vue.config.js
- 面板分割左右拖動
- vvmily-admin-template
- v-if與v-for那個優先級高?
- 下載excel
- 導入excel
- Echart-China-Map
- vue-xlsx(解析excel)
- 給elementUI的el-table添加骨架
- cdn引入配置
- Vue2.x之defineProperty應用
- 徹底弄懂diff算法的key作用
- 復制模板內容
- 表格操作按鈕太多
- element常用組件二次封裝
- Vue3.x
- Vue3快速上手(第一天)
- Vue3.x快速上手(第二天)
- Vue3.x快速上手(第三天)
- vue3+element-plus搭建項目
- vue3
- 腳手架
- vvmily-cli
- TS
- ts筆記
- common
- Date
- utils
- axios封裝
- 2022年
- HTML
- CSS基礎
- JavaScript 基礎
- 前端框架Vue
- 計算機網絡
- 瀏覽器相關
- 性能優化
- js手寫代碼
- 前端安全
- 前端算法
- 前端構建與編譯
- 操作系統
- Node.js
- 一些開放問題、智力題