this 在前端是一個難點,也是一個痛點。首先this在聲明的時候是不肯定的,只有在被調用了以後才知道this的指向。主要有一下集中調用方式:
複製代碼
1: 函數名()直接調用 此時的this指向window
```
function fn() {
var name = '我是fn裏面的name'
console.log(this.name)
}
var name = '我是window裏面的name'
fn()
window.fn()
// 結果
我是window裏面的name
我是window裏面的name
```
複製代碼
2: window下默認的函數如:setTimeout this也指向window
```
setTimeout(function() {
var name = '我是setTimeout裏面的name'
console.log(this.name)
}, 1000)
var name = '我是window裏面的name'
// 結果
我是window裏面的name
```
複製代碼
3: Object.函數名()的調用 此時的this指向該Object
```
var name = '我是window裏面的name'
var obj = {
name: '我是obj裏面的name',
getName: function() {
console.log(this.name)
}
}
obj.getName()
var temp = obj.getName
temp()
// 結果
我是obj裏面的name
我是window裏面的name (聲明一個全局變量temp而後將函數賦值給它,最後經過window調用)var name = '我是window裏面的name'
var obj = {
name: '我是obj裏面的name',
getName: function() {
console.log(this.name)
}
}
obj.getName()
var temp = obj.getName
temp()
// 結果
我是obj裏面的name
我是window裏面的name (聲明一個全局變量temp而後將函數賦值給它,最後經過window調用)s
```
複製代碼
4: new運算符中的this指向該實例
```
var name = '我是window裏面的name'
function Fn() {
this.name = '我是Fn函數裏面的name'
this.getName = function() {
console.log(this.name)
}
}
var fn1 = new Fn()
var temp = fn1.getName
fn1.getName()
temp()
// 結果
我是Fn函數裏面的name
我是window裏面的name (聲明一個全局變量temp而後將函數賦值給它,最後經過window調用)
```
複製代碼
5: 數組元素爲函數時,經過數組來調用函數,此時的this爲該數組
```
function yideng(a, b, c) {
console.log(this.length)
console.log(this.callee.length)
}
function fn(d) {
arguments[0](10, 20, 30, 40, 50)
}
fn(yideng, 10, 20, 30)
// 結果
4
1 (callee是arguments對象的一個屬性,指向當前執行的那個函數)
```
複製代碼
6: bind,call,apply 對 this 的從新綁定,this都指向第一個參數
```
function fn() {
var name = '我是fn裏面的name'
console.log(this.name)
}
var name = '我是window裏面的name'
fn()
fn.bind({name: '我是bind裏面的name哦'})() // 注意bind以後返回的是一個函數哦
fn.call({name: '我是call裏面的name哦'})
fn.apply({name: '我是apply裏面的name哦'})
// 結果
我是window裏面的name
我是bind裏面的name哦
我是call裏面的name哦
我是apply裏面的name哦
```
複製代碼
7: 箭頭函數中this指向最近一層中的this,不決定於誰調用
```
function fn() {
var name = '我是fn裏面的name'
console.log(this.name)
function fn2() {
console.log(this.name)
}
fn2()
}
fn.call({name: '我是call裏面的name哦'})
// 結果
我是call裏面的name哦
我是window裏面的name
function fn() {
var name = '我是fn裏面的name'
console.log(this.name)
var fn2 = () => {
console.log(this.name)
}
fn2()
}
fn.call({name: '我是call裏面的name哦'})
// 結果
我是call裏面的name哦
我是call裏面的name哦
```複製代碼