小編給大家分享一下JavaScrip的常見面試題有哪些,相信大部分人都還不怎么了解,因此分享這篇文章給大家參考一下,希望大家閱讀完這篇文章后大有收獲,下面讓我們一起去了解一下吧!
在紅山等地區(qū),都構(gòu)建了全面的區(qū)域性戰(zhàn)略布局,加強發(fā)展的系統(tǒng)性、市場前瞻性、產(chǎn)品創(chuàng)新能力,以專注、極致的服務(wù)理念,為客戶提供網(wǎng)站建設(shè)、成都做網(wǎng)站 網(wǎng)站設(shè)計制作按需規(guī)劃網(wǎng)站,公司網(wǎng)站建設(shè),企業(yè)網(wǎng)站建設(shè),品牌網(wǎng)站建設(shè),全網(wǎng)營銷推廣,外貿(mào)網(wǎng)站建設(shè),紅山網(wǎng)站建設(shè)費用合理。
首先:this 永遠(yuǎn)指向函數(shù)運行時所在的對象,而不是函數(shù)被創(chuàng)建時所在的對象。匿名函數(shù)或不處于任何對象中的函數(shù)指向 window 。
1、 方法調(diào)用模式
當(dāng)函數(shù)被保存為對象的一個屬性時,成該函數(shù)為該對象的方法。函數(shù)中this的值為該對象。
var foo = { name: 'fooname', getName: function (){ return this.name } } foo.getName(); // this => foo
2、 函數(shù)調(diào)用模式
當(dāng)函數(shù)并不是對象的屬性。函數(shù)中this的值為全局對象
note:某個方法中的內(nèi)部函數(shù)中的this的值也是全局對象,而非外部函數(shù)的this
function foo(){ this.name = 'fooname'; } foo(); // this => window
3、構(gòu)造器調(diào)用模式
即使用new調(diào)用的函數(shù),則其中this將會被綁定到那個新構(gòu)造的對象。
function Foo(){ this.name = 'fooname'; } var foo = new Foo(); // this => foo
4、使用apply或call調(diào)用模式
該模式調(diào)用時,函數(shù)中this被綁定到apply或call方法調(diào)用時接受的第一個參數(shù)。
function getName(name){ this.name = name; } var foo = {}; getName.call(foo, name); // this =>foo
改變this的值主要方法(目前想到的,歡迎評論添加):
apply或call方法調(diào)用時強制修改,使this指向第一個參數(shù)。
使用Function.bind方法創(chuàng)造新的函數(shù),該新函數(shù)的中this指向所提供的第一個參數(shù)。
二、請解釋原型繼承 (prototypal inheritance) 的原理。
JavaScript沒有“子類”和“父類”的概念,也沒有“類”(class)和“實例”(instance)的區(qū)分,全靠“原型鏈”(prototype chain)模式,來實現(xiàn)繼承。
每個函數(shù)Sub都有一個屬性prototype,prototype指向一個原型對象,原型對象中也有一個指向函數(shù)的屬性constructor,通過new一個函數(shù)Sub可以產(chǎn)生實例instance,調(diào)用這個instance的某個屬性或方法時,instance會先查找自身是否有這個方法或者屬性,沒有的話就會去實例的構(gòu)造函數(shù)Sub的原型prototype中查找,即Sub.prototype,如果給原型對象Sub.prototype賦予另一個類型的實例superInstance,則是在superInstance中查找的,這個superInstance中也有屬性prototype指向某個原型對象,以此一級級往上最終到Object.prototype,這樣就形成了原型繼承。
利用此原理可以自己實現(xiàn)一個inherits函數(shù):
function inherits(subType, superType){ var _prototype = Object.create(superType.prototype); _prototype.constructor = subType; subType.prototype = _prototype; }
三、解釋為什么接下來這段代碼不是 IIFE (立即調(diào)用的函數(shù)表達(dá)式):function foo(){ }(); 要做哪些改動使它變成 IIFE?
(function fn(){..})()
,函數(shù)被包含在一個括號內(nèi),變成為一個表達(dá)式,隨后跟著一個(),就立即執(zhí)行這個函數(shù)。
IIFE的一些作用:
創(chuàng)建作用域,內(nèi)部保存一些大量臨時變量的代碼防止命名沖突。
一些庫的外層用這種形式包起來防止作用域污染。
運行一些只執(zhí)行一次的代碼。
四、(function fn(){..})(),函數(shù)被包含在一個括號內(nèi),變成為一個表達(dá)式,隨后跟著一個(),就立即執(zhí)行這個函數(shù)。
IIFE的一些作用:
創(chuàng)建作用域,內(nèi)部保存一些大量臨時變量的代碼防止命名沖突。
一些庫的外層用這種形式包起來防止作用域污染。
運行一些只執(zhí)行一次的代碼。
當(dāng)某個函數(shù)調(diào)用時會創(chuàng)建一個執(zhí)行環(huán)境以及作用域鏈,然后根據(jù)arguments和其它命名參數(shù)初始化形成活動對象。在外部函數(shù)調(diào)用結(jié)束后,其執(zhí)行環(huán)境與作用域鏈被銷毀,但是其活動對象保存在了閉包之中,最后在閉包函數(shù)調(diào)用結(jié)束后才銷毀。簡單的說,閉包就是能夠讀取其他函數(shù)內(nèi)部變量的函數(shù)。在js中,閉包是指有權(quán)訪問另一個函數(shù)作用域中的變量的函數(shù)。
如何使用:將A函數(shù)內(nèi)部的B函數(shù)作為A函數(shù)的返回值返回。
為什么要:
1、匿名自執(zhí)行函數(shù)
有的場景下函數(shù)只需要執(zhí)行一次,例如init()之類的函數(shù),其內(nèi)部變量無需維護(hù),我們可以使用閉包。 我們創(chuàng)建了一個匿名的函數(shù),并立即執(zhí)行它,由于外部無法引用它內(nèi)部的變量,因此在函數(shù)執(zhí)行完后會立刻釋放資源,而且不污染全局對象。
2、封裝
模擬面向?qū)ο蟮拇a風(fēng)格進(jìn)行封裝,使私有屬性存在成為可能。
五、.call 和 .apply 的區(qū)別是什么?
.call和.apply的共同點是都是用來改變函數(shù)體內(nèi)this對象的值。
區(qū)別是第二個參數(shù)不一樣。apply()的第二個參數(shù)是一個類數(shù)組對象arguments,參數(shù)都是以數(shù)組的形式傳入,而call(),傳遞給他的是一系列參數(shù)。例如
Math.max.call(null, 1, 2, 3, 4); //4 Math.max.apply(null, [1, 2, 3, 4]); //4
六、請解釋 Function.prototype.bind?
Function.prototype.bind方法會創(chuàng)建一個新函數(shù),當(dāng)這個新函數(shù)被調(diào)用時,它的this值是傳遞給bind()的第一個參數(shù), 它的參數(shù)是bind()的其他參數(shù)和其原本的參數(shù).
七、請指出 JavaScript 宿主對象 (host objects) 和原生對象 (native objects) 的區(qū)別?
宿主對象是指DOM和BOM。
原生對象是Object、Function、Array、String、Boolean、Number、Date、RegExp、Error、Math等對象。
八、請指出以下代碼的區(qū)別:function Person(){}、var person = Person()、var person = new Person()?
function Person(){}
聲明一個函數(shù)Person()。
var person = Person()
將函數(shù)Person()的結(jié)果返回給變量person,如果沒有返回值則person為undefined。
var person = new Person()
new一個Person的實例對象。
九、請盡可能詳盡的解釋 Ajax 的工作原理。以及使用 Ajax 都有哪些優(yōu)劣?
Ajax是無需刷新頁面就能從服務(wù)器取得數(shù)據(jù)的一種方法。
Ajax通過XmlHttpRequest對象來向服務(wù)器發(fā)異步請求,從服務(wù)器獲得數(shù)據(jù),然后用javascript來操作DOM更新頁面。
過程
創(chuàng)建XMLHttpRequest對象。
設(shè)置響應(yīng)HTTP請求的回調(diào)函數(shù)。
創(chuàng)建一個HTTP請求,指定相應(yīng)的請求方法、url等。
發(fā)送HTTP請求。
獲取服務(wù)器端返回的數(shù)據(jù)。
使用JavaScript操作DOM更新頁面。
缺點
對搜索引擎不友好
要實現(xiàn)Ajax下的前后退功能成本較大
跨域問題限制
十、請解釋變量聲明提升 (hoisting)。
變量的聲明前置就是把變量的聲明提升到當(dāng)前作用域的最前面。
函數(shù)的聲明前置就是把整個函數(shù)提升到當(dāng)前作用域的最前面(位于前置的變量聲明后面)。
//變量的聲明前置 console.log(num);//undefined var num = 1; 等價于 //變量的聲明前置 var num; console.log(num);//undefined num = 1;
十一、請描述事件冒泡機制 (event bubbling)。
事件冒泡(event bubbling),事件最開始時由觸發(fā)的那個元素身上發(fā)生,然后沿著DOM樹向上傳播,直到document對象。如果想阻止事件起泡,可以使用e.stopPropagation()。
十二、什么是 “use strict”; ? 使用它的好處和壞處分別是什么?
優(yōu)點
消除Javascript語法的一些不嚴(yán)謹(jǐn)之處,減少一些怪異行為;
消除代碼運行的一些不安全之處,保證代碼運行的安全;
提高編譯器效率,增加運行速度;
為未來新版本的Javascript做好鋪墊。
缺點
嚴(yán)格模式改變了語義。依賴這些改變可能會導(dǎo)致沒有實現(xiàn)嚴(yán)格模式的瀏覽器中出現(xiàn)問題或者錯誤。
十三、請解釋 JavaScript 的同源策略 (same-origin policy)。
同源策略限制了一個源(origin)中加載文本或腳本與來自其它源(origin)中資源的交互方式。同源指的是協(xié)議、域名、端口相同,同源策略是一種安全協(xié)議。
十四、請解釋 JSONP 的工作原理,以及它為什么不是真正的 Ajax。
JSONP(JSON with Padding)是一種非官方跨域數(shù)據(jù)交互協(xié)議,它允許在服務(wù)器端集成< script >標(biāo)簽返回至客戶端,通過javascript回調(diào)的形式實現(xiàn)跨域訪問。
因為同源策略的原因,我們不能使用XMLHttpRequest與外部服務(wù)器進(jìn)行通信,但是< script >可以訪問外部資源,所以通過JSON與< script >相結(jié)合的辦法,可以繞過同源策略從外部服務(wù)器直接取得可執(zhí)行的JavaScript函數(shù)。
原理
客戶端定義一個函數(shù),比如jsonpCallback,然后創(chuàng)建< script >,src為url + ?jsonp=jsonpCallback這樣的形式,之后服務(wù)器會生成一個和傳遞過來jsonpCallback一樣名字的參數(shù),并把需要傳遞的數(shù)據(jù)當(dāng)做參數(shù)傳入,比如jsonpCallback(json),然后返回給客戶端,此時客戶端就執(zhí)行了這個服務(wù)器端返回的jsonpCallback(json)回調(diào)。
通俗的說,就是客戶端定義一個函數(shù)然后請求,服務(wù)器端返回的javascript內(nèi)容就是調(diào)用這個函數(shù),需要的數(shù)據(jù)都當(dāng)做參數(shù)傳入這個函數(shù)了。
優(yōu)點 - 兼容性好,簡單易用,支持瀏覽器與服務(wù)器雙向通信
缺點 - 只支持GET請求;存在腳本注入以及跨站請求偽造等安全問題
補充一點,JSONP不使用XMLHttpRequest對象加載資源,不屬于真正意義上的AJAX。
十五、== 和 === 有什么不同?
通俗的說就是===比==要更為嚴(yán)格,===比較過程中沒有任何的類型轉(zhuǎn)換。
十六、什么是三元表達(dá)式 (Ternary expression)?“三元 (Ternary)” 表示什么意思?
如名字表示的三元運算符需要三個操作數(shù)。
語法是
條件 ? 結(jié)果1 : 結(jié)果2;
這里你把條件寫在問號(?)的前面后面跟著用冒號(:)分隔的結(jié)果1和結(jié)果2。滿足條件時結(jié)果1否則結(jié)果2。
十七、你怎么看 AMD vs. CommonJS?
瀏覽器端異步和服務(wù)器端同步的模塊化編程規(guī)范
十八、請舉出一個匿名函數(shù)的典型用例?
定義回調(diào)函數(shù),立即執(zhí)行函數(shù),作為返回值的函數(shù),使用方法var foo = function() {}定義的函數(shù)。
十九、描述以下變量的區(qū)別:null,undefined 或 undeclared?該如何檢測它們?
未定義的屬性、定義未賦值的為undefined,JavaScript訪問不會報錯;null是一種特殊的object;NaN是一種特殊的number;undeclared 是未聲明也未賦值的變量,JavaScript訪問會報錯。
二十、在什么時候你會使用 document.write()?
DOM方法,可向文檔寫入 HTML 表達(dá)式或 JavaScript 代碼。
二十一、如何實現(xiàn)下列代碼:[1,2,3,4,5].duplicator(); // [1,2,3,4,5,1,2,3,4,5]
Array.prototype.duplicator = function(){ var l = this.length,i; for(i=0;i二十二、解釋 function foo() {} 與 var foo = function() {} 用法的區(qū)別
函數(shù)聲明的兩種方法:
var foo = function () {}
這種方式是聲明了個變量,而這個變量是個方法,變量在js中是可以改變的。
也:將一個匿名函數(shù)賦值給了變量。
function foo() {}
這種方式是聲明了個方法,foo這個名字無法改變
二十三、請解釋可變 (mutable) 和不變 (immutable) 對象的區(qū)別。
在 JavaScript 中,對象是引用類型的數(shù)據(jù),其優(yōu)點在于頻繁的修改對象時都是在原對象的基礎(chǔ)上修改,并不需要重新創(chuàng)建,這樣可以有效的利用內(nèi)存,不會造成內(nèi)存空間的浪費,對象的這種特性可以稱之為 Mutable,中文的字面意思是「可變」。
Immutable 從字面上翻譯成中文是「不可變」。每次修改一個 Immutable 對象時都會創(chuàng)建一個新的不可變的對象,在新對象上操作并不會影響到原對象的數(shù)據(jù)。
二十四、使用 Promises 而非回調(diào) (callbacks) 優(yōu)缺點是什么?
Promise是異步編程的一種解決方案,比傳統(tǒng)的解決方案——回調(diào)函數(shù)和事件——更合理和更強大。它由社區(qū)最早提出和實現(xiàn),ES6將其寫進(jìn)了語言標(biāo)準(zhǔn),統(tǒng)一了用法,原生提供了Promise對象。
所謂Promise,簡單說就是一個容器,里面保存著某個未來才會結(jié)束的事件(通常是一個異步操作)的結(jié)果。從語法上說,Promise是一個對象,從它可以獲取異步操作的消息。Promise提供統(tǒng)一的API,各種異步操作都可以用同樣的方法進(jìn)行處理。
有了Promise對象,就可以將異步操作以同步操作的流程表達(dá)出來,避免了層層嵌套的回調(diào)函數(shù)。此外,Promise對象提供統(tǒng)一的接口,使得控制異步操作更加容易。
Promise也有一些缺點。
首先,無法取消Promise,一旦新建它就會立即執(zhí)行,無法中途取消。
其次,如果不設(shè)置回調(diào)函數(shù),Promise內(nèi)部拋出的錯誤,不會反應(yīng)到外部。
第三,當(dāng)處于Pending狀態(tài)時,無法得知目前進(jìn)展到哪一個階段(剛剛開始還是即將完成)。二十五、請解釋同步 (synchronous) 和異步 (asynchronous) 函數(shù)的區(qū)別。
同步調(diào)用,在發(fā)起一個函數(shù)或方法調(diào)用時,沒有得到結(jié)果之前,該調(diào)用就不返回,直到返回結(jié)果;
異步調(diào)用的概念和同步相對,在一個異步調(diào)用發(fā)起后,被調(diào)用者立即返回給調(diào)用者,但調(diào)用者不能立刻得到結(jié)果,被調(diào)用者在實際處理這個調(diào)用的請求完成后,通過狀態(tài)、通知或回調(diào)等方式來通知調(diào)用者請求處理的結(jié)果。
簡單地說,同步就是發(fā)出一個請求后什么事都不做,一直等待請求返回后才會繼續(xù)做事;異步就是發(fā)出請求后繼續(xù)去做其他事,這個請求處理完成后會通知你,這時候就可以處理這個回應(yīng)了。
二十六、你使用哪些工具和技術(shù)來調(diào)試 JavaScript 代碼?
1.javascript的debugger語句
需要調(diào)試js的時候,我們可以給需要調(diào)試的地方通過debugger打斷點,代碼執(zhí)行到斷點就會暫定,這時候通過單步調(diào)試等方式就可以調(diào)試js代碼if (waldo) { debugger; }這時候打開console面板,就可以調(diào)試了
2.DOM斷點
DOM斷點是一個Firebug和chrome DevTools提供的功能,當(dāng)js需要操作打了斷點的DOM時,會自動暫停,類似debugger調(diào)試。
使用DOM斷點步驟:
選擇你要打斷點的DOM節(jié)點
右鍵選擇Break on..
選擇斷點類型另外的調(diào)試方法例如alert, console.log,查看元素等就不再贅述了。
二十七、你會使用怎樣的語言結(jié)構(gòu)來遍歷對象屬性 (object properties) 和數(shù)組內(nèi)容?
for in 語句
一般for循環(huán)
數(shù)組forEach方法以上是“JavaScrip的常見面試題有哪些”這篇文章的所有內(nèi)容,感謝各位的閱讀!相信大家都有了一定的了解,希望分享的內(nèi)容對大家有所幫助,如果還想學(xué)習(xí)更多知識,歡迎關(guān)注創(chuàng)新互聯(lián)行業(yè)資訊頻道!
名稱欄目:JavaScrip的常見面試題有哪些
當(dāng)前路徑:http://weahome.cn/article/pjhhip.html