蜜桃精品成人影片_99热在线精品免费_日韩亚洲中字无码一区二区三区_亚洲中文字幕久久精品无码一区

您現(xiàn)在所在的位置:首頁 >學(xué)員就業(yè) > 就業(yè)寶典 > 前端經(jīng)典面試題之JavaScript篇

前端經(jīng)典面試題之JavaScript篇

來源:奇酷教育 發(fā)表于:

1 JavaScript基礎(chǔ)數(shù)據(jù)類型JavaScript數(shù)據(jù)類型包括原始類型和引用類型,原始類型有五個(gè):Number(數(shù)值) String(字符串) Boolean(布爾

1 JavaScript基礎(chǔ)數(shù)據(jù)類型

JavaScript數(shù)據(jù)類型包括原始類型和引用類型,原始類型有五個(gè):

Number(數(shù)值) String(字符串) Boolean(布爾) Null(空) Undefined(未定義)

引用類型有一個(gè):

Object(對(duì)象)

通過typeof(x)可以返回一個(gè)變量x的數(shù)據(jù)類型“number”、“string”、“boolean”、“undefined”、”object”,這里要注意一點(diǎn):typeof運(yùn)算符對(duì)于null類型返回的是object。

^ 《JavaScript高級(jí)程序設(shè)計(jì)》: 
這實(shí)際上是JavaScript最初實(shí)現(xiàn)中的一個(gè)錯(cuò)誤,后來被ECMAScript沿用了?,F(xiàn)在null被認(rèn)為是對(duì)象的占位符,從而解釋了這一矛盾。但是從技術(shù)上來說,它仍然是原始值。

2 談一談JavaScript作用域鏈

當(dāng)執(zhí)行一段JavaScript代碼(全局代碼或函數(shù))時(shí),JavaScript引擎會(huì)創(chuàng)建為其創(chuàng)建一個(gè)作用域又稱為執(zhí)行上下文(Execution Context),在頁面加載后會(huì)首先創(chuàng)建一個(gè)全局的作用域,然后每執(zhí)行一個(gè)函數(shù),會(huì)建立一個(gè)對(duì)應(yīng)的作用域,從而形成了一條作用域鏈。每個(gè)作用域都有一條 對(duì)應(yīng)的作用域鏈,鏈頭是全局作用域,鏈尾是當(dāng)前函數(shù)作用域。

作用域鏈的作用是用于解析標(biāo)識(shí)符,當(dāng)函數(shù)被創(chuàng)建時(shí)(不是執(zhí)行),會(huì)將this、arguments、命名參數(shù)和該函數(shù)中的所有局部變量添加到該當(dāng)前作用域 中,當(dāng)JavaScript需要查找變量X的時(shí)候(這個(gè)過程稱為變量解析),它首先會(huì)從作用域鏈中的鏈尾也就是當(dāng)前作用域進(jìn)行查找是否有X屬性,如果沒有 找到就順著作用域鏈繼續(xù)查找,直到查找到鏈頭,也就是全局作用域鏈,仍未找到該變量的話,就認(rèn)為這段代碼的作用域鏈上不存在x變量,并拋出一個(gè)引用錯(cuò)誤 (ReferenceError)的異常。

3 如何理解JavaScript原型鏈

JavaScript中的每個(gè)對(duì)象都有一個(gè)prototype屬性,我們稱之為原型,而原型的值也是一個(gè)對(duì)象,因此它也有自己的原型,這樣就串聯(lián)起來了一條原型鏈,原型鏈的鏈頭是object,它的prototype比較特殊,值為null。

原型鏈的作用是用于對(duì)象繼承,函數(shù)A的原型屬性(prototype property)是一個(gè)對(duì)象,當(dāng)這個(gè)函數(shù)被用作構(gòu)造函數(shù)來創(chuàng)建實(shí)例時(shí),該函數(shù)的原型屬性將被作為原型賦值給所有對(duì)象實(shí)例,比如我們新建一個(gè)數(shù)組,數(shù)組的方法便從數(shù)組的原型上繼承而來。

當(dāng)訪問對(duì)象的一個(gè)屬性時(shí), 首先查找對(duì)象本身, 找到則返回; 若未找到, 則繼續(xù)查找其原型對(duì)象的屬性(如果還找不到實(shí)際上還會(huì)沿著原型鏈向上查找, 直至到根). 只要沒有被覆蓋的話, 對(duì)象原型的屬性就能在所有的實(shí)例中找到,若整個(gè)原型鏈未找到則返回undefined;

4 JavaScript變量聲明提前

《JavaScript權(quán)威指南》中是這樣解釋的:JavaScript變量在聲明之前已經(jīng)可用,JavaScript的這個(gè)特性被非正式的稱為聲明提前(hoisting),即JavaScript函數(shù)中聲明的所有變量(但不涉及賦值)都被“提前”至函數(shù)的頂部。

從一個(gè)例子來看:

var scope = "global";

function myFunc(){

   console.log(scope);

   var scope = "local";

}

控制臺(tái)打印出來的不是“global”而是“undefined”,這是因?yàn)樵趍yFunc這個(gè)函數(shù)的作用域中,局部變量scope聲明被提前至函數(shù)頂部,而此時(shí),scope僅聲明,未賦值,因此輸出undefined。實(shí)際上,上面的代碼和下面的效果是一樣的:

var scope = "global";

function myFunc(){

   var scope;

   console.log(scope);

   scope = "local";

}

5 如何理解和應(yīng)用JavaScript閉包

關(guān)于閉包具體的定義文獻(xiàn)中給的概念很抽象,我認(rèn)為閉包是一種使函數(shù)能夠都去其它函數(shù)的局部變量的語法機(jī)制。

舉個(gè)例子:

function outFunc(){

   var name = "Vicfeel";

   function inFunc(){

       console.log(name);

   }

   return inFunc;

}

inFunc(); //控制臺(tái)顯示"Vicfeel"

這這個(gè)例子我們可以看出,在函數(shù)inFunc中依然可以訪問outFunc的局部變量name。

閉包應(yīng)用舉例,模擬類的私有屬性,利用閉包的性質(zhì),局部變量只有在sayAge方法中才可以訪問,而name在外部也訪問,從而實(shí)現(xiàn)了類的私有屬性。

function User(){

   this.name = "Vicfeel";  //共有屬性

   var age = 23;    //私有屬性

   this.sayAge:function(){

       console.log("my age is " + age);

   }

}

var user = new User();

console.log(user.name); //"Vicfeel"

console.log(user.age);  //"undefined"

user.sayAge();   //"my age is 23"


6 new構(gòu)建對(duì)象的本質(zhì)

function User(){

   this.name = "Vicfeel";

   this.age = 23;

}

 

var user = new User();

通過new操作符,實(shí)際上在構(gòu)造函數(shù)User中完成了如下操作:

創(chuàng)建一個(gè)新的對(duì)象,這個(gè)對(duì)象的類型是object; 
設(shè)置這個(gè)新的對(duì)象的內(nèi)部、可訪問性和prototype屬性為構(gòu)造函數(shù)(指prototype.construtor所指向的構(gòu)造函數(shù))中設(shè)置的; 
執(zhí)行構(gòu)造函數(shù); 
返回新創(chuàng)建的對(duì)象。

function User(){

   //this = {};  

   //this.constructor = User;

   this.name = "Vicfeel";

   this.age = 23;

   //return this;

}

 

var user = new User();

如果構(gòu)造函數(shù)默認(rèn)返回的新創(chuàng)建的this對(duì)象,如果手動(dòng)return 一個(gè)變量的話,如果該變量是原始類型則無效,如果是對(duì)象,則返回該對(duì)象。

7 JavaScript代理

當(dāng)我們需要對(duì)很多元素添加事件的時(shí)候,可以通過將事件添加到它們的父節(jié)點(diǎn)而將事件委托給父節(jié)點(diǎn)來觸發(fā)處理函數(shù)。

比如我們需要向一個(gè)ul中動(dòng)態(tài)添加很多個(gè)li,需要遍歷li逐個(gè)添加點(diǎn)擊事件

<ul id='list'></ul>

var count = 100;

var ulList = document.getElementById("list");

//動(dòng)態(tài)構(gòu)建節(jié)點(diǎn)

for(var i = count;i--;){

   var liDom = document.createElement('li');

   ulList.appendChild(liDom);

}

//綁定點(diǎn)擊事件

var liNode = ulList.getElementByTagName("li");

for(var i=0, l = liNodes.length; i < l; i++){

   liNode[i].onClick = function(){

       //li點(diǎn)擊事件

   }

}

眾 所周知,DOM操作是十分消耗性能的。所以重復(fù)的事件綁定簡(jiǎn)直是性能殺手。而事件代理的核心思想,就是通過盡量少的綁定,去監(jiān)聽盡量多的事件。如何做呢? 答案是利用事件冒泡機(jī)制,對(duì)其父節(jié)點(diǎn)ul進(jìn)行事件綁定(Event Bubble),然后通過event.target來判斷是哪個(gè)節(jié)點(diǎn)觸發(fā)的事件,從而減少很多EventHandler的綁定。

var count = 100;

var ulList = document.getElementById("list");

//動(dòng)態(tài)構(gòu)建節(jié)點(diǎn)

for(var i = count;i--;){

   var liDom = document.createElement('li');

   ulList.appendChild(liDom);

}

//綁定點(diǎn)擊事件

var liNode = ulList.getElementByTagName("li");

liNode.onClick = function(e){

   if(e.target && e.target.nodeName.toUpperCase == "LI") {

       // li點(diǎn)擊事件

   }

}

军事| 南开区| 临澧县| 虞城县| 滦平县| 鄂尔多斯市| 永兴县| 越西县| 盐源县| 潞城市| 荔浦县| 台东县| 张家口市| 漳浦县| 大悟县| 绥阳县| 城固县| 慈利县| 巴楚县| 广饶县| 瓮安县| 汝阳县| 江津市| 东台市| 镇康县| 来凤县| 深泽县| 禹城市| 巴彦淖尔市| 昌黎县| 五家渠市| 福州市| 晋江市| 汝州市| 来安县| 资溪县| 庐江县| 灌阳县| 永胜县| 兴文县| 牟定县|