摘要:預解釋變量和函數的預解釋只發生在當前的作用于中中內存的分類棧內存用來提供一個代碼指定的環境作用域全局作用域和局部作用域堆內存用來存儲引用類型的值對象存儲的是鍵值對,函數儲存的是字符串函數執行的時候形成一個私有作用域有形參給形參賦值,形參也
預解釋
變量和函數的預解釋只發生在當前的作用于中
js中內存的分類
棧內存:用來提供一個js代碼指定的環境 —>作用域(全局作用域和局部作用域)
堆內存:用來存儲引用類型的值 ->對象存儲的是鍵值對,函數儲存的是字符串
函數執行的時候形成一個私有作用域
1.有形參給形參賦值,形參也是函數的局部變量,把實參賦值一份給形參(值類型和引用類型不同的情況)2.進行私有作用域預解釋 3.私有作用域從上倒下執行
作用鏈的機制:冒泡向上查找(作用域鏈模式查找)
閉包: 函數形成了一個新新的私有作用域保護了里面的私有作用域不受外界的干擾(外界改變不了私有的,私有的也改變不了外面的)
函數不使用var聲明的變量,指定函數時是綁定到window上的
預解釋的時候,不管條件成立不成立都會進行預解釋
在js中如果變量的名字和函數的名字重復了,也算沖突
如何查找當前作用域上一級作用域?看當前的函數是在那個作用域定義的,和執行沒有關系
內存的釋放和作用域銷毀
堆內存:
對象數據類型或者函數數據類型在定義的時候首先開辟一個堆內存,對內存有一個引用地址,如果外面有變量知道了這個地址,我們就說這個內存被占用了,就不能銷毀
我們想要讓堆內存釋放/銷毀,只需要把所有她的變量設置為null即可,如果當前的堆內存沒有任何東西被占用,那么瀏覽器會在空閑的時候把它銷毀...
棧內存
全局作用域
私有作用域(只有函數執行才能產生私有作用域)
一般情況下,函數執行會形成一個私有的作用域,當私有作用域執行完成后,都會主動的釋放和銷毀(即函數執行時開辟內存空間,執行完成后內存空間會被釋放和銷毀)
特殊情況下,當前私有作用域中的部分內存被作用域以為的變量占用了,那么當前的作用域就不能銷毀了(地址被其他占用,就不能夠銷毀)
function fn () { var num = 100; return function () { } } var f = fn() // 私有作用域被外界占用不會銷毀 fn()() // 不立即銷毀私有作用域,當返回的函數執行執行完畢后,再銷毀
自執行函數形成的作用域也不會銷毀(dom的click綁定函數也會占用作用域以外的內存,私有作用域也不會銷毀)
~function () { oDiv.onclick = function () { .... //原理都是一樣的,都是函數地址被別的占用不銷毀 } }js中的this
js中的this主要是函數中函數的this
js中的this代表當前執行的主體,js的contenxt代表的是當前的執行環境(this和執行上下文沒必然的聯系)
this是誰和函數在哪定義和在哪執行沒有必然的聯系
this在函數中5種情況
函數執行,首先看函數名之前,有沒有.,有點.的話之前是誰,this就是誰
function fn() { console.log(this) } var obj = {fn:fn}; obj.fn() // this 指向fn function sum (){ fn() } sum() // this指向window var o = { sum: function () { fn() } } o.sum() // this指向window
自執行函數中的this永遠指向window
給元素的某一個事件綁定一個方法,當事件觸發的時候,執行對應的方法,方法中的this是當前的元素
document.getElementById("#app").onclick = function(){ console.log(this) // this ->app元素對象 fn() // this指向window }
在構造函數當中,類中(函數體中)出現的this指向當前new創建的實例
設計模式單利模式
對象數據類型:把同一個事物的屬性和方法放在同一個孔家下,起到了分組的作用,不同事物之間的屬性即使屬性名相同,也不會發生沖突,這種分組編寫代碼的模式叫做單利模式(模塊化開發的原理)
缺點: 單利模式不能夠批量生產
工廠模式
把實現同一件是事情的相同代碼放在一個函數中,以后如果想實現這個功能,不需要重新在編寫這個代碼,直接調用函數即可 --> 函數的封裝
缺點:不能夠識別調用者的身份
function createPerson (name, age) { var obj = {}; obj.name = name; obj.age = age; obj.call = function() { .... } return obj }
構造函數模式
構造函數目的:就是為了創建一個自定義類
function createPerson (name, age) { var obj = {}; obj.name = name; obj.age = age; obj.call = function() { .... } return obj } function CreatePerson (name, age) { this.name = name; this.age = age; this.call = function() { .... } } var p1 = new createPerson("章三", 18)
工廠函數和構造函數的區別
執行的時候
普通函數執行 --> createPerson()
構造函數執行 ——> new createPerson() // 通過new創建出來一個實例(p1)
在函數執行的時候
相同點: 都是形成一個私有的作用域,然后形參賦值 ->預解釋 ->代碼自上而下執行
不同點:構造函數在代碼執行之前,不用再手動創建對象(new的作用)
1.瀏覽器會默認創建一個對象(而這個對象就是我們new創建出來的實例),
2.然后把屬性值和屬性名賦值給當前的實例,
3.最后瀏覽器會把創建的這個實例返回
檢測數據類型的方式:
typeof(): 檢測基本的數據類型
instanceof():檢測某一個實例是否屬于這個類
attr in Obj: 檢測某一個屬性(共有和私有)是否屬于這個對象
hasOwnProperty: 用來檢測一個私有屬性是夠屬于這個對象
原型模式
基于構造函數的圓形模式解決了方法和屬性共有的問題
1.每一個函數類型(函數,類)都有一個天生自帶的屬性:prototype,并且這個屬性是一個對象數據類型的值
并且在prototype上天生給他加了一個屬性constructor(構造函數),屬性值是當前函數本身
3.每一個對象數據類型(普通獨享,實例,prototype...)也天生自帶一個屬性:__proto__,屬性值是當前實例所屬類或函數的原型(prototype)
function Fn() { this.x = 100 } Fn.prototype.add = function () { console.log(this.x) } var f1 = new Fn(); var f2 = new Fn(); f1.hasOwnproperty("x")
Object是所有對象類型的基類
在Object.prototype上是沒有__proto__屬性(是唯一沒有的)
再實例對象f1上沒有hasOwnProPerty這個屬性?
通過對象名.屬性名 的形式獲取屬性值的時候,首先在對象的私有屬性進行查找,若果私有中存在這個屬性,則獲取這個私有屬性值;若果沒有,通過__proto__找到所屬類的原型(具有類原型定義的公共方法和屬性),原型存在的,獲取共有的屬性值;如果原型上也沒有,則繼續通過原型的__proto__繼續查找,直到找到Object.prototype為止,這種查詢模式叫做"原型鏈模式"
原型鏈模式遵行冒泡形式就近原型
所有類都是函數數據類型的,所有類的原型都是對象數據類型的
Fuction函數類,所有的函數數據類型都是它的一個實例
再內置類原型上擴展我們的方法
Array.prototype.mgUnique = function(){ var obj = {} for(var i=0;i
批量添加共有方法
function Fn(){ this.x = 100 } Fn.prototype = { // 重構原型的指向 constructor: Fn, // 手動添加constructor a: function(){ ... }, b:function(){ ... } }
克隆一個對象的方式
原生實現
function cloneObj(obj){ var obj2 = {}; for(var key in obj) { if(obj.hasOwnproperty(key)){ obj2[key] = obj[key] } } retuen obj2 }
Object.create(proObj): 創建一個新的對象,把proObj當作新創建對象的原型,IE8下不兼容
function object(o){ function Fn(){ } Fn.prototype = o; return new Fn; }1.原型繼承
B.prototype = new A;
原型鏈繼承的特點:子類B繼承了父類A所有的屬性和方法
#div.__proto__ -> HTMLDivElement.prototype -> HTMLElement.prototype ->Element.prototype -> Node.prototype ->EventTarget.prototype -> Object.prototype(Dom原型繼承的原理) function Object() { ... } Object.prototype = { constructor:Object, hasOwnProperty: function(){ ... } }; function EventTarget () { ... } EventTarget.prototype = new Object(); EventTarget.prototype.addEventListenter = function(){ ... } function Node(){ ... } Node.prototype = new EventTarget(); Node.prototype.createElement = function(){ ... }原型繼承并不是把父類中的屬性和方法克隆一份給子類,而是讓子類和父類增加了原型鏈的鏈接,喲吼子類獲取父類的方法,需要一級一級的向上查找來使用
2. call繼承
把父類的私有方法和屬性克隆一份,作為子類的私有屬性
function A(){ this.x = 100; } A.prototype.getX = function(){ console.log(this.x) } function B(){ A.call(this) // A.call(n) 把修改this的指向,并讓A執行 } var n = new B()3.冒充對象繼承 4.混合模式繼承
原型繼承+call繼承
function A(){ this.x = 100; } A.prototype.getX = function(){ console.log(this.x) } function B(){ A.call(this) // A.call(n) 把修改this的指向,并讓A執行 } B.prototype = new A; B.prototype.constaructor = B var n = new B()5.寄生混合式繼承function A(){ this.x = 100; } A.prototype.getX = function(){ console.log(this.x) } function B(){ A.call(this) // A.call(n) 把修改this的指向,并讓A執行 } B.prototype = Object.create(A.prototype); B.prototype.constaructor = B var n = new B()函數的三種角色function Fn(){ var num = 500; this.x = 100; } Fn.prototype.getX = function(){ console.log(this.x) } Fn.aaa = 1000; var f = new Fn(); f.num // undefined f.aaa // undefined var res = Fn() // this指向undefined Fn.aaa // 1000
函數在整個js中是最復雜也是最重要的知識
一個函數存在了多面性
普通函數:本身就是一個函數,執行的時候形成私有的左右域(閉包),形參賦值,預解釋,代碼執行,執行完成后內存銷毀/不銷毀
類:它有自己的實例,也有一個叫prototype屬性是自己的原型,它的實例都可以通過__proto__指向自己的原型
普通對象:和 var obj = {}中的obj一樣,就是一個普通對象,他作為對象可以有一些自己的私有屬性,也可以通過__proto__找到Function.prototype對象
文章版權歸作者所有,未經允許請勿轉載,若此文章存在違規行為,您可以聯系管理員刪除。
轉載請注明本文地址:http://m.specialneedsforspecialkids.com/yun/108775.html
摘要:基礎鞏固基礎總結使用已經好幾年了,由于工作主要是做服務端開發,在工作中逐漸發現的使用范圍原來越廣泛。這里要注意,務必將基礎部分掌握牢靠,磨刀不誤砍柴功,只有將基礎部分掌握并建立起系統的知識體系,在后面學習衍生的其他模式才能游刃有余。 基礎鞏固:JavaScript基礎總結 使用JavaScript已經好幾年了,由于工作主要是做服務端開發,在工作中逐漸發現JavaScript的使用范圍原...
摘要:下面我們從前端基礎和底層原理開始講起。對于和這三個對應于矢量圖位圖和圖的渲染來說,給前端開發帶來了重武器,很多小游戲也因此蓬勃發展。這篇文章受眾之大,后來被人重新整理并發布為,其中還包括中文版。 showImg(https://segmentfault.com/img/bVbjM5r?w=1142&h=640); 想閱讀更多優質文章請猛戳GitHub博客,一年百來篇優質文章等著你! 這...
摘要:也就是我們常見的瀏覽器以及內置瀏覽器,比如微信打開的大型移動端網頁。這個以微信小程序為例,主要是微信團隊基于前端基礎來做的封裝語法,主要的還是語法。學習路線放一下給大家。前端開發學習不是單一的,內容比較多,同樣應用的場景也非常多。 近兩年來,前端開發工程師越來越火了,2019年已經到來了,很多準備入行前端開發工程師的小伙伴們,不知道準備得怎么樣了呢?有的朋友在想方設法的學習,爭取在年后...
摘要:也就是我們常見的瀏覽器以及內置瀏覽器,比如微信打開的大型移動端網頁。這個以微信小程序為例,主要是微信團隊基于前端基礎來做的封裝語法,主要的還是語法。學習路線放一下給大家。前端開發學習不是單一的,內容比較多,同樣應用的場景也非常多。 近兩年來,前端開發工程師越來越火了,2019年已經到來了,很多準備入行前端開發工程師的小伙伴們,不知道準備得怎么樣了呢?有的朋友在想方設法的學習,爭取在年后...
摘要:也就是我們常見的瀏覽器以及內置瀏覽器,比如微信打開的大型移動端網頁。這個以微信小程序為例,主要是微信團隊基于前端基礎來做的封裝語法,主要的還是語法。學習路線放一下給大家。前端開發學習不是單一的,內容比較多,同樣應用的場景也非常多。 近兩年來,前端開發工程師越來越火了,2019年已經到來了,很多準備入行前端開發工程師的小伙伴們,不知道準備得怎么樣了呢?有的朋友在想方設法的學習,爭取在年后...
閱讀 2120·2021-11-24 09:39
閱讀 1504·2019-08-30 15:44
閱讀 1956·2019-08-29 17:06
閱讀 3409·2019-08-29 16:32
閱讀 3553·2019-08-29 16:26
閱讀 2662·2019-08-29 15:35
閱讀 3033·2019-08-29 12:50
閱讀 1649·2019-08-29 11:15