欧美bbbwbbbw肥妇,免费乱码人妻系列日韩,一级黄片

js中的this作用域全解析

 更新時(shí)間:2022年10月18日 15:03:41   作者:bye_cherry  
這篇文章主要介紹了js中的this作用域全解析,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教

this作用域問題

一般來說,誰調(diào)指誰是一個(gè)基本原則,但是js和其他面向?qū)ο笳Z言稍微有些區(qū)別,雖然從某種程度上,這有助于幫我們判斷this指向問題,但是并不能涵蓋所有的情況,建議從函數(shù)調(diào)用的5種方式展開

  • 1.函數(shù)式調(diào)用
  • 2.方法調(diào)用模式
  • 3.構(gòu)造函數(shù)調(diào)用模式(this指向?qū)嵗?/li>
  • 4.call、apply、bind
  • 5.特殊情況——箭頭函數(shù)

函數(shù)式調(diào)用

var age = 10
var person = {
  age:12,
  say(){
    function f(){
      console.log(this.age)
    }
    f()
  }
}
person.say()// 10

以此模式調(diào)用函數(shù)時(shí),this被綁定到全局對(duì)象。這是語言設(shè)計(jì)上的一個(gè)錯(cuò)誤。倘若語言設(shè)計(jì)正確,那么當(dāng)內(nèi)部函數(shù)被調(diào)用時(shí),this應(yīng)該仍然綁定到外部函數(shù)的this變量。這個(gè)設(shè)計(jì)錯(cuò)誤的后果就是方法不能利用內(nèi)部函數(shù)來幫助它工作,因?yàn)閮?nèi)部函數(shù)的this被綁定了錯(cuò)誤的值(全局對(duì)象),所以不能共享該方法對(duì)對(duì)象的訪問權(quán)。

這種情況是不遵從所謂誰調(diào)指誰原則的

解決方法,內(nèi)部函數(shù)外使用一個(gè)變量保存this

var age = 10
var person = {
  age:12,
  say(){
    var that = this
    function f(){
      console.log(that.age)
    }
    f()
  }
}
person.say()// 12

方法調(diào)用模式

當(dāng)一個(gè)函數(shù)被保存為對(duì)象的一個(gè)屬性時(shí),我們稱它為一個(gè)方法。當(dāng)一個(gè)對(duì)象的方法被調(diào)用時(shí),this被綁定到調(diào)用方法的對(duì)象。

var age = 10
var person = {
  age:12,
  say(){
    console.log(this.age)
  }
}
person.say()// 12

這就有點(diǎn)像所謂的誰調(diào)指誰

在數(shù)組中的特例

var arr=[
  function(){
    console.log(this)
  },
  1,
  2,
]
arr[0]()
//輸出結(jié)果
[f, 1, 2]

很顯然,數(shù)組其實(shí)也是對(duì)象,雖然這種調(diào)用方式在寫法上可能更加貼近函數(shù)調(diào)用模式,但是從打印結(jié)果來看,這很顯然屬于方法調(diào)用模式有點(diǎn)類似于arr.0()

反過來想,方法調(diào)用模式也可以寫成

person['say']()

構(gòu)造器調(diào)用模式

如果在一個(gè)函數(shù)前面帶上 new 關(guān)鍵字來調(diào)用,那么背地里將會(huì)創(chuàng)建一個(gè)連接到該函數(shù)的prototype成員的新對(duì)象,同時(shí)this會(huì)被綁定到那個(gè)新對(duì)象上。

function foo(){
  console.log('this is' + this)
}
new foo()
// this is [object]

new 前綴也會(huì)改變r(jià)eturn 語句的行為,如果return 的值是對(duì)象,那么將會(huì)將這個(gè)對(duì)象返回,否則將返回默認(rèn)創(chuàng)建的新對(duì)象。

function foo(){
  console.log('this is ' + this.a)
  const obj = {
    a:1
  }
  return obj
}
const f1 = new foo()
console.log(f1.a) 
// this is undefied
// 1

新知識(shí)點(diǎn),買一送一

這里可以看到,雖然返回的實(shí)例中確實(shí)有屬性a,但是在代碼執(zhí)行上仍然存在先后順序

call、apply、bind

沒什么好講的,更改作用域

特殊情況——箭頭函數(shù)

箭頭函數(shù)作為函數(shù)式調(diào)用設(shè)計(jì)失誤的解決方案而提出(例a如下)

var age = 10
var person = {
  age:12,
  say(){
    var f=()=>{
      console.log(this.age)
    }
    f()
  }
}
person.say()// 12

箭頭函數(shù)的特點(diǎn)中有一點(diǎn)是函數(shù)體內(nèi)的this對(duì)象,就是定義時(shí)所在的對(duì)象,而不是使用時(shí)所在的對(duì)象。

所以call、apply、bind對(duì)箭頭函數(shù)是不起作用的

var age = 10
var person = {
  age:12,
  say(){
    var f=()=>{
      console.log(this.age)
    }
    f.call({age:9})
  }
}
person.say()// 12

再看下面的例子

var age = 10
var person = {
  age:12,
  say:()=>{
    console.log(this.age)
  }
}
person.say()// 10

這是因?yàn)閷?duì)象不構(gòu)成單獨(dú)的作用域,導(dǎo)致say箭頭函數(shù)定義時(shí)的作用域就是全局作用域。阮一峰的es6教程中也有相關(guān)內(nèi)容。

最后一個(gè)例子

var age = 10
var person = {
  age:12,
  say:()=>{
    console.log(this.age)
  }
}
var person1 = {
  age:13,
  say(){
    var f=person.say
    f()
  }
}
person1.say()// 10

這個(gè)例子看起來和例a很像,內(nèi)層函數(shù)f是一個(gè)箭頭函數(shù),雖然是person的一個(gè)屬性,那么結(jié)果是不是13呢,然而并不是,還是緊扣箭頭函數(shù)特征:函數(shù)體內(nèi)的this對(duì)象,就是定義時(shí)所在的對(duì)象,而不是使用時(shí)所在的對(duì)象。

該例中,person.say定義時(shí)在person內(nèi),對(duì)象不構(gòu)成單獨(dú)作用域,所以person.say定義時(shí)的作用域是全局作用域,所以f被調(diào)用時(shí)打印的結(jié)果為全局變量age=10

綜合例題

var length = 10;
function fn(){
  console.log(this.length)
}
var obj = {
  length: 5,
  method: function(fn){
    fn()
    arguments[0]()
  }
}
obj.method(fn, 1)
// 輸出結(jié)果
// 10
// 2
// 如果注釋掉第一行代碼 輸出結(jié)果
// 0
// 2

(1)首先如果不注釋第一行代碼,obj調(diào)用自己的method方法,傳了兩個(gè)參數(shù),第一個(gè)是在全局定義的函數(shù)fn,第二個(gè)參數(shù)是number類型的常量

進(jìn)入method,立即調(diào)用fn,因?yàn)閒n是一個(gè)函數(shù)式調(diào)用,所以this指向全局,也就是window,打印結(jié)果是10

再看接下來執(zhí)行的arguments[0](),arguments是一個(gè)數(shù)組,表示函數(shù)的實(shí)參列表,也就是說這個(gè)數(shù)組中包含兩個(gè)元素,第一個(gè)是傳進(jìn)去的fn,第二個(gè)是傳進(jìn)去的常量1,然后它調(diào)用了第0個(gè)元素表示的函數(shù),所以這里是方法調(diào)用模式中的特例,作為數(shù)組元素被調(diào)用,this指向數(shù)組本身,我們經(jīng)常會(huì)忽略數(shù)組中其實(shí)默認(rèn)是有l(wèi)ength屬性的,即使在寫for循環(huán)的時(shí)候經(jīng)常會(huì)用,數(shù)組長(zhǎng)度為2,所以打印結(jié)果是2

(2)如果注釋了第一行代碼,不在全局定義length屬性,正常分析,length未定義,返回undefined,那么答案就錯(cuò)了,事實(shí)上,全局window是有l(wèi)ength屬性的,默認(rèn)值為0

這就是這道題隱藏最深的點(diǎn)了

以上為個(gè)人經(jīng)驗(yàn),希望能給大家一個(gè)參考,也希望大家多多支持腳本之家。

相關(guān)文章

最新評(píng)論