日本综合一区二区|亚洲中文天堂综合|日韩欧美自拍一区|男女精品天堂一区|欧美自拍第6页亚洲成人精品一区|亚洲黄色天堂一区二区成人|超碰91偷拍第一页|日韩av夜夜嗨中文字幕|久久蜜综合视频官网|精美人妻一区二区三区

RELATEED CONSULTING
相關(guān)咨詢
選擇下列產(chǎn)品馬上在線溝通
服務(wù)時(shí)間:8:30-17:00
你可能遇到了下面的問題
關(guān)閉右側(cè)工具欄

新聞中心

這里有您想知道的互聯(lián)網(wǎng)營銷解決方案
你真的知道JavaScript中的“this”嗎?

介紹

在前端面試過程中,面試官經(jīng)常會(huì)問一些關(guān)于this關(guān)鍵字的問題,即使是工作多年的人也可能知之甚少。因此,本文對(duì)this關(guān)鍵字進(jìn)行了詳細(xì)分析,以便他人深入了解。

站在用戶的角度思考問題,與客戶深入溝通,找到個(gè)舊網(wǎng)站設(shè)計(jì)與個(gè)舊網(wǎng)站推廣的解決方案,憑借多年的經(jīng)驗(yàn),讓設(shè)計(jì)與互聯(lián)網(wǎng)技術(shù)結(jié)合,創(chuàng)造個(gè)性化、用戶體驗(yàn)好的作品,建站類型包括:網(wǎng)站設(shè)計(jì)制作、成都網(wǎng)站制作、企業(yè)官網(wǎng)、英文網(wǎng)站、手機(jī)端網(wǎng)站、網(wǎng)站推廣、國際域名空間、網(wǎng)站空間、企業(yè)郵箱。業(yè)務(wù)覆蓋個(gè)舊地區(qū)。

什么是"this"?

調(diào)用函數(shù)時(shí),將創(chuàng)建一個(gè)執(zhí)行環(huán)境,this 在運(yùn)行時(shí)根據(jù)函數(shù)的執(zhí)行環(huán)境綁定。它允許函數(shù)在內(nèi)部引用上下文中的執(zhí)行變量,使函數(shù)編程更加優(yōu)雅和簡潔。

看看下面的代碼,想想為什么不同的調(diào)用方法會(huì)打印出不同的結(jié)果。

var a = 10


const obj = {
a: 20,
foo: function() {
console.log(this.a)


return function() {
console.log(this.a)
}
}
}


obj.foo()() // 20 10
const fn = obj.foo
fn() // 10

其實(shí)很簡單,因?yàn)椴煌恼{(diào)用方法的this指向不同的點(diǎn)。為什么這指向不同的函數(shù)調(diào)用方法?是什么決定了這一點(diǎn)?現(xiàn)在讓我們開始帶著問題深入了解這個(gè)問題!

“this”的約束規(guī)則

默認(rèn)綁定

默認(rèn)綁定規(guī)則下,函數(shù)的運(yùn)行環(huán)境為全局環(huán)境,this默認(rèn)指向Window。

默認(rèn)綁定規(guī)則如下:

1、this指向Window的全局函數(shù)

在全局函數(shù)中直接打印 this 時(shí),可以看到 this 指向 Window。

2、獨(dú)立函數(shù)調(diào)用this指向Window

獨(dú)立的函數(shù)調(diào)用,即直接調(diào)用函數(shù),如 foo()。

function foo() {
console.log(this);
}


foo()

這里的foo默認(rèn)鏈接到Window,相當(dāng)于window.foo()。根據(jù)函數(shù)的隱式綁定規(guī)則,誰調(diào)用誰就指向誰。這里的 this 指向 Window。結(jié)果如下:

同樣,如果嵌套函數(shù)中直接調(diào)用的函數(shù)也是獨(dú)立的函數(shù)調(diào)用,那么this也指向Window:

var a = 10
var obj = {
a: 20,
foo: function() {
console.log(this); // {a: 20, foo: ?}
console.log(this.a); // 20


function son() {
console.log(this); // Window
console.log(this.a); // 10
}
// Independent function call
son()
}
}


obj.foo()

在上面的代碼中,子函數(shù)son也嵌套在對(duì)象obj的方法foo中。當(dāng)直接調(diào)用子方法時(shí),子里面的this指向Window,所以子函數(shù)里面的this.a結(jié)果是全局變量a,也就是10。

如果要在子函數(shù)中使用 obj 中的變量 a 怎么辦?只需將 this 對(duì)象分配給另一個(gè)變量,并在子方法中引用此變量:

var a = 10
var obj = {
a: 20,
foo: function() {
const that = this


function son() {
console.log(that.a); // 20
}
son()
}
}


obj.foo()

3、對(duì)于自執(zhí)行函數(shù)調(diào)用,this指向window

自執(zhí)行函數(shù),顧名思義,就是定義函數(shù)后自動(dòng)調(diào)用的函數(shù),自執(zhí)行函數(shù)的this指向如下代碼:

// exp1
(function() {
console.log(this); // Window
})()


// exp2
var a = 10
function foo() {
(function son(that) {
console.log(this); // Window
console.log(that); // {a: 20, foo: ?}
})(this)
}


var obj = {
a: 20,
foo: foo,
}


obj.foo()

上面代碼中的foo函數(shù)內(nèi)部嵌套了一個(gè)自執(zhí)行函數(shù)son,而son內(nèi)部的this指向Window。這里this指向的原理類似于獨(dú)立函數(shù)調(diào)用,即先聲明一個(gè)son方法,然后通過son()執(zhí)行該函數(shù)。如果要獲取son中上層對(duì)象obj的變量,可以在調(diào)用時(shí)將this點(diǎn)作為參數(shù)傳遞給自執(zhí)行函數(shù)son。

4、閉包里面的this指向Window

閉包可以理解為一個(gè)函數(shù)內(nèi)部定義的函數(shù),可以訪問其他函數(shù)的內(nèi)部變量。當(dāng)我們查看閉包中的 this 點(diǎn)時(shí),我們可以看到 this 指向 Window。

var a = 10


var obj = {
a: 20,
foo: function() {
var sum = this.count + 10


console.log(this.a); // 20
return function() {
console.log(this.a); // 10
return sum
}
}
}


obj.foo()()

上面代碼中,foo函數(shù)的第一個(gè)this.a的this指向obj對(duì)象,所以結(jié)果是20。return函數(shù)調(diào)用的this指向Window,結(jié)果是10。obj.foo ()() 可以理解為:

const fn = obj.foo()
fn()

fn 是 obj.foo() 返回的函數(shù)。fn 函數(shù)是獨(dú)立調(diào)用的,this 指向 Window。

隱式綁定

當(dāng)函數(shù)作為方法調(diào)用時(shí),this指向函數(shù)的直接父對(duì)象,稱為隱式綁定。

在隱式綁定規(guī)則中,認(rèn)為 this 指向調(diào)用函數(shù)的人,并將指向函數(shù)的直接父對(duì)象。比如obj.foo()中foo函數(shù)里面的this指向obj,而obj1中的foo函數(shù)。obj2.foo() 指向 obj2。

var a = 10
function foo () {
console.log(this.a);
}


var obj = {
a: 20,
foo: foo,
obj2: {
a: 30,
foo: foo
}
}


// exp1
foo() // 10


// exp2
obj.foo() // 20


// exp3
obj.obj2.foo() // 30

上面的代碼也是對(duì) foo 函數(shù)的調(diào)用。調(diào)用方法不同,結(jié)果不同。

‘exp1’中的foo直接被獨(dú)立函數(shù)調(diào)用,所以,this指向Window,結(jié)果為10;‘exp2’中的調(diào)用方法是obj。foo(),foo函數(shù)的this指向上級(jí)調(diào)用對(duì)象obj;結(jié)果是 20。'exp3' 中 foo 函數(shù)的直接上級(jí)對(duì)象是 obj2,所以結(jié)果是 30。

隱式綁定丟失

隱式綁定丟失意味著隱式綁定的函數(shù)丟失了它的綁定對(duì)象,所以默認(rèn)綁定到Window。這種方法在我們的項(xiàng)目中很容易導(dǎo)致錯(cuò)誤,但也很常見。

1、隱式綁定的函數(shù)被分配為沒有 this 指向的變量。

在下面的代碼中,obj下的foo值實(shí)際上是foo函數(shù)的地址信息,并不是真正的foo函數(shù)。當(dāng) obj.調(diào)用 foo() 時(shí), this 的 this 隱式綁定到 obj。當(dāng) var fn=obj.foo 為 fn 分配一個(gè)函數(shù)時(shí)。相當(dāng)于把foo函數(shù)的地址賦給fn。這時(shí)候fn沒有和obj關(guān)聯(lián),所以這里fn()的運(yùn)行環(huán)境就是全局環(huán)境,this指向Window,this的結(jié)果a 是 10。

var a = 10
var obj = {
a: 20,
foo: function () {
console.log(this.a);
}
}
function bar (fn) {
fn()
}


bar(obj.foo) // 10

2、隱式綁定的函數(shù)作為參數(shù)傳給函數(shù),丟失了this點(diǎn)。

當(dāng)一個(gè)隱式綁定的函數(shù)直接作為參數(shù)傳遞給另一個(gè)函數(shù)時(shí),這個(gè)綁定會(huì)丟失,從而指向全局Window。obj.foo作為參數(shù)傳給bar函數(shù)后,this.a的結(jié)果是10。這里bar(obj.foo)等價(jià)于var fn=obj.foo; bar(fn)。

var a = 10
var obj = {
a: 20,
foo: function () {
console.log(this.a);
}
}
function bar (fn) {
fn()
}


bar(obj.foo) // 10

3、內(nèi)置對(duì)象setTimeout和setInterval函數(shù)的隱式綁定丟失

內(nèi)置函數(shù) setTimeout 和 setInterval 的 this 默認(rèn)指向 Window。

// exp1
setTimeout(function() {
console.log(this); // Window
}, 1000)


// exp2
var a = 10
var obj = {
a: 20,
foo: function () {
console.log(this.a); // 10
}
}


setTimeout(obj.foo, 1000)

對(duì)了,當(dāng)setTimeout或者setInterval的第一個(gè)參數(shù)是箭頭函數(shù)時(shí),this會(huì)指向上層的函數(shù)執(zhí)行環(huán)境。代碼如下:

var a = 10
var obj = {
a: 20,
foo: function () {
console.log(this.a); // 20


setTimeout(() => {
console.log(this.a); // 20
}, 1000)


setTimeout(function() {
console.log(this.a); // 10
}, 1000);
}
}


obj.foo()

顯式綁定

當(dāng)我們要將函數(shù)綁定到指定對(duì)象時(shí),可以使用call、apply、bind等方法手動(dòng)改變this的方向,即顯式綁定。

在下面的代碼中,將 foo 顯式綁定到 p 對(duì)象的方法分別使用 call、apply 和 bind 來舉例說明。顯式綁定 call 和 apply 的方法會(huì)在顯式綁定后直接調(diào)用,而顯式綁定 this 到 bind 的方法需要手動(dòng)調(diào)用。

var obj = {
a: 20,
foo: function () {
console.log(this.a);
}
}
var p = {
a: 30,
}


obj.foo() // 20
obj.foo.call(p) // 30
obj.foo.apply(p) // 30


const fn = obj.foo.bind(p)
fn() // 30

關(guān)于硬裝訂

顯式綁定可以幫我們把this改成指定對(duì)象,但是不能解決隱式綁定缺失的問題,比如:

var a = 10
function foo() {
console.log(this.a);
}


var obj = {
a: 20,
foo: foo
}


var p = {
a: 30
}


function func(fn) {
fn()
}


func.call(p, obj.foo) // 10

在上面的代碼中,調(diào)用是綁定 this 指向 p 對(duì)象,但最終 this 指向的是 Window。此時(shí),我們可以通過硬綁定來解決這個(gè)問題。

var a = 10
function foo() {
console.log(this.a);
}


var obj = {
a: 20,
foo: foo
}


var p = {
a: 30
}


function func(fn) {
fn()
}


let bar = function () {
foo.call(p)
}
bar() // 30

“new”綁定

new綁定是我們常用的方法。事實(shí)上,我們可以創(chuàng)建一個(gè)構(gòu)造,然后新建一個(gè)實(shí)例對(duì)象。這時(shí)候this指向了new出來的實(shí)例對(duì)象。

當(dāng)我們彼此認(rèn)識(shí)時(shí),我們主要做以下事情:

  • a、創(chuàng)建一個(gè)新對(duì)象
  • b、讓這一點(diǎn)指向新對(duì)象并執(zhí)行構(gòu)造體
  • c、將新對(duì)象的 proto 屬性設(shè)置為指向構(gòu)造的原型對(duì)象
  • d、判斷構(gòu)造的返回類型。如果是,則返回新對(duì)象。如果它是引用類型,它將返回此類型的對(duì)象。

首先,創(chuàng)建了“Person”的構(gòu)造,然后,通過“new”創(chuàng)建了一個(gè)“zhangsan”的實(shí)例對(duì)象。在“zhangsan”的“foo”函數(shù)中,“this”指向“zhangsan”的實(shí)例。

function Person(name, age) {
this.name = name
this.age = age
this.foo = function () {
console.log(this.name);
}
}


const zhangsan = new Person('zhangsan', 18)
console.log(zhangsan) // {name: 'zhangsan', age: 18, foo: ?}
zhangsan.foo() // zhangsan

在嚴(yán)格模式下,“this”指向一個(gè)問題。

1.獨(dú)立調(diào)用函數(shù)的內(nèi)部“this”是“undefined”

function foo() {
"use strict"
console.log(this); undifined
}
foo()

2. “call()”和“apply()”中的this總是他們的第一個(gè)參數(shù)

var a = 10
var obj = {
a: 20,
foo: function () {
"use strict"
console.log(this);
}
}


// When null | undefined, in non-strict mode, this points to window
obj.foo.call(null) // null
obj.foo.call(undefined) // undefined
obj.foo.apply(null) // null
obj.foo.apply(undefined) // undefined
var fn = obj.foo.bind(null)
fn()

總結(jié)

這是一個(gè)比較復(fù)雜的知識(shí)點(diǎn)。當(dāng)然,如果我們真的理解了this的原理,那么遇到this所指出的問題就很簡單了。如果我們明白了這一點(diǎn),不僅可以為前端面試加分,也有利于我們的發(fā)展和學(xué)習(xí)。讓我們總結(jié)一下,其約束原則如下:

  • 默認(rèn)綁定,this指向全局Window。
  • 不要忘記隱藏綁定的丟失。
  • 它顯示了綁定。他通過使用 call、apply 和 bind 改變了這個(gè)方向。
  • new綁定,構(gòu)造new的一個(gè)實(shí)例,this指向new的實(shí)例對(duì)象。

網(wǎng)站欄目:你真的知道JavaScript中的“this”嗎?
轉(zhuǎn)載來于:http://www.dlmjj.cn/article/dpephei.html