摘要:深入認(rèn)知前言關(guān)于,平時(shí)我們僅僅做到了使用,但是真的理解為什么這么使用嗎這里詳細(xì)介紹一些我們常用的語(yǔ)法。在以下,是沒(méi)有塊級(jí)作用域的,只有函數(shù)作用域。而如果在作用域中嵌套作用域,那么就會(huì)有作用域鏈。
本文當(dāng)時(shí)寫在本地,發(fā)現(xiàn)換電腦很不是方便,在這里記錄下。
深入認(rèn)知 Javascript 前言關(guān)于 Javascript,平時(shí)我們僅僅做到了使用,但是真的理解為什么這么使用嗎?
這里詳細(xì)介紹一些我們常用的 Javascript 語(yǔ)法。
關(guān)鍵字what: 在Javascript 關(guān)鍵字是有很多的,而普通的關(guān)鍵字基本沒(méi)有太多的難度,例如var,eval,void,break...,這里僅僅挑選兩個(gè) this 和 new 也是最讓人疑惑的關(guān)鍵字。1.1 this
在 Javascript6.0 以下,Javascript是沒(méi)有塊級(jí)作用域的,只有函數(shù)作用域。而如果在作用域中嵌套作用域,那么就會(huì)有作用域鏈。
foo = "window"; function first(){ var foo = "first"; function second(){ var foo = "second"; console.log(foo); } function third(){ console.log(foo); } second(); //second third(); //first } first();
理解:當(dāng)執(zhí)行second時(shí),JS引擎會(huì)將second的作用域放置鏈表的頭部,其次是first的作用域,最后是window對(duì)象,于是會(huì)形成如下作用域鏈:second->first->window, 此時(shí),JS引擎沿著該作用域鏈查找變量foo, 查到的是 second。當(dāng)執(zhí)行third時(shí),third形成的作用域鏈:third->first->window, 因此查到的是:frist。
弄清楚作用域,我們?cè)趤?lái)看 this 關(guān)鍵字,Javascript 中的 this 總是指向當(dāng)前函數(shù)的所有者對(duì)象,this總是在運(yùn)行時(shí)才能確定其具體的指向, 也才能知道它的調(diào)用對(duì)象
window.name = "window"; function f(){ console.log(this.name); } f();//window var obj = {name:"obj"}; f.call(obj); //obj
理解:在執(zhí)行f()時(shí),此時(shí)f()的調(diào)用者是window對(duì)象,因此輸出 window ,f.call(obj) 是把f()放在obj對(duì)象上執(zhí)行,相當(dāng)于obj.f(),此時(shí)f 中的this就是obj,所以輸出的是 obj
Demo 1
var foo = "window"; var obj = { foo : "obj", getFoo : function() { return function() { return this.foo; }; } }; var f = obj.getFoo(); f();
Demo 2
var foo = "window"; var obj = { foo : "obj", getFoo : function() { var that = this; return function(){ return that.foo; }; } }; var f = obj.getFoo(); f();
? Demo1 和 Demo2 的返回值是多少
代碼解析:
// demo1: //執(zhí)行var f = obj.getFoo()返回的是一個(gè)匿名函數(shù),相當(dāng)于: var f = function(){ return this.foo; } // f() 相當(dāng)于window.f(), 因此f中的this指向的是window對(duì)象,this.foo相當(dāng)于window.foo, 所以f()返回"window" // demo2: // 執(zhí)行var f = obj.getFoo() 同樣返回匿名函數(shù),即: var f = function(){ return that.foo; } // 唯一不同的是f中的this變成了that, 要知道that是哪個(gè)對(duì)象之前,先確定f的作用域鏈:f->getFoo->window 并在該鏈條上查找that, // 此時(shí)可以發(fā)現(xiàn)that指代的是getFoo中的this, getFoo中的this指向其運(yùn)行時(shí)的調(diào)用者, // 從var f = obj.getFoo() 可知此時(shí)this指向的是obj對(duì)象,因此that.foo 就相當(dāng)于obj.foo,所以f()返回 "obj"1.2 new
what: 和其他高級(jí)語(yǔ)言一樣 Javascript 中也有 new 運(yùn)算符,我們知道 new 運(yùn)算符是用來(lái)實(shí)例化一個(gè)類,從而在內(nèi)存中分配一個(gè)實(shí)例對(duì)象。 但在 Javascript 中,萬(wàn)物皆對(duì)象,為什么還要通過(guò) new 來(lái)產(chǎn)生對(duì)象
先看一個(gè)例子
01 function Animal(name){ 02 this.name = name; 03 } 04 Animal.color = "black"; 05 Animal.prototype.say = function(){ 06 console.log("I"m " + this.name); 07 }; 08 var cat = new Animal("cat"); 09 10 console.log( 11 cat.name, //cat 12 cat.height //undefined 13 ); 14 cat.say(); //I"m cat 15 16 console.log( 17 Animal.name, //Animal 18 Animal.color //back 19 ); 20 Animal.say(); //Animal.say is not a function
代碼解析:
1-3行創(chuàng)建了一個(gè)函數(shù) Animal,并在其 this 上定義了屬性 name,name的值是函數(shù)被執(zhí)行時(shí)的形參。
4行在 Animal 對(duì)象(Animal 本身是一個(gè)函數(shù)對(duì)象)上定義了一個(gè)靜態(tài)屬性 color,并賦值“black”
5-7行在 Animal 函數(shù)的原型對(duì)象 prototype 上定義了一個(gè) say 方法,say 方法輸出了 this.name。
8行通過(guò) new 關(guān)鍵字創(chuàng)建了一個(gè)新對(duì)象 cat。
10-14行 cat 對(duì)象嘗試訪問(wèn) name 和 color 屬性,并調(diào)用 say 方法。
16-20行 Animal 對(duì)象嘗試訪問(wèn) name 和 color 屬性,并調(diào)用 say 方法。
重點(diǎn)解析:
注意到第 8 行,
var cat = new Animal("cat");
JS引擎執(zhí)行這句代碼時(shí),在內(nèi)部做了很多工作,用偽代碼模擬其工作流程如下:
new Animal("cat") = { var obj = {}; obj.__proto__ = Animal.prototype; var result = Animal.call(obj, "cat"); return typeof result === "object"? result : obj; }
代碼解析:
創(chuàng)建一個(gè)空對(duì)象obj;
把obj 的 __proto__ 指向 Animal 的原型對(duì)象 prototype,此時(shí)便建立了 obj 對(duì)象的原型鏈:
obj Animal.prototype Object.prototype null
簡(jiǎn)單解釋下原型對(duì)象和原型鏈:
原型對(duì)象:指給后臺(tái)函數(shù)繼承的父對(duì)象
原型鏈:鏈接成 java 的繼承
文章版權(quán)歸作者所有,未經(jīng)允許請(qǐng)勿轉(zhuǎn)載,若此文章存在違規(guī)行為,您可以聯(lián)系管理員刪除。
轉(zhuǎn)載請(qǐng)注明本文地址:http://m.hztianpu.com/yun/104564.html
摘要:等待的基本語(yǔ)法該關(guān)鍵字的的意思就是讓編譯器等待并返回結(jié)果。這里并不會(huì)占用資源,因?yàn)橐婵梢酝瑫r(shí)執(zhí)行其他任務(wù)其他腳本或處理事件。接下來(lái),我們寫一個(gè)火箭發(fā)射場(chǎng)景的小例子不是真的發(fā)射火箭 本文由云+社區(qū)發(fā)表 本篇文章,小編將和大家一起學(xué)習(xí)異步編程的未來(lái)——async/await,它會(huì)打破你對(duì)上篇文章Promise的認(rèn)知,竟然異步代碼還能這么寫! 但是別太得意,你需要深入理解Promise后,...
某熊的技術(shù)之路指北 ? 當(dāng)我們站在技術(shù)之路的原點(diǎn),未來(lái)可能充滿了迷茫,也存在著很多不同的可能;我們可能成為 Web/(大)前端/終端工程師、服務(wù)端架構(gòu)工程師、測(cè)試/運(yùn)維/安全工程師等質(zhì)量保障、可用性保障相關(guān)的工程師、大數(shù)據(jù)/云計(jì)算/虛擬化工程師、算法工程師、產(chǎn)品經(jīng)理等等某個(gè)或者某幾個(gè)角色。某熊的技術(shù)之路系列文章/書(shū)籍/視頻/代碼即是筆者蹣跚行進(jìn)于這條路上的點(diǎn)滴印記,包含了筆者作為程序員的技術(shù)視野、...
摘要:?jiǎn)尉€程使用單線程來(lái)運(yùn)行,而不是向之類的其它服務(wù)器,每個(gè)請(qǐng)求將生產(chǎn)一個(gè)線程,這種方法避免了上下文切換和內(nèi)存中的大量執(zhí)行堆棧,這也是和其它服務(wù)器為解決上一個(gè)年,著名的并發(fā)連接問(wèn)題而采用的方法。 showImg(https://segmentfault.com/img/remote/1460000019968794?w=1080&h=675);當(dāng)我們學(xué)習(xí)一項(xiàng)新的事物的時(shí)候,我們首先要知道它來(lái)...
摘要:大家好,我是冰河有句話叫做投資啥都不如投資自己的回報(bào)率高。馬上就十一國(guó)慶假期了,給小伙伴們分享下,從小白程序員到大廠高級(jí)技術(shù)專家我看過(guò)哪些技術(shù)類書(shū)籍。 大家好,我是...
閱讀 1734·2021-10-13 09:39
閱讀 2156·2021-09-07 10:20
閱讀 2750·2019-08-30 15:56
閱讀 3018·2019-08-30 15:56
閱讀 992·2019-08-30 15:55
閱讀 726·2019-08-30 15:46
閱讀 3550·2019-08-30 15:44
閱讀 2618·2019-08-30 11:15