日本不卡不码高清免费观看,久久国产精品久久w女人spa,黄色aa久久,三上悠亚国产精品一区二区三区

您的位置:首頁技術(shù)文章
文章詳情頁

JavaScript逐點(diǎn)突破系列之this是什么

瀏覽:28日期:2023-10-03 10:17:42
了解this

也許你在其他面向?qū)ο蟮木幊陶Z言曾經(jīng)看過this,也知道它會指向某個構(gòu)造器(constructor)所建立的對象。但事實(shí)上在JavaScript里面,this所代表的不僅僅是那個被建立的對象。

先來看看ECMAScript 標(biāo)準(zhǔn)規(guī)范對this 的定義:

「The this keyword evaluates to the value of the ThisBinding of the current execution context.」「this 這個關(guān)鍵字代表的值為當(dāng)前執(zhí)行上下文的ThisBinding。」

然后再來看看MDN 對this 的定義:

「In most cases, the value of this is determined by how a function is called.」「在大多數(shù)的情況下,this 其值取決于函數(shù)的調(diào)用方式。」

好,如果上面兩行就看得懂的話那么就不用再往下看了,Congratulations!

… 我想應(yīng)該不會,至少我光看這兩行還是不懂。

先來看個例子吧:

var getGender = function() { return people1.gender;};var people1 = { gender: ’female’, getGender: getGender};var people2 = { gender: ’male’, getGender: getGender};console.log(people1.getGender()); // femaleconsole.log(people2.getGender()); // female

what?怎么people2變性了呢,這不是我想要的結(jié)果啊,為什么呢?

因?yàn)間etGender()返回(return)寫死了people1.gender的關(guān)系,結(jié)果自然是’female’。

那么,如果我們把getGender稍改一下:

var getGender = function() { return this.gender;};

這個時候,你應(yīng)該會分別得到female與male兩種結(jié)果。

所以回到前面講的重點(diǎn),從這個例子可以看出,即便people1與people2的getGender方法參照的都是同一個getGender function,但由于調(diào)用的對象不同,所以執(zhí)行的結(jié)果也會不同

現(xiàn)在我們知道了第一個重點(diǎn),**this實(shí)際上是在函數(shù)被調(diào)用時發(fā)生的綁定,它指向什么完全取決于函數(shù)的調(diào)用方式。**如何的區(qū)分this呢?

this到底是誰

看完上面的例子,還是有點(diǎn)似懂非懂吧?那接下來我們來看看不同的調(diào)用方式對 this 值的影響。

情況一:全局對象&調(diào)用普通函數(shù)

在全局環(huán)境中,this 指向全局對象,在瀏覽器中,它就是 window 對象。下面的示例中,無論是否是在嚴(yán)格模式下,this 都是指向全局對象。

var x = 1console.log(this.x) // 1console.log(this.x === x) // trueconsole.log(this === window) // true

如果普通函數(shù)是在全局環(huán)境中被調(diào)用,在非嚴(yán)格模式下,普通函數(shù)中 this 也指向全局對象;如果是在嚴(yán)格模式下,this 將會是 undefined。ES5 為了使 JavaScript 運(yùn)行在更有限制性的環(huán)境而添加了嚴(yán)格模式,嚴(yán)格模式為了消除安全隱患,禁止了 this 關(guān)鍵字指向全局對象。

var x = 1function fn() { console.log(this); // Window 全局對象 console.log(this.x); // 1}fn();

使用嚴(yán)格模式后:

'use strict' // 使用嚴(yán)格模式var x = 1function fn() { console.log(this); // undefined console.log(this.x); // 報(bào)錯 'Cannot read property ’x’ of undefined',因?yàn)榇藭r this 是 undefined}fn(); 情況二:作為對象方法的調(diào)用

我們知道,在對象里的值如果是原生值(primitive type;例如,字符串、數(shù)值、布爾值),我們會把這個新建立的東西稱為「屬性(property)」;如果對象里面的值是函數(shù)(function)的話,我們則會把這個新建立的東西稱為「方法(method)」。

如果函數(shù)作為對象的一個方法時,并且作為對象的一個方法被調(diào)用時,函數(shù)中的this指向這個上一級對象

var x = 1var obj = { x: 2, fn: function() {console.log(this); console.log(this.x); }}obj.fn() // obj.fn()結(jié)果打印出;// Object {x: 2, fn: function}// 2var a = obj.fna() // a()結(jié)果打印出: // Window 全局對象// 1

在上面的例子中,直接運(yùn)行 obj.fn() ,調(diào)用該函數(shù)的上一級對象是 obj,所以 this 指向 obj,得到 this.x 的值是 2;之后我們將 fn 方法首先賦值給變量 a,a 運(yùn)行在全局環(huán)境中,所以此時 this 指向全局對象Window,得到 this.x 為 1。

我們再來看一個例子,如果函數(shù)被多個對象嵌套調(diào)用,this 會指向什么。

var x = 1var obj = { x: 2, y: { x: 3, fn: function() { console.log(this); // Object {x: 3, fn: function} console.log(this.x); // 3 } }}obj.y.fn();

為什么結(jié)果不是 2 呢,因?yàn)樵谶@種情況下記住一句話:this 始終會指向直接調(diào)用函數(shù)的上一級對象,即 y,上面例子實(shí)際執(zhí)行的是下面的代碼。

var y = { x: 3, fn: function() { console.log(this); // Object {x: 3, fn: function} console.log(this.x); // 3 }}var x = 1var obj = { x: 2, y: y}obj.y.fn();

對象可以嵌套,函數(shù)也可以,如果函數(shù)嵌套,this 會有變化嗎?我們通過下面代碼來探討一下。

var obj = { y: function() {console.log(this === obj); // trueconsole.log(this); // Object {y: function}fn();function fn() { console.log(this === obj); // false console.log(this); // Window 全局對象} }}obj.y();

在函數(shù) y 中,this 指向了調(diào)用它的上一級對象 obj,這是沒有問題的。但是在嵌套函數(shù) fn 中,this 并不指向 obj。嵌套的函數(shù)不會從調(diào)用它的函數(shù)中繼承 this,當(dāng)嵌套函數(shù)作為函數(shù)調(diào)用時,其 this 值在非嚴(yán)格模式下指向全局對象,在嚴(yán)格模式是 undefined,所以上面例子實(shí)際執(zhí)行的是下面的代碼。

function fn() { console.log(this === obj); // false console.log(this); // Window 全局對象}var obj = { y: function() {console.log(this === obj); // trueconsole.log(this); // Object {y: function}fn(); }}obj.y(); 情況三:作為構(gòu)造函數(shù)調(diào)用

我們可以使用 new 關(guān)鍵字,通過構(gòu)造函數(shù)生成一個實(shí)例對象。此時,this 便指向這個新對象

var x = 1;function Fn() {  this.x = 2; console.log(this); // Fn {x: 2}}var obj = new Fn(); // obj和Fn(..)調(diào)用中的this進(jìn)行綁定console.log(obj.x) // 2

使用new來調(diào)用Fn(..)時,會構(gòu)造一個新對象并把它(obj)綁定到Fn(..)調(diào)用中的this。還有值得一提的是,如果構(gòu)造函數(shù)返回了非引用類型(string,number,boolean,null,undefined),this 仍然指向?qū)嵗男聦ο蟆?/p>

var x = 1function Fn() { this.x = 2 return { x: 3 }}var a = new Fn()console.log(a.x) // 3

因?yàn)镕n()返回(return)的是一個對象(引用類型),this 會指向這個return的對象。如果return的是一個非引用類型的值呢?

var x = 1function Fn() { this.x = 2 return 3}var a = new Fn()console.log(a.x) // 2情況四:call 和 apply 方法調(diào)用

如果你想改變 this 的指向,可以使用 call 或 apply 方法。它們的第一個參數(shù)都是指定函數(shù)運(yùn)行時其中的this指向。如果第一個參數(shù)不傳(參數(shù)為空)或者傳 null 、undefined,默認(rèn) this 指向全局對象(非嚴(yán)格模式)或 undefined(嚴(yán)格模式)。

var x = 1;var obj = { x: 2}function fn() { console.log(this); console.log(this.x);}fn.call(obj)// Object {x: 2}// 2fn.apply(obj) // Object {x: 2}// 2fn.call() // Window 全局對象// 1fn.apply(null) // Window 全局對象// 1fn.call(undefined) // Window 全局對象// 1

使用 call 和 apply 時,如果給 this 傳的不是對象,JavaScript 會使用相關(guān)構(gòu)造函數(shù)將其轉(zhuǎn)化為對象,比如傳 number 類型,會進(jìn)行new Number()操作,如傳 string 類型,會進(jìn)行new String()操作,如傳 boolean 類型,會進(jìn)行new Boolean()操作。

function fn() { console.log(Object.prototype.toString.call(this))}fn.call(’love’) // [object String]fn.apply(1) // [object Number]fn.call(true) // [object Boolean]

call 和 apply 的區(qū)別在于,call 的第二個及后續(xù)參數(shù)是一個參數(shù)列表,apply 的第二個參數(shù)是數(shù)組。參數(shù)列表和參數(shù)數(shù)組都將作為函數(shù)的參數(shù)進(jìn)行執(zhí)行。

var x = 1var obj = { x: 2}function Sum(y, z) { console.log(this.x + y + z)}Sum.call(obj, 3, 4) // 9Sum.apply(obj, [3, 4]) // 9情況五:bind 方法調(diào)用

調(diào)用 f.bind(someObject) 會創(chuàng)建一個與 f 具有相同函數(shù)體和作用域的函數(shù),但是在這個新函數(shù)中,新函數(shù)的 this 會永久的指向 bind 傳入的第一個參數(shù),無論這個函數(shù)是如何被調(diào)用的。

var x = 1var obj1 = { x: 2};var obj2 = { x: 3};function fn() { console.log(this); console.log(this.x);};var a = fn.bind(obj1);var b = a.bind(obj2);fn();// Window 全局對象// 1a();// Object {x: 2}// 2b();// Object {x: 2}// 2a.call(obj2);// Object {x: 2}// 2

在上面的例子中,雖然我們嘗試給函數(shù) a 重新指定 this 的指向,但是它依舊指向第一次 bind 傳入的對象,即使是使用 call 或 apply 方法也不能改變這一事實(shí),即永久的指向 bind 傳入的第一次參數(shù)。

情況六:箭頭函數(shù)中this指向

值得一提的是,從ES6 開始新增了箭頭函數(shù),先來看看MDN 上對箭頭函數(shù)的說明

An arrow function expression has a shorter syntax than a function expression and does notbind its ownthis,arguments,super, ornew.target. Arrow functions are always anonymous. These function expressions are best suited for non-method functions, and they cannot be used as constructors.

這里已經(jīng)清楚了說明了,箭頭函數(shù)沒有自己的this綁定。箭頭函數(shù)中使用的this,其實(shí)是直接包含它的那個函數(shù)或函數(shù)表達(dá)式中的this。在前面情況二中函數(shù)嵌套函數(shù)的例子中,被嵌套的函數(shù)不會繼承上層函數(shù)的 this,如果使用箭頭函數(shù),會發(fā)生什么變化呢?

var obj = { y: function() {console.log(this === obj); // trueconsole.log(this); // Object {y: function} var fn = () => { console.log(this === obj); // true console.log(this); // Object {y: function} } fn(); }}obj.y()

和普通函數(shù)不一樣,箭頭函數(shù)中的 this 指向了 obj,這是因?yàn)樗鼜纳弦粚拥暮瘮?shù)中繼承了 this,你可以理解為箭頭函數(shù)修正了 this 的指向。所以箭頭函數(shù)的this不是調(diào)用的時候決定的,而是在定義的時候處在的對象就是它的this

換句話說,箭頭函數(shù)的this看外層的是否有函數(shù),如果有,外層函數(shù)的this就是內(nèi)部箭頭函數(shù)的this,如果沒有,則this是window

var obj = { y: () => {console.log(this === obj); // falseconsole.log(this); // Window 全局對象 var fn = () => { console.log(this === obj); // false console.log(this); // Window 全局對象 } fn(); }}obj.y()

上例中,雖然存在兩個箭頭函數(shù),其實(shí)this取決于最外層的箭頭函數(shù),由于obj是個對象而非函數(shù),所以this指向?yàn)閃indow全局對象。

同 bind 一樣,箭頭函數(shù)也很“頑固”,我們無法通過 call 和 apply 來改變 this 的指向,即傳入的第一個參數(shù)被忽略

var x = 1var obj = { x: 2}var a = () => { console.log(this.x) console.log(this)}a.call(obj) // 1// Window 全局對象a.apply(obj) // 1// Window 全局對象

上面的文字描述過多可能有點(diǎn)干澀,那么就看以下的這張流程圖吧,我覺得這個圖總結(jié)的很好,圖中的流程只針對于單個規(guī)則。

JavaScript逐點(diǎn)突破系列之this是什么

小結(jié)

本篇文章介紹了 this 指向的幾種情況,不同的運(yùn)行環(huán)境和調(diào)用方式都會對 this 產(chǎn)生影響。總的來說,函數(shù) this 的指向取決于當(dāng)前調(diào)用該函數(shù)的對象,也就是執(zhí)行時的對象。在這一節(jié)中,你需要掌握:

this 指向全局對象的情況; 嚴(yán)格模式和非嚴(yán)格模式下 this 的區(qū)別; 函數(shù)作為對象的方法調(diào)用時 this 指向的幾種情況; 作為構(gòu)造函數(shù)時 this 的指向,以及是否 return 的區(qū)別; 使用 call 和 apply 改變調(diào)用函數(shù)的對象; bind 創(chuàng)建的函數(shù)中 this 的指向; 箭頭函數(shù)中的 this 指向。

到此這篇關(guān)于JavaScript逐點(diǎn)突破系列之this是什么的文章就介紹到這了,更多相關(guān)JavaScript this內(nèi)容請搜索好吧啦網(wǎng)以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持好吧啦網(wǎng)!

標(biāo)簽: JavaScript
相關(guān)文章:
日本不卡不码高清免费观看,久久国产精品久久w女人spa,黄色aa久久,三上悠亚国产精品一区二区三区
日本欧美一区二区| 色爱综合av| 国产免费成人| 国产精品美女久久久| 亚洲综合精品四区| 中文一区一区三区免费在线观| 日韩精品一级中文字幕精品视频免费观看| 久久精品不卡| 伊人久久亚洲影院| 免费国产亚洲视频| 日韩av成人高清| 欧美欧美黄在线二区| 色综合视频一区二区三区日韩 | 久久亚洲专区| 黄色国产精品| 日韩精品一页| 久久福利在线| 国产精品黑丝在线播放| 成人精品亚洲| 影音国产精品| 深夜福利亚洲| 日韩手机在线| 精品一区二区三区免费看| 成人精品动漫一区二区三区| 国产成人精品一区二区免费看京| 人在线成免费视频| 亚洲精品91| 日韩综合小视频| 国产精品草草| 91精品久久久久久久久久不卡| 亚洲精品一二三区区别| 日韩精品电影一区亚洲| 精品一区二区三区四区五区| 久久国产毛片| 日本不卡高清| 高潮一区二区| 视频一区中文字幕| 国产高清精品二区| 偷拍欧美精品| 亚州av一区| 久久精品国产在热久久| 欧美日韩在线播放视频| 亚洲1区在线观看| 成人日韩av| 午夜在线视频观看日韩17c| 国产另类在线| 午夜国产精品视频免费体验区| 欧美专区一区| 久久九九精品| 国产精品一站二站| 久久久久国产| 欧美亚洲综合视频| 欧美肉体xxxx裸体137大胆| 日韩不卡一区二区| 日韩免费福利视频| 亚洲1区在线| 久久人人精品| 国产精品网站在线看| 好看不卡的中文字幕| 免费在线亚洲欧美| 久久国产精品久久久久久电车| 国产精品magnet| 欧美+日本+国产+在线a∨观看| 日本在线不卡视频| 日本精品影院| 国产精品亚洲成在人线| 在线综合亚洲| 激情视频网站在线播放色| 亚洲三级网址| 亚洲h色精品| 日韩高清欧美激情| 亚洲电影在线一区二区三区| 久久久久黄色| 亚洲香蕉视频| 激情综合自拍| 狂野欧美性猛交xxxx| 亚洲欧美久久精品| 91成人网在线观看| 福利精品在线| 国产亚洲欧美日韩精品一区二区三区 | 成人三级高清视频在线看| 久久国产精品毛片| 日韩欧美精品综合| 麻豆国产欧美一区二区三区| 在线精品福利| 在线综合亚洲| 久久麻豆精品| 神马久久午夜| 国产中文字幕一区二区三区| 欧美精品福利| 亚洲精一区二区三区| 2023国产精品久久久精品双| 在线天堂资源www在线污| 蜜桃久久久久| 欧美在线看片| 综合欧美亚洲| 午夜欧美理论片| 亚洲日本网址| 精品国产乱码久久久久久樱花| 欧美一区自拍| 日韩精品一区二区三区中文在线| 美女精品在线| 先锋亚洲精品| 99精品99| 午夜欧美精品| 国产精品91一区二区三区| 四虎影视精品| 韩国精品主播一区二区在线观看 | 三上亚洲一区二区| 国产精品成人3p一区二区三区| 亚洲精品第一| 综合干狼人综合首页| 夜夜精品视频| 亚洲综合不卡| 日韩影院精彩在线| 奶水喷射视频一区| 中文日韩在线| 蘑菇福利视频一区播放| 国产精品毛片在线| 午夜在线一区二区| 蘑菇福利视频一区播放| 99在线精品免费视频九九视| 亚洲电影在线一区二区三区| 1024精品久久久久久久久| 日本在线一区二区三区| 久久av免费| 日韩在线网址| 日韩精品视频网| 91精品在线免费视频| 国产亚洲一区| 国产精品大片免费观看| 麻豆成人91精品二区三区| 精品99久久| 电影天堂国产精品| 亚洲高清毛片| 国产色综合网| 亚洲精品伊人| 日本欧美韩国一区三区| 国产欧美午夜| 国产一区2区| 国产91在线精品| 91精品久久久久久久久久不卡| 亚洲一级特黄| 亚洲视频二区| 国产视频网站一区二区三区| 美女国产一区二区三区| 日本综合字幕| 日韩午夜黄色| 日韩精品一区二区三区中文在线| 欧美日韩网址| 高清日韩欧美| 好吊日精品视频| 日韩美女国产精品| 久久精品亚洲| 免费不卡中文字幕在线| 一区在线免费观看| 日韩激情一二三区| 九九久久国产| 欧美亚洲激情| 日韩激情一二三区| av资源新版天堂在线| 在线亚洲自拍| 久久国内精品自在自线400部| 国产在线视频欧美一区| 亚洲精品国产偷自在线观看| 日韩精品中文字幕吗一区二区 | 蜜臀国产一区| 图片区亚洲欧美小说区| 午夜久久av | 老鸭窝毛片一区二区三区| 欧美日本不卡高清| 美女一区网站| 亚洲人成网站在线在线观看| 久久麻豆视频| 亚洲深爱激情| 国产三级精品三级在线观看国产| 97精品国产| 天海翼亚洲一区二区三区| 久久精品国内一区二区三区| 蜜桃国内精品久久久久软件9| 久久精品97| 国产精品99一区二区| 国产欧美一区二区三区米奇| 亚洲大片在线| 国产精品蜜月aⅴ在线| 不卡一区综合视频| 欧美激情日韩| 日本欧洲一区二区| 超碰在线99| 亚洲bt欧美bt精品777| 久久久久久一区二区| 亚洲欧洲日韩| 精品丝袜在线| 国产精品亲子伦av一区二区三区| 欧美日韩少妇| 福利精品一区| 国产亚洲人成a在线v网站| 国产综合精品一区| 精品一区二区三区中文字幕视频| 男女性色大片免费观看一区二区|