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