国产xxxx99真实实拍_久久不雅视频_高清韩国a级特黄毛片_嗯老师别我我受不了了小说

資訊專欄INFORMATION COLUMN

JavaScript進階之’this‘

shenhualong / 2453人閱讀

摘要:所以相同點是,在全局范圍內,全局變量終究是屬于老大的。只生效一次引入了。只生效一次在箭頭函數中,與封閉詞法環境的保持一致。我通常把這些原始函數叫做構造函數。在里面你可以嵌套函數,也就是你可以在函數里面定義函數。

只有掌握了JavaScript中的this操作符你才算正式邁入JavaScript這門語言的門檻!我們一直都在用這個框架,那個框架,但往往忽視掉了js最基礎的東西,筆者認為這些基礎往往才是走下去,走深,最不可或缺的東西.那我們就一起來學習一下js中神奇的this吧--------筆者查看了大量有關this的文章,有些是按照自己思路寫的,有些是直接引用其他作者成熟的思路的文章
1.什么是this?

學習一個知識首先要理解他的字面含義,通過翻譯我們知道,this的含義是這,這個(指較近的人或事物)的意思。那么我們結合現實,我們說的“這”在不同的環境所指的事物是不一樣的。那么在JavaScript中this在不同的環境調用所表達的含義也是非常豐富的。如果你覺得JavaScript中的this和其他面向對象語言Java一樣,是指存儲在實例屬性中的值,那你就大錯特錯了。JavaScript中的this有著在這門語言中不可或缺魔力。

2.運行的宿主(環境)不同this含義也是不一樣
宿主(環境)解釋

JS的運行環境一般由宿主環境和執行期環境共同構成,宿主環境是由外殼程序(如web瀏覽器就是一個外殼程序)生成,執行期環境是由嵌入到外殼程序中的JS引擎(/JS解釋器)生成的,在執行期環境JS可以生成內置靜態對象、初始化執行環境等。

對于JavaScript,宿主環境最常見的是web瀏覽器,瀏覽器提供了一個JavaScript運行的環境,這個環境里面,需要提供一些接口,好讓JavaScript引擎能夠和宿主環境對接。JavaScript引擎才是真正執行JavaScript代碼的地方,常見的引擎有V8(目前最快JavaScript引擎、Google生產)、JavaScript core

但是環境不是唯一的,也就是JavaScript不僅僅能夠在瀏覽器里面跑,也能在其他提供了宿主環境的程序里面跑,最常見的就是nodejs。同樣作為一個宿主環境,nodejs也有自己的JavaScript引擎--V8。根據官方的定義:
Node.js is a platform built on Chrome’s JavaScript runtime for easily building fast, scalable network applications

3.全局中的this
1.瀏覽器環境中

在瀏覽器里,在全局范圍內,this等價于window對象。用var聲明一個變量和給this或者window添加屬性是等價的

說明:在瀏覽器中,window對象同時也是全局對象
1.node環境中

在node環境里,如果使用REPL(Read-Eval-Print Loop,簡稱REPL:讀取-求值-輸出,是一個簡單的,交互式的編程環境)來執行程序,this并不是最高級的命名空間,最高級的是global.

> this === global
true

但在node環境里,如果執行一個js腳本,在全局范圍內,this以一個空對象開始作為最高級的命名空間,這個時候,它和global不是等價的。

index.js 文件在node環境中執行

console.log(this) //Object {}
console.log(this === global); //false

在node環境里,在全局范圍內,如果你用REPL執行一個腳本文件,用var聲明一個變量并不會和在瀏覽器里面一樣將這個變量添加給this。

index.js 文件在node環境中執行

var foo = "bar";
console.log(this.foo);//undefined

但是如果你不是用REPL執行腳本文件,而是直接執行代碼,結果和在瀏覽器里面是一樣的(神坑)

 > var foo = "bar";
 > this.foo
 bar
 > global.foo
 bar

在node環境里,用REPL運行腳本文件的時候,如果在聲明變量的時候沒有使用var或者let,這個變量會自動添加到global對象,但是不會自動添加給this對象。如果是直接執行代碼,則會同時添加給global和this

index.js 文件在node環境中執行

 foo = "bar";
 console.log(this.foo);//undefined
 console.log(global.foo);//bar
上面的幾種種情況可能大家已經繞暈了,總結起來就是:在瀏覽器里面this是老大,它等價于window對象,如果你聲明一些全局變量(不管在任何地方),這些變量都會作為this的屬性。在node里面,有兩種執行JavaScript代碼的方式,一種是直接執行寫好的JavaScript文件,另外一種是直接在里面執行一行行代碼。對于直接運行一行行JavaScript代碼的方式,global才是老大,this和它是等價的。在這種情況下,和瀏覽器比較相似,也就是聲明一些全局變量會自動添加給老大global,順帶也會添加給this。但是在node里面直接腳本文件就不一樣了,你聲明的全局變量不會自動添加到this,但是會添加到global對象。所以相同點是,在全局范圍內,全局變量終究是屬于老大的。
4.函數(function)中的this
說明:在函數內部,this的值取決于函數被調用的方式

無論是在瀏覽器環境還是node環境,除了在DOM事件處理程序里或者給出了thisArg(接下來會講到)外,如果不是用new調用,在函數里面使用this都是指代全局范圍的this。


index.js 文件在node環境中執行

foo = "bar";

function testThis () {
  this.foo = "foo";
}

console.log(global.foo);//bar
testThis();
console.log(global.foo);//foo
說明:因為上面代碼不在嚴格模式下,且this的值不是由該調用設置的,所以this的值默認指向全局對象。

除非你使用嚴格模式,這時候this就會變成undefined。

說明:然而,在嚴格模式下,this將保持他進入執行環境時的值,所以下面的this將會默認為undefined,所以,在嚴格模式下,如果 this 沒有被執行環境(execution context)定義,那它將保持為 undefined。

如果你在調用函數的時候在前面使用了new,this就會變成一個新的值,和global的this脫離干系。

函數里面的this其實相對比較好理解,如果我們在一個函數里面使用this,需要注意的就是我們調用函數的方式,如果是正常的方式調用函數,this指代全局的this,如果我們加一個new,這個函數就變成了一個構造函數,我們就創建了一個實例,this指代這個實例,這個和其他面向對象的語言很像。另外,寫JavaScript很常做的一件事就是綁定事件處理程序,也就是諸如button.addEventListener(‘click’, fn, false)之類的,如果在fn里面需要使用this,this指代事件處理程序對應的對象,也就是button。

如果想把this的值從一個環境傳到另一個環境,就要用到call或者apply的方法。

說明:使用 call 和 apply 函數的時候要注意,如果傳遞給 this 的值不是一個對象,JavaScript 會嘗試使用內部 ToObject 操作將其轉換為對象。因此,如果傳遞的值是一個原始值比如 7 或 "foo",那么就會使用相關構造函數將它轉換為對象,所以原始值 7 會被轉換為對象,像 new Number(7) 這樣,而字符串 "foo" 轉化成 new String("foo") 這樣,例如:下面代碼

ECMAScript 5 引入了 Function.prototype.bind。調用f.bind(someObject)會創建一個與f具有相同函數體和作用域的函數,但是在這個新函數中,this將永久地被綁定到了bind的第一個參數,無論這個函數是如何被調用的。

ECMAScript 5 引入了 Function.prototype.bind。調用f.bind(someObject)會創建一個與f具有相同函數體和作用域的函數,但是在這個新函數中,this將永久地被綁定到了bind的第一個參數,無論這個函數是如何被調用的。

在箭頭函數中,this與封閉詞法環境的this保持一致。在全局代碼中,它將被設置為全局對象:

5.原型(prototype)中的this

你創建的每一個函數都是函數對象,他們會自動獲取一個特殊的屬性prototype,你可以給這個屬性賦值。當你用new的方式調用一個函數的時候,你就能通過this訪問你給prototype賦的值了。

當你使用new為你的函數創建多個實例的時候,這些實例會共享你給prototype設定的值。對于下面的例子,當你調用this.foo的時候,都會返回相同的值,除非你在某個實例里面重寫了自己的this.foo

實例里面的this是一個特殊的對象。你可以把this想成一種獲取prototype的值的一種方式。當你在一個實例里面直接給this添加屬性的時候,會隱藏prototype中與之同名的屬性。如果你想訪問prototype中的這個屬性值而不是你自己設定的屬性值,你可以通過在實例里面刪除你自己添加的屬性的方式來實現。

或者你也能直接通過引用函數對象的prototype 來獲得你需要的值。

此時的this是指,構造函數的原型上的方法至于為什么看下面

通過一個函數創建的實例會共享這個函數的prototype屬性的值,如果你給這個函數的prototype賦值一個Array,那么所有的實例都會共享這個Array,除非你在實例里面重寫了這個Array,這種情況下,函數的prototype的Array就會被隱藏掉。

實際上你可以通過把多個函數的prototype鏈接起來的從而形成一個原型鏈,因此this就會魔法般地沿著這條原型鏈往上查找直到找你你需要引用的值。

一些人利用原型鏈的特性來在JavaScript模仿經典的面向對象的繼承方式。任何給用于構建原型鏈的函數的this的賦值的語句都會隱藏原型鏈上游的相同的屬性。

我喜歡把被賦值給prototype的函數叫做方法。在上面的例子中,我已經使用過方法了,如logFoo。這些方法有著相同的prototype,即創建這些實力的原始函數。我通常把這些原始函數叫做構造函數。在prototype里面定義的方法里面使用this會影響到當前實例的原型鏈的上游的this。這意味著你直接給this賦值的時候,隱藏了原型鏈上游的相同的屬性值。這個實例的任何方法都會使用這個最新的值而不是原型里面定義的這個相同的值。

在JavaScript里面你可以嵌套函數,也就是你可以在函數里面定義函數。嵌套函數可以通過閉包捕獲父函數的變量,但是這個函數沒有繼承this

在doIt里面的this是global對象或者在嚴格模式下面是undefined。這是造成很多不熟悉JavaScript的人深陷 this陷阱的根源。在這種情況下事情變得非常糟糕,就像你把一個實例的方法當作一個值,把這個值當作函數參數傳遞給另外一個函數但是卻不把這個實例傳遞給這個函數一樣。在這種情況下,一個方法里面的環境變成了全局范圍,或者在嚴格模式下面的undefined。

一些人喜歡先把this捕獲到一個變量里面,通常這個變量叫做self,來避免上面這種情況的發生

但是當你需要把一個方法作為一個值傳遞給一個函數的時候并不管用。

你可以通過bind將實例和方法一切傳遞給函數來解決這個問題,bind是一個函數定義在所有函數和方法的函數對象上面

你同樣可以使用apply和call來在新的上下文中調用方法或函數。

你可以用bind來代替任何一個函數或者方法的this,即便它沒有賦值給實例的初始prototype。

你應該避免在構造函數里面返回任何東西,因為這可能代替本來應該返回的實例。

怪的是,如果你在構造函數里面返回了一個原始值,上面所述的情況并不會發生并且返回語句被忽略了。最好不要在你將通過new調用的構造函數里面返回任何類型的數據,即便你知道自己正在做什么。如果你想創建一個工廠模式,通過一個函數來創建一個實例,這個時候不要使用new來調用函數。當然這個建議是可選的。

你可以通過使用Object.create來避免使用new,這樣同樣能夠創建一個實例。

在這種情況下并不會調用構造函數

因為Object.create不會調用構造函數的特性在你繼承模式下你想通過原型鏈重寫構造函數的時候非常有用。

6.對象(object )中的this

在一個對象的一個函數里,你可以通過this來引用這個對象的其他屬性。這個用new來新建一個實例是不一樣的。

注意,沒有使用new,沒有使用Object.create,也沒有使用函數調用創建一個對象。你也可以將對象當作一個實例將函數綁定到上面。

當你用這種方式使用this的時候,并不會越出當前的對象。只有有相同直接父元素的屬性才能通過this共享變量

你可以直接通過對象引用你需要的屬性

7.DOM(event)中的this

在一個HTML DOM事件處理程序里面,this始終指向這個處理程序被所綁定到的HTML DOM節點

除非你自己通過bind切換了上下文

8.HTML 中的this

在HTML節點的屬性里面,你可以放置JavaScript代碼,this指向了這個元素

 

到此結束~~~~~~~~~

作者 作者: weshmily科技站長 官網: 百度搜索(weshmily科技) CSDN博客:http://blog.csdn.net/qq_27118895 GitHub: https://github.com/weshmily 公眾號:搜索"weshmilyqd"

文章版權歸作者所有,未經允許請勿轉載,若此文章存在違規行為,您可以聯系管理員刪除。

轉載請注明本文地址:http://m.specialneedsforspecialkids.com/yun/105551.html

相關文章

  • 進階1-5期】JavaScript深入4類常見內存泄漏及如何避免

    摘要:本期推薦文章類內存泄漏及如何避免,由于微信不能訪問外鏈,點擊閱讀原文就可以啦。四種常見的內存泄漏劃重點這是個考點意外的全局變量未定義的變量會在全局對象創建一個新變量,如下。因為老版本的是無法檢測節點與代碼之間的循環引用,會導致內存泄漏。 (關注福利,關注本公眾號回復[資料]領取優質前端視頻,包括Vue、React、Node源碼和實戰、面試指導) 本周正式開始前端進階的第一期,本周的主題...

    red_bricks 評論0 收藏0
  • 進階1-1期】理解JavaScript 中的執行上下文和執行棧

    摘要:首次運行代碼時,會創建一個全局執行上下文并到當前的執行棧中。執行上下文的創建執行上下文分兩個階段創建創建階段執行階段創建階段確定的值,也被稱為。 (關注福利,關注本公眾號回復[資料]領取優質前端視頻,包括Vue、React、Node源碼和實戰、面試指導) 本周正式開始前端進階的第一期,本周的主題是調用堆棧,,今天是第一天 本計劃一共28期,每期重點攻克一個面試重難點,如果你還不了解本進...

    import. 評論0 收藏0
  • 進階2-2期】JavaScript深入從作用域鏈理解閉包

    摘要:使用上一篇文章的例子來說明下自由變量進階期深入淺出圖解作用域鏈和閉包訪問外部的今天是今天是其中既不是參數,也不是局部變量,所以是自由變量。 (關注福利,關注本公眾號回復[資料]領取優質前端視頻,包括Vue、React、Node源碼和實戰、面試指導) 本周正式開始前端進階的第二期,本周的主題是作用域閉包,今天是第7天。 本計劃一共28期,每期重點攻克一個面試重難點,如果你還不了解本進階計...

    simpleapples 評論0 收藏0
  • 進階3-2期】JavaScript深入重新認識箭頭函數的this

    摘要:箭頭函數的尋值行為與普通變量相同,在作用域中逐級尋找。題目這次通過構造函數來創建一個對象,并執行相同的個方法。 我們知道this綁定規則一共有5種情況: 1、默認綁定(嚴格/非嚴格模式) 2、隱式綁定 3、顯式綁定 4、new綁定 5、箭頭函數綁定 其實大部分情況下可以用一句話來概括,this總是指向調用該函數的對象。 但是對于箭頭函數并不是這樣,是根據外層(函數或者全局)作用域(...

    Rainie 評論0 收藏0
  • 進階1-2期】JavaScript深入執行上下文棧和變量對象

    摘要:本計劃一共期,每期重點攻克一個面試重難點,如果你還不了解本進階計劃,點擊查看前端進階的破冰之旅本期推薦文章深入之執行上下文棧和深入之變量對象,由于微信不能訪問外鏈,點擊閱讀原文就可以啦。 (關注福利,關注本公眾號回復[資料]領取優質前端視頻,包括Vue、React、Node源碼和實戰、面試指導) 本周正式開始前端進階的第一期,本周的主題是調用堆棧,今天是第二天。 本計劃一共28期,每期...

    Richard_Gao 評論0 收藏0
  • 進階3-3期】深度解析 call 和 apply 原理、使用場景及實現

    摘要:之前文章詳細介紹了的使用,不了解的查看進階期。不同的引擎有不同的限制,核心限制在,有些引擎會拋出異常,有些不拋出異常但丟失多余參數。存儲的對象能動態增多和減少,并且可以存儲任何值。這邊采用方法來實現,拼成一個函數。 之前文章詳細介紹了 this 的使用,不了解的查看【進階3-1期】。 call() 和 apply() call() 方法調用一個函數, 其具有一個指定的 this 值和分...

    godlong_X 評論0 收藏0

發表評論

0條評論

最新活動
閱讀需要支付1元查看
<