摘要:沒有找到的話,看上級(jí)函數(shù)作用域,向上查找到,找到為止。將會(huì)在執(zhí)行上下文棧中保留上級(jí)作用域的執(zhí)行上下文。若在閉包使用完畢之后不手動(dòng)解除引用,相關(guān)執(zhí)行上下文將會(huì)一直保留于執(zhí)行上下文棧中,占據(jù)內(nèi)存空間,若持續(xù)積累,容易造成內(nèi)存泄漏。
JS有哪些基本數(shù)據(jù)類型呢?
值類型:undefined, Number, Boolean, String,null
引用類型:Object
值類型存放在棧中
引用類型將地址存放在棧中,將數(shù)據(jù)實(shí)體存放在堆中
null和undefined,not defined的區(qū)別?not defined是未聲明,當(dāng)使用未聲明變量時(shí)瀏覽器會(huì)拋出這個(gè)錯(cuò)誤
undefined是已聲明未賦值,typeof undefined是undefined
null類似于空對(duì)象,是一個(gè)已定義,定義為空的值,typeof null 是 object
如何判斷數(shù)據(jù)類型?如果是值類型,直接用typeof判斷
如果是引用類型,使用instanceof判斷,instanceof基于原型鏈,一般用于判斷自定義對(duì)象
constructor是prototype上的一個(gè)屬性,他容易被重寫覆蓋,所以不可信賴
Object.prototype.toString.call,調(diào)用Object原型上的toString方法可以得到當(dāng)前調(diào)用者的具體類型
Object.prototype.toString.call().slice(8, -1); // Object|Array|Number|String|Boolean...什么是原型鏈?
每一個(gè)函數(shù)上都有一個(gè)prototype屬性,稱為原型對(duì)象
函數(shù)實(shí)例化產(chǎn)生對(duì)象
每一個(gè)對(duì)象都有一個(gè)__proto__(隱匿原型)屬性,指向構(gòu)造它的原型對(duì)象。
原型對(duì)象本身也是對(duì)象,也有一個(gè)隱匿原型,指向它的原型對(duì)象。
沿著隱匿原型鏈最終會(huì)指向Object.prototype,它的原型對(duì)象是null
這就構(gòu)成一個(gè)原型鏈
PS. 將原子類型賦給 prototype 的操作將會(huì)被忽略
function Foo() {} Foo.prototype = 1; // 無效
instanceof的原理
A instanceof B
A的原型鏈?zhǔn)欠駮?huì)到達(dá)B.prototype
通過原型鏈實(shí)現(xiàn)繼承,原型對(duì)象上可以定義屬性和方法。
當(dāng)要在一個(gè)對(duì)象上尋找某個(gè)屬性,先在對(duì)象本身找,沒有的話,再沿著原型鏈向上找原型對(duì)象里有沒有,向上查找找到為止,到達(dá)頂部仍未找到,返回undefined
PS.判斷對(duì)象上是否有某個(gè)屬性,而非其原型鏈上有,使用hasOwnProperty 函數(shù)執(zhí)行上下文
在函數(shù)調(diào)用時(shí)或者是全局代碼開始運(yùn)行時(shí)產(chǎn)生,處理的事情:變量聲明,函數(shù)聲明,函數(shù)聲明形式的定義賦值,定義this,在函數(shù)內(nèi)還有定義arguments的操作
執(zhí)行上下文棧PS. arguments 變量不是一個(gè)數(shù)組(Array)。 盡管在語法上它有數(shù)組相關(guān)的屬性 length,但它不從 Array.prototype 繼承,實(shí)際上它是一個(gè)對(duì)象(Object)。
因此,無法對(duì) arguments 變量使用標(biāo)準(zhǔn)的數(shù)組方法,比如 push, pop 或者 slice。 雖然使用 for 循環(huán)遍歷也是可以的,但是為了更好的使用數(shù)組方法,最好把它轉(zhuǎn)化為一個(gè)真正的數(shù)組。
Array.prototype.slice.call(arguments);
全局代碼開始執(zhí)行時(shí),產(chǎn)生一個(gè)全局的執(zhí)行上下文,壓棧
代碼執(zhí)行到函數(shù)A調(diào)用時(shí),產(chǎn)生一個(gè)函數(shù)A的執(zhí)行上下文,壓棧
函數(shù)A中調(diào)用函數(shù)B,產(chǎn)生一個(gè)函數(shù)B的執(zhí)行上下文,壓棧
函數(shù)B,執(zhí)行完畢,出棧銷毀執(zhí)行上下文
函數(shù)A,執(zhí)行完畢,出棧并銷毀執(zhí)行上下文
關(guān)于this的指向this存在于執(zhí)行上下文中
作為構(gòu)造函數(shù)調(diào)用時(shí),指向?qū)嵗膶?duì)象
作為對(duì)象屬性調(diào)用時(shí),指向?qū)ο?/p>
call, apply調(diào)用時(shí),指向參數(shù)指定上下文
全局和普通函數(shù)都指向windows
ES6中,箭頭函數(shù)本身沒有this,導(dǎo)致以下三種現(xiàn)象:根據(jù)外層(函數(shù)或者全局)作用域來決定this,箭頭函數(shù)不能作為構(gòu)造函數(shù)使用,不能使用call, apply手動(dòng)修改this
PS. 一些誤解
// 1. 嚴(yán)格按照規(guī)范 Foo.method = function() { // 在這,this是Foo的實(shí)例化對(duì)象 function test() { // this 將會(huì)被設(shè)置為全局對(duì)象 } test(); } // 2. 函數(shù)別名 var test = someObject.methodTest; test(); // this設(shè)置為全局對(duì)象
PS. apply和call的用法作用域function.apply(null, arguments);
function.call(null, arg1, arg2);
ES5中只有函數(shù)作用域的概念,作用域是一個(gè)虛擬概念,沒有具體的數(shù)據(jù)類型或者結(jié)構(gòu)。
一個(gè)函數(shù)的作用域在函數(shù)定義時(shí)確定,創(chuàng)建函數(shù)的作用域成為該函數(shù)的上級(jí)作用域
在函數(shù)中尋找變量,先找到函數(shù)作用域?qū)?yīng)的執(zhí)行上下文,在執(zhí)行上下文中找變量。
沒有找到的話,看上級(jí)函數(shù)作用域,向上查找到,找到為止。
如果找不到,則會(huì)拋出 ReferenceError異常。
閉包PS. 比如,當(dāng)訪問函數(shù)內(nèi)的 foo 變量時(shí),JavaScript 會(huì)按照下面順序查找:
當(dāng)前作用域內(nèi)是否有 var foo 的定義。
函數(shù)形式參數(shù)是否有使用 foo 名稱的。
函數(shù)自身是否叫做 foo。
回溯到上一級(jí)作用域,然后從 #1 重新開始。
什么是閉包?
一個(gè)函數(shù)中有依賴外部變量,函數(shù)在創(chuàng)建它的作用域之外被調(diào)用。
將會(huì)在執(zhí)行上下文棧中保留上級(jí)作用域的執(zhí)行上下文。
若在閉包使用完畢之后不手動(dòng)解除引用,相關(guān)執(zhí)行上下文將會(huì)一直保留于執(zhí)行上下文棧中,占據(jù)內(nèi)存空間,若持續(xù)積累,容易造成內(nèi)存泄漏。
常見應(yīng)用,函數(shù)作為返回值,函數(shù)作為參數(shù)。
經(jīng)典問題
for (var i = 0; i < 5; i++) { setTimeout(function() { console.log(i); }, 1000); } // 5,5,5,5,5 for (let i = 0; i < 5; i++) { setTimeout(function() { console.log(i); }, 1000); } // 0,1,2,3,4 for (var i = 0; i < 5; i++) { (function (i) { setTimeout(function() { console.log(i); }, 1000); })(i) } // 0, 1, 2, 3, 4 for(var i = 0; i < 5; i++) { setTimeout((function(e) { return function() { console.log(e); } })(i), 1000) } // 0, 1, 2, 3, 4JS中實(shí)現(xiàn)繼承的方法
基礎(chǔ)繼承
var Bar = function () {}; Bar.prototype = { greet: function (name) { console.log(name); } } var Foo = function () {} Foo.prototype.__proto__ = Bar.prototype;
等價(jià)于
var Bar = function () {}; var Foo = function () {} Foo.prototype = new Bar();
原理:實(shí)現(xiàn)原型鏈
缺點(diǎn):屬性不獨(dú)立
組合繼承
var Bar = function (name) { this.name = name; } Bar.prototype = { greet: function () { console.log(this.name); } } var Foo = function (name) { Bar.apply(this, arguments); } Foo.prototype = new Bar();
原理:把this屬性賦值在子類的作用域執(zhí)行一次,方法通過原型鏈繼承
缺點(diǎn):this屬性賦值進(jìn)行了兩次
寄生組合式繼承
var Bar = function (name) { this.name = name; } Bar.prototype = { greet: function () { console.log(this.name); } } var Foo = function (name) { Bar.apply(this, arguments); } Foo.prototype = Object.create(Bar.prototype); Foo.prototype.constructor = Foo;
原理: 把this屬性賦值在子類的作用域執(zhí)行一次,手動(dòng)連接原型對(duì)象的拷貝
優(yōu)點(diǎn):解決組合繼承的缺點(diǎn)
extends方法
class Point { constructor(x, y) { this.x = x; this.y = y; } toString () { return this.x + " " + this.y; } } class ColorPoint extends Point { constructor(x, y, color) { super(x, y); // 調(diào)用父類的constructor(x, y) this.color = color; } toString() { return this.color + " " + super.toString(); // 調(diào)用父類的toString() } }
子類自己的this對(duì)象,必須先通過父類的構(gòu)造函數(shù)完成塑造,得到與父類同樣的實(shí)例屬性和方法,然后再對(duì)其進(jìn)行加工,加上子類自己的實(shí)例屬性和方法。如果不調(diào)用super方法,子類就得不到this對(duì)象。
類型轉(zhuǎn)換 強(qiáng)制轉(zhuǎn)換PS. new 運(yùn)算符做了什么
// 1. 首先創(chuàng)建一個(gè)空對(duì)象 var o = new Object(); // 2. 將空對(duì)象的原型賦值為構(gòu)造器函數(shù)的原型 o.__proto__ = A.prototype; // 3. 更改構(gòu)造器函數(shù)內(nèi)部this,將其指向新創(chuàng)建的空對(duì)象 A.call(o);
轉(zhuǎn)為字符串::.toString(), String()
轉(zhuǎn)為數(shù)值:Number針對(duì)所有類型,parseInt和parseFloat針對(duì)字符串
字符串轉(zhuǎn)換為數(shù)字的常用方法:
+"010" === 10 Number("010") === 10 parseInt("010", 10) === 10 // 用來轉(zhuǎn)換為整數(shù) +"010.2" === 10.2 Number("010.2") === 10.2 parseInt("010.2", 10) === 10 parseFloat("10.1.2") === 10.1 // 字符轉(zhuǎn)換為浮點(diǎn)數(shù) Number(undefined) // NaN Number嚴(yán)格轉(zhuǎn)換,只要有一個(gè)字符無法轉(zhuǎn)為數(shù)值輸出NaN parseInt原理為從左往右讀字符串,讀到非數(shù)值字符為止 parseFloat原理為從左往右讀字符串,讀到第二個(gè)小數(shù)點(diǎn)或者非數(shù)值非小數(shù)點(diǎn)字符為止
轉(zhuǎn)為布爾值:Boolean(),""、null、undefined、+0、-0 和 NaN 轉(zhuǎn)為布爾型是 false,其他的都是 true
自動(dòng)轉(zhuǎn)換轉(zhuǎn)為字符串:包含字符串的+法運(yùn)算,"5" + 1 === "51"
轉(zhuǎn)為數(shù)值:不包含字符串的算術(shù)運(yùn)算
轉(zhuǎn)為布爾值:條件語句判斷,非運(yùn)算
事件輪詢機(jī)制主線程運(yùn)行時(shí)產(chǎn)生堆和執(zhí)行棧
主線程之外,還存在一個(gè)"任務(wù)隊(duì)列"。只要異步任務(wù)有了運(yùn)行結(jié)果,就在"任務(wù)隊(duì)列"之中放置一個(gè)事件。
一旦"執(zhí)行棧"中的所有同步任務(wù)執(zhí)行完畢,系統(tǒng)就會(huì)讀取"任務(wù)隊(duì)列",看看里面有哪些事件。對(duì)應(yīng)的異步任務(wù),結(jié)束等待狀態(tài),進(jìn)入執(zhí)行棧,開始執(zhí)行
任務(wù)隊(duì)列任務(wù)隊(duì)列分為宏任務(wù)隊(duì)列和微任務(wù)隊(duì)列
宏任務(wù)包括:script(全局任務(wù)), setTimeout, setInterval, setImmediate, I/O, UI rendering。
微任務(wù)包括: new Promise().then(回調(diào)), process.nextTick, Object.observe(已廢棄), MutationObserver(html5新特性)
執(zhí)行同步任務(wù) -> 處理微任務(wù)隊(duì)列 -> 處理宏任務(wù)隊(duì)列里隊(duì)首任務(wù) -> 處理微任務(wù)隊(duì)列
Promise.resolve().then(()=>{ console.log("Promise1") setTimeout(()=>{ console.log("setTimeout1") },0) }) setTimeout(()=>{ console.log("setTimeout2") Promise.resolve().then(()=>{ console.log("Promise2") }) Promise.resolve().then(()=>{ console.log("Promise3") }) },0) setTimeout(()=>{ console.log("setTimeout4") Promise.resolve().then(()=>{ console.log("Promise4") }) },0) Output: Promise1 setTimout2 Promise2 Promise3 setTimeout4 Promise4 setTimeout1setTimeout和setInterval的區(qū)別
setTimeout:產(chǎn)生一個(gè)宏任務(wù),在指定時(shí)間之后加入任務(wù)隊(duì)列。
setInterval:循環(huán)產(chǎn)生宏任務(wù),但存在問題,若任務(wù)執(zhí)行時(shí)間長于指定時(shí)間間隔,會(huì)產(chǎn)生堆疊執(zhí)行效果。
文章版權(quán)歸作者所有,未經(jīng)允許請(qǐng)勿轉(zhuǎn)載,若此文章存在違規(guī)行為,您可以聯(lián)系管理員刪除。
轉(zhuǎn)載請(qǐng)注明本文地址:http://specialneedsforspecialkids.com/yun/100410.html
摘要:為了實(shí)現(xiàn)文字環(huán)繞效果,規(guī)范規(guī)定的措施是使父容器塌陷,元素脫離文檔流浮動(dòng)產(chǎn)生,元素周圍的內(nèi)容轉(zhuǎn)換為圍繞元素排列。 選擇器注意點(diǎn) 屬性選擇器 [attr^=value] - 開頭或全等 [attr$=value] - 結(jié)尾或全等 [attr*=value] - 包含值 [attr~=value] - 字符串包含 選擇器組 A > B - 直接子節(jié)點(diǎn) A + B - 下一個(gè)兄弟節(jié)點(diǎn) A...
摘要:讀一遍文檔后的個(gè)人總結(jié),重點(diǎn)在于整理語義化標(biāo)簽的定義規(guī)范,記錄各種部件容易被忽略的特性。結(jié)構(gòu)化,通過標(biāo)簽先后順序和嵌套語法給樹提供基礎(chǔ)。標(biāo)簽列表基于個(gè)人理解即非官方描述,給標(biāo)簽劃分為結(jié)構(gòu)化標(biāo)簽語義化標(biāo)簽功能化標(biāo)簽,文檔標(biāo)簽。 讀一遍MDN文檔后的個(gè)人總結(jié),重點(diǎn)在于整理語義化標(biāo)簽的定義規(guī)范,記錄各種部件容易被忽略的特性。 關(guān)于HTML HTML的作用可以簡(jiǎn)單總結(jié)為結(jié)構(gòu)化、語義化和提供基礎(chǔ)...
摘要:本文主要是我自己對(duì)的一些整理,參考自,其中的分類有些不準(zhǔn)確之處,還望見諒的基本屬性屬性的一些方法增刪改查基礎(chǔ)功能增刪改查基礎(chǔ)功能增刪改刪除數(shù)組的第一個(gè)元素刪除數(shù)組的最后一個(gè)元素在數(shù)組的開頭一個(gè)或多個(gè)元素,在數(shù)組的末尾增加一個(gè)或者多個(gè)元素?cái)?shù)組 本文主要是我自己對(duì)Array的一些整理,參考自MDN,其中的分類有些不準(zhǔn)確之處,還望見諒 Array const arr = [1, 2, 3, ...
摘要:維護(hù)瀏覽器和服務(wù)器端會(huì)話狀態(tài)的一種方式,一般用于保存用戶身份信息。服務(wù)器端生成推送到瀏覽器端,瀏覽器負(fù)責(zé)保存和維護(hù)數(shù)據(jù)。 Cookie 維護(hù)瀏覽器和服務(wù)器端會(huì)話狀態(tài)的一種方式,一般用于保存用戶身份信息。 服務(wù)器端生成Cookie推送到瀏覽器端,瀏覽器負(fù)責(zé)保存和維護(hù)數(shù)據(jù)。 特點(diǎn) 域名下的所用請(qǐng)求都會(huì)帶上Cookie 每條Cookie限制在4KB左右 Cookie在過期時(shí)間之前一直有效,若...
閱讀 1015·2021-11-22 14:56
閱讀 983·2021-11-11 16:54
閱讀 7700·2021-09-23 11:55
閱讀 3004·2021-09-22 15:57
閱讀 2792·2021-08-27 16:25
閱讀 670·2019-08-30 15:55
閱讀 1660·2019-08-30 15:43
閱讀 1595·2019-08-30 14:23