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