JavaScript與DOM常見面試題

1. JavaScriptjavascript

 

1.1.簡要描述 JavaScript的數據類型?html

 

參考答案:java


Java Sc ri pt 的數據類型能夠分爲原始類型和對象類型。
原始類型包括 string、 number和 boolean三種。其中,字符串是使用一對單引號或者一對雙引號括起來的任意文本;而數值類型都採用64位浮點格式存儲,不區分整數和小數;布爾(邏輯)只能有兩個值: true或 false。
複雜類型指其餘對象,如 Array、 Date、 Object等。
除此以外, JavaScript中還有兩個特殊的原始值: null(空)和 undefined(未定義),它們表明了各自特殊類型的惟一成員。node

 

 

1.2.讀代碼,寫結果 git

寫出下列表達式的計算結果: 正則表達式

var a= [];
var b= a;
b[0] = 1;
console.log(a[0] ) ; console.log(b[0] ) ; console.log(a===b) ; 數組

參考答案:瀏覽器

上述代碼的結果分別爲:緩存

1
1
true
將對象賦值給變量,僅僅是賦值的引用,對象自己並無賦值一次,所以,變量 a和 b 指向同一個數組閉包

 

 

1.3.簡要描述 null和 undefined的區別

 

參考答案:


null:是 JavaScript的關鍵字,用於描述「空值」,對其執行 typeof操做,返回「object」,
即爲一個特殊的對象值,能夠表示數字、字符串和對象是「無值」的。
undefined:是預約義的全局變量,其值爲「未定義」,它是變量的一種取值,表示變
量沒有初始化。 當查詢對象屬性、數組元素的值時,若是返回 undefined則表示屬性或者元素不存在;若是函數沒有任何返回值,也返回 undefined。
須要注意的是,雖然 null和 undfined是不一樣的,可是由於都表示「值的空缺」,二者能夠互換。所以,使用「==」認爲兩者是相等的,須要使用「===」來區分它們。

 

1.4.讀代碼,寫結果

寫出下列表達式的計算結果:

10+ "objects" "7" * "4"

1 - "x"
1+ {}
true+ true
2 + null

 

參考答案:

上述代碼的結果分別爲:

10objects
28
NaN
1[object Ojbect] 2

1.5.讀代碼,寫結果

 

/ /轉換爲字符串
/ /轉換爲字符
//沒法轉換爲數值進行計算,所以返回 NaN
//返回對象的 toString( )結果,按照字符串相加/ / bo o l 類型轉換爲數值類型
//null轉換爲數值 0

 

寫出下列代碼的輸出結果:

 

var a= 2;
var obj= { x: 1, y: { z: 2} }; var n= [obj,3,[4,5]];
console.log(a<< 2);
console.log(obj["y"] .z) ;
console.log(n[0] .y["z"] ) ;
console.log(n[2] ["1"] ) ;
delete n[0];
console.log(n[0] .x) ;

 

參考答案: 

 

上述代碼的輸出結果分別爲: 

8
2
2
5
console. log(n[ 0] .x) ;此行代碼錯誤,沒法輸出有效信息,會輸出 Error信息

 

 

1.6.閱讀以下代碼:

var x= 10;
var y= 20;
var z= x< y? x++ : ++y;

 

上述代碼運行後,變量 x、 y和 z的值爲多少?


參考答案:


上述代碼運行後,變量x的值爲11;變量 y的值爲20;變量 z的值爲10。
這是由於,運行第三行代碼時,只執行?後的第一個語句,所以, y的值不發生變化,仍爲20;並返回 x的值賦值給變量z,所以z的值爲10;而後將 x的值增長1,變爲11。

 

 

1.7.什麼是「邏輯短路」?

 

參考答案:
邏輯短路是對於邏輯運算而言,是指,僅計算邏輯表達式中的一部分便能肯定結果,而不對整個表達式進行計算的現象。
對於「&&」運算符,當第一個操做數爲 false時,將不會判斷第二個操做數,由於此時不管第二個操做數爲什麼,最後的運算結果必定是 false;
對於「||」運算符,當第一個操做數爲 true時,將不會判斷第二個操做數,由於此時不管第二個操做數爲什麼,最後的運算結果必定是 true。

 

1.8.閱讀以下代碼

var empAge= 20;
var empName;
if (empAge> 20&& empName.length> 0) {
console.log(1) ;
}
else {
console.log(2) ;
}

 

上述代碼運行後,將產生有效輸出,仍是代碼錯誤?

 

參考答案:


上述代碼運行,會輸出2,而不會發生錯誤。
這是由於, if條件中的邏輯表達式的第一個條件( empAge> 20)不知足,會返回false,此時,將發生「邏輯短路」,而不會繼續判斷下一個條件。所以,即便下一個條件中的變量 empName沒有賦值,此時若是計算 empName.length將發生錯誤;可是,由於發生了「邏輯短路」,不會計算此表達式,所以不會發生錯誤。
既然 if條件中的邏輯表達式返回 false,則運行 else語句:輸出2。

 

 

1.9.解釋一下 JavaScript中的局部變量與全局變量的區別

 

參考答案:
全局變量擁有全局做用域,在 JavaScript代碼的任何地方均可以訪問;在函數內聲明的變量只在函數體內有定義,即爲局部變量,其做用域是局部性的。
須要注意的是,在函數體內聲明局部變量時,若是不使用 var關鍵字,則將聲明全局變量。

 

 

1.10. 讀代碼,寫結果

 

寫出下列代碼的輸出結果:

 

var x= "global";
function test() {
var x= "local";
return x;
}
console.log(test( ) ) ;

 

參考答案:
上述代碼的輸出結果爲 local。這是由於,在函數 test()體內,局部變量的優先級高於同名的全局變量。所以,若是在函數體內聲明的局部變量和全局變量重名,則以局部變量優先。所以,調用函數 test()時,返回的是局部變量x,其值爲 local。

 

 

1.11. 什麼是 JavaScript中的函數做用域

 

參考答案:
J ava Sc ri pt 中的函數做用域是指 : 變量在聲明它的函數體以及這個函數體嵌套的任意函數體內都是有定義的。這意味着,在函數體內聲明的全部變量在整個函數體內始終是可見的,這種特性也被稱爲「聲明提早」,即,函數內聲明的全部變量(不涉及到賦值)都被提早至函數的頂部聲明。

 

好比,查看以下代碼:

 

function test() {
console.log(x) ;
var x= 10;
console.log(x) ; }
test() ;

 

上述代碼運行,將先輸出 undefined,再輸出10。
這是由於,雖然變量 x在第二行聲明並賦值,但其有效範圍爲整個函數體,所以,第
一行代碼輸出時,表示變量 x已經聲明可是沒有賦值,所以輸出 undefined;第三行代碼
運行時,由於變量 x已經賦值爲10,則輸出10。

1.12. 讀代碼,寫結果

 

寫出下列代碼的輸出結果:

 

function test() {
var sum= 0;
for (var i= 0; i< 10; i++) {
sum+= i;
}
console.log(sum) ;
console.log(i) ;
}
test() ;

 

參考答案:


上述代碼中,輸出 sum的值爲45;輸出 i的值爲10。
這是由於,在函數 test()體內,循環計算完畢後,變量 sum的值爲從 0累加到10 的和,即45;變量 i雖然是在 for循環中聲明,可是在整個函數體內都有效(函數做用域),所以,循環完畢後,變量 i的值爲10。

 

 

1.13. 讀代碼,寫結果

 

寫出下列代碼的輸出結果:

 

var x= "global";
function test() {
console.log(x) ;
var x= "local";
console.log(x) ;
}
test() ;

 

參考答案:

 

上述代碼中,先輸出 undefined,再輸出 local。
函數 test()體內聲明瞭與全局變量同名的局部變量 x,則將覆蓋全局變量,即局部變量優先。所以,第一次輸出變量 x時,爲輸出局部變量x,此時變量 x只有聲明而沒有賦值,所以輸出 undefined;第二次輸出變量 x時,局部變量x已經賦值,所以輸出字符串local。

 

 

1.14. 簡述 arguments對象的做用

 

參考答案:
在函數代碼中,使用特殊對象 arguments能夠訪問函數的參數。即,開發者在定義函數時,無需明確的爲方法聲明參數,也能夠在方法體中使用 arguments來訪問參數。這是由於, arguments是一種特殊對象,在函數代碼中,表示函數的參數數組。
正由於 arguments表示參數組成的數組,所以,首先可使用 arguments.length 檢測函數的參數個數,其次,能夠經過下標( arguments[index])來訪問某個參數。這樣,能夠用 arguments對象判斷傳遞給函數的參數個數並獲取參數,適用於函數參數沒法肯定個數的狀況下。

 

 

1.15. 簡要描述 JavaScript中定義函數的幾種方式

 

參考答案:


JavaScript中,有三種定義函數的方式:
一、函數語句:即便用 function關鍵字顯式定義函數。如:

function f(x){
return x+1;

二、函數定義表達式:也稱爲「函數直接量」。形如: 

var f= function(x){return x+1;}; 

三、使用 Function()構造函數定義,形如: 

Var f= new Function(「x」,」return x+1;」);


1.16. 讀代碼,寫結果

 

寫出下列代碼的輸出結果:

 

var f= function (x) { return x* x; }

console.log(f) ;
console.log(f(10) ) ;

 

參考答案:


上述代碼運行時,先輸出 function(x) { return x* x; };再輸出100。
這是由於,變量 f表明一個函數對象,所以直接輸出變量時,將輸出函數體對應的字符文本; f(10)表示調用變量 f所對應的函數,返回100並輸出。

 

1.17. 閱讀以下代碼

function f() {
console.log("function") ; }
function test() {
console.log(f) ;
f();
f= "hello";
console.log(f) ;
f();
}
test() ;

 

上述代碼運行後,輸出結果爲?


參考答案:


上述代碼運行,會先輸出
function f() {
console.log("function");
};
而後輸出 function;再輸出 hello;而後會輸出異常信息: string is not a function。
這是由於,定義函數時,函數名稱做爲一個全局變量,該變量指向函數對象。所以,執行函數 test中的第一行代碼時,將輸出變量 f所對應的函數對象,即輸出函數體中代碼的字符串形式;而後執行 f()表示調用方法 f,則輸出字符串「function」;執行代碼 f =「hello」,意味着將變量 f的值改成字符串,所以再輸出變量 f時,將輸出字符串「Hello」;而若是試圖再執行 f(),會引起錯誤。這是由於,此時,變量 f再也不是一個函數對象,而
是一個普通字符串。

 

 

1.18. 列舉幾個 JavaScript中經常使用的全局函數,並描述其做用 

參考答案

JavaScript 中經常使用的全局函數及其做用以下:
1. parseInt:解析一個字符串並返回一個整數;

}}

2. parseFloat:解析一個字符串並返回一個浮點數;
3. isNaN:檢查某個值是不是數字,返回 true或者 false;
4. encodeURI :把字符串做爲 URI進行編碼;
5.decodeURI :對 encodeURI()函數編碼過的 URI進行解碼;
6. eval:計算某個字符串,以獲得結果,或者用於執行其中的 JavaScript代碼。

 

1.19. 閱讀以下代碼

function printArray(arr) {
for (var i in arr) {
if (arr[i] instanceof Array) {
printArray(arr[i] ) ;
} else {
document.write(arr[i] + ' ');
}
}
}
var data= [1, [20, 21], [[301, 302], [310, 311]]]; printArray(data) ;

 

上述代碼運行後,頁面的輸出結果爲?


參考答案:


上述代碼運行,會在頁面輸出:1 20 21 301 302 310 311。
函數 printArray使用了遞歸方式,逐一輸出數組中的每一個成員,中間以空格隔開。

 

 

1.20. 編寫函數,實現冒泡排序

 

參考答案:
使用 JavaScript編寫的冒泡排序函數以下所示:

 

function bubbleSort(arr) {
for (var i= 0; i< arr.length; i++) {
for (var j= 0; j< arr.length- i- 1; j++) {
if (arr[j] > arr[j+ 1]) {
var temp= arr[j];
arr[j] = arr[j + 1];
arr[j+ 1] = temp;
}
}

測試函數 bubbleSort,代碼以下:

var arr= [12, 4, 9, 21, 43, 3]; bubbleSort(arr) ;
console.log(arr) ;

arr[j + 1] = arr[j]; }//插入元素arr[j+ 1] = k;}9

 

上述代碼運行時,將輸出排序後的結果:[3, 4, 9, 12, 21, 43]。

 

1.21. 編寫函數,實現插入排序

 

參考答案:
插入排序是指,先假定將 n個元素的數列分爲已有序和無序兩個部分;而後將無序數列的第一個元素與有序數列的元素從後往前逐個進行比較,找出插入位置,將該元素插入到有序數列的合適位置中。過程以下圖所示:

使用 JavaScript編寫的插入排序函數以下所示:

 

function insertionSort(arr) {
/ /從第二個元素開始
for (var i= 1; i< arr.length; i++) {
//取出待比較的元素
var k= arr[i];
//向前找,找到比當前元素大的位置
var j;
for (j= i- 1; j>= 0&& k< arr[j]; j--) {
/ /向後移動一位

 

}

 

測試函數 insertionSort,代碼以下:

 

var arr= [12, 4, 9, 21, 43, 3]; insertionSort(arr) ;
console.log(arr) ;

/ /驗證方法function verifyCode(id) {if(id.length !=18 )var c= sum%11;//三、分別對應的最後一位身份證的號碼爲:1- 0- X-9-8-7-6-5-4-3-2}10

 

上述代碼運行時,將輸出排序後的結果:[3, 4, 9, 12, 21, 43]。

 

1.22. 編寫函數,實現對身份證號碼最後一位的驗證

 

二代身份證號碼爲18位,其最後一位(第18位)的計算方法爲:


一、 將前面的身份證號碼17位數分別乘以不一樣的係數。從第一位到第十七位的係數分
別爲:

 

7-9-10-5-8-4-2-1-6-3-7-9-10-5-8-4-2


二、 將這17位數字和係數相乘的結果相加


三、 用加出來和除以11,看餘數是多少?


四、 餘數只可能有 0-1-2-3-4-5-6-7-8-9-10這11個數字。每一個數字所對應
的最後一位身份證的號碼爲:1- 0- X-9-8-7-6-5-4-3-2。即,若是餘數
是2,就會在身份證的第18位數字上出現羅馬數字的Ⅹ。若是餘數是10,身份證
的最後一位號碼就是2。
例如:某男性的身份證號碼是34052419800101001X。驗證其最後一位是否正確時,首先須要得出前17位的乘積和是189,而後用189除以11得出的結果是17+2/11,也就是說其他數是2。最後經過對應規則就能夠知道餘數2對應的數字是 x。因此,能夠斷定此身份證號碼的最後一位是合格的。


參考答案:


編寫驗證方法以下:

return false;
/*一、從第一位到第十七位的係數分別爲:
7,9,10,5,8,4,2,1,6,3,7,9,10,5,8,4,2
將這17位數字和係數相乘的結果相加。 */
var arr= [7,9,10,5,8,4,2,1,6,3,7,9,10,5,8,4,2]; var sum= 0;
for(var i=0; i<arr.length; i++){
sum+= parseInt(id.charAt(i) ) * arr[i];
}
//二、用加出來和除以11,看餘數,

var ch= ['1', '0', 'X', '9', '8', '7', '6', '5', '4', '3', '2']; var code= ch[c];
var last= id.charAt(17);
last= last=='x' ? 'X': last;
return last== code;

 

測試該方法: 

var id= "34052419800101001X"; console.log(verifyCode(id) ) ; 


1.23. 讀代碼,寫結果

 

寫出下列代碼的輸出結果:

 

var arr1 = [10, 20];
arr1 .push(30) ;
arr1.push( [40, 50] ) ;
var data= arr1.pop(); console.log(data) ;

 

參考答案:


上述代碼的輸出結果爲[40, 50]。
數組的方法 push()表示入棧,即在棧頂(數組尾端)添加指定的元素;方法 pop()表示出棧,刪除並返回棧頂(數組尾端)的元素。
代碼中,第一次入棧爲數字30;第二次入棧爲數組[40,50],且該數組排在棧頂。所以,調用方法 pop()時,將刪除並返回棧頂元素[40,50],這是一個數組,所以輸出結果爲[40, 50]。

 

 

1.24. 什麼是棧?在 JavaScript中,如何模擬棧操做?

 

參考答案:
棧( stack)是一種運算受限的線性表,其限制是僅容許在表的一端進行插入和刪除運算。這一端被稱爲棧頂,相對的把另外一端稱爲棧底。向一個棧插入新元素又稱做進棧、入棧或壓棧,它是把新元素放到棧頂元素的上面,使之成爲新的棧頂元素;從一個棧刪除元素又稱做出棧或退棧,它是把棧頂元素刪除掉,使其相鄰的元素成爲新的棧頂元素。棧的操做以下圖所示:

 

在 JavaScript中,可使用數組及其相關操做來模擬棧操做。首先,使用數組存儲一列元素,而後使用數組的 push()方法在數組的尾部添加指定的元素,相似於在棧頂添加元素,即頂部入;而後使用數組的 pop()刪除並返回數組尾部的元素,相似於頂部出棧,即後入的元素先出。

 

 

1.25. 讀代碼,寫結果

 

寫出下列代碼的輸出結果:

 

var arr1 = [10, 20, 30, 40]; arr1 .push(50) ;
arr1 .shift( ) ;
console.log(arr1 ) ;

 

參考答案:


上述代碼的輸出結果爲[20, 30, 40, 50]。
數組的方法 push()表示入棧,即在棧頂(數組尾端)添加指定的元素,所以,數字50將做爲數組的最後一個元素;方法 shift()表示刪除並返回棧底(數組頭部)的元素,所以,將從數組刪除數值10。此時,輸出數組,將輸出剩餘的4個數值,即[20, 30, 40, 50]。

 

 

1.26. 什麼是正則表達式?在 JavaScript中,如何應用正則表達式?

 

參考答案:
正則表達式(Regular Expression)自己就是一個字符串,由一些普通字符和特殊字符組成的,用以描述一種特定的字符規則的表達式。
正則表達式經常使用於在一段文本中搜索、匹配或替換特定形式的文本。如:詞語出現頻率

}console.log('try block end' ) ;} catch (e) {console.log( 'catch block' ) ;return;} finally{console.log( 'finally block' ) ;}console.log( ' function end' ) ;}add( '10x' ) ;13

 

統計、驗證字符串是否符合郵箱格式、屏蔽一篇帖子中的限制性詞語等。許多程序設計語言都支持利用正則表達式進行字符串操做。
在 JavaScript中,正則表達式的應用分爲兩種:
一、結合 String對象的 replace、 search和 match方法,實現對字符串的替換、查
找和匹配;
二、定義正則表達式對象,實現對字符串的複雜匹配操做。

 

 

1.27. 讀代碼,寫結果

 

寫出下列代碼的輸出結果: 

var regexp= /\bdo\b/ig;
var data= 'He does told to Do,do.'; console.log(data.search(regexp) ) ;

參考答案:

上述代碼的輸出結果爲3。
String的 search(regexp)方法,用於返回第一次出現匹配指定正則表達式的下標,若沒有匹配則返回- 1。
試題中,正則表達式\bdo\b表示匹配完整的單詞 do,且不區分大小寫。而變量 data 中,第一次出現單詞 do(不區分大小寫)的位置爲16。

 

 

1.28. 閱讀以下代碼

function add(num) {
try{
num= Number(num) ;
if (isNaN(num)) {
throw new Error('Arguments is NaN');

上述代碼運行後,輸出結果爲?


參考答案:


上述代碼運行,會先輸出 catch block;再輸出 finally block。

 

這是由於,執行代碼 num= Number(num);時,由於傳入的參數值爲字符串「10x」,沒法轉換爲 number類型,則產生錯誤,運行到 catch語句塊中,輸出「catch bloc」;而 finally塊始終會運行,所以繼續輸出「finallyblock」。程序發生異常後,將退出,所以再也不執行其餘語句。

 

 

1.29. 簡要描述 JavaScript中的匿名函數

 

參考答案:


匿名函數是指在定義時沒有指定名字的函數,且定義後每每直接調用。如:

 

function(num1, num2) {
console.log( num1 + num2 ); } 

這種方式所定義的匿名函數,每每須要直接調用,如: 

(function (num1, num2) {
console.log(num1 + num2); }) (10,20);
匿名函數經常使用於定義不須要重複使用的函數,用完即釋放。另外,對於直接調用的匿名函數而言,能夠當作是一個臨時的命名空間,其區域內定義的全部變量,不會污染到全局命名空間。 

 

1.30. 簡要描述 JavaScript中的做用域鏈

 

參考答案:
任何一段 JavaScript代碼都對應一個做用域鏈,做用域鏈中存放一系列對象,代碼中聲明的變量將做爲對象的屬性存放。
在 JavaScript的頂層代碼中,做用域鏈由一個全局對象組成;當定義一個函數時,它保存一個做用域鏈,做用域鏈上有兩個對象,一個是函數對象,一個是全局對象。
每當一個函數被調用時,會建立一個活動對象(也叫上下文對象),函數中的局部變量將做爲該對象的屬性存放。
當須要使用一個變量時,將從做用域鏈中逐個查找對象的屬性。好比:要使用變量 a,將先查找做用域中的第一個對象是否有屬性 a,若是有就使用;若是沒有就查找做用域鏈中下一個對象的屬性,以此類推。若是做用域鏈上沒有任何一個對象含有屬性 x,則認爲這段代碼的做用域鏈上不存在 x,將拋出引用錯誤異常。
當函數調用完成後,若是沒有其餘引用指向爲這次調用所建立的上下文對象,該對象將被回收。

 

1.31. 閱讀以下代碼

var a= 100;
function f() {
var a= 200;
function g() {
return a;
}
return g;
}
console.log(f() () ) ;

 

上述代碼運行後,輸出結果爲?


參考答案:


上述代碼運行,會輸出200。
上述代碼意味着,先執行 f(),獲得該函數內嵌套的一個函數對象 g,而後調用這個嵌
套的函數。
定義函數 f時,它保存一個做用域鏈,做用域鏈上有兩個對象,一個是函數對象,
個是全局對象,此時,全局變量 a是全局對象的屬性,和函數對象 f無關。
執行函數 f時,會建立一個活動對象,其中保存變量 a做爲函數 f的屬性而存在。
而函數 g嵌套定義在函數 f裏,對其訪問變量 a時,它沒有變量 a,則繼續往下查找函數
f。找到函數 f的屬性 a並返回。所以,輸出結果爲200。
這種函數將變量包裹起來,外部代碼能夠經過內嵌函數 g來訪問函數 f內的局部變量
的方式,也稱爲閉包。

 

 

1.32. 簡要描述你對閉包的理解

 

參考答案:


函數對象能夠經過做用域鏈相互關聯起來,函數體內部的變量均可以保存在函數做用域
這種特性稱爲閉包。這意味着函數變量能夠隱藏於做用域鏈以內,看起來好像是函數將
變量包裹了起來。這種方式經常使用於共享函數內的私有變量。
閉包有以下應用特徵:
一、局部變量:在函數中定義有共享意義(如:緩存、計數器等)的局部變量(注:定
義成全局變量會對外形成污染);
二、內嵌函數:在函數中聲明有內嵌函數,內嵌函數對函數中的局部變量進行訪問;
三、外部使用:函數向外返回此內嵌函數,外部能夠經過此內嵌函數持有並訪問聲明在
函數中的局部變量,而此變量在外部是經過其餘途徑沒法訪問的。

 

1.33. 閱讀以下代碼

var n= 10;
function counter() {
var n= 0;
var g= function () {
return++n;
};
return g;
}
var c1 = counter(); console.log(c1 ( ) ) ; console.log(c1 ( ) ) ; console.log(c1 ( ) ) ;

 

上述代碼運行後的輸出爲?


參考答案:


上述代碼運行後,分別輸出數字一、二、3。
首先從應用上分析,這是一個閉包的典型應用:模擬計數器。調用一次函數 counter,則獲得一個計數器,即代碼中的變量 c1,用於統計被調用的次數;每運行一次計數器 c1,則訪問次數加1。所以分別輸出數字一、二、3。
其次從代碼原理來分析:函數 counter返回其內嵌函數 g,該函數中包裹了函數counter的局部變量 n,其初始值爲 0;每次運行函數 g,均訪問相應的局部變量 n,從而實現累加計數的效果。

 

 

1.34. 閱讀以下代碼

 

 

for (var i= 0; i< 3; i++) {
setTimeout(function () { alert(i); }, 3000);
}
上述代碼但願實現:3s後彈出三次警告對話框,對話框中顯示的數字分別爲 0、一、2。問,上述代碼可否實現所須要的效果?若是不能,應該如何實現?


參考答案:
上述代碼不能實現所須要的效果。會在3s後彈出三次警告對話框,對話框中的數字均爲3。
這是由於,循環結束後,變量 i的值爲3;當3s後運行循環中內嵌的函數,執行語句alert(i)時,訪問的是循環中的變量 i。所以,三次彈出均爲數值3。
若是但願實現分別彈出數字 0、一、2,須要將代碼修改以下:

 

for (var i= 0; i< 3; i++) {
(function (n) {
setTimeout(function () { alert(n); }, 3000);
})(i);
}

 

修改後的代碼中,使用匿名函數封裝一次性定時器的代碼,並在調用匿名函數時,將變量 i的值做爲參數傳入。每次循環中,調用一次匿名函數,則啓動一個定時器對象,將相應的數字傳入。3s後執行函數時,再也不訪問循環中的局部變量 i,則會依次彈出 0、一、2。

 

 

1.35. 簡述 JavaScript中建立自定義對象的方式

 

參考答案:


自定義對象( user-defined object)指由用戶建立的對象,兼容性問題須要由編寫者
注意。建立自定義對象的方式有:
一、對象直接量
二、 newObject()
三、 function對象模板
四、 Object.create()

 

 

1.36. 查看以下 JavaScript代碼:

 

 

var p= new User("mary");
alert(p.name) ; //彈出 mary
p.introduce(); //彈出 i am mary

 

爲使上段代碼正確運行,請定義對象 User。


參考答案:


須要使用 function模板建立對象 User,代碼以下:

 

function User(name) {
this.name= name;
this.introduce= function () {
alert("i am" + this.name);
};
}

 


1.37. JavaScript中, this關鍵字的做用是什麼?

 

參考答案:
籠統的說,關鍵字 this指向當前對象。好比,頂級代碼中的 this指向全局對象;在指定元素事件的時候, this指定當前發生事件的元素對象。
對於嵌套函數,若是嵌套函數做爲方法被調用,其 this指向調用它的對象;若是做爲函數調用, this是全局對象或者爲 undefined(嚴格模式下)。


1.38. 查看以下 JavaScript代碼:

var o= {
m: function () {
console.log(this) ;
f();

}
};
o.m();
function f() {
console.log(this) ; }

請描述上述代碼的運行結果。

參考答案:
上述代碼在瀏覽器中運行後,第一行的輸出結果相似於: Object{m: function},表示this關鍵字指向調用它的當前對象;第二行的輸出結果爲 Window,表示 this關鍵字指向全局變量。
這是由於,調用對象 o的方法 m,在該方法中直接使用 this關鍵字,則指向調用它的對象;而後運行嵌套函數 f時, this指向全局對象,在瀏覽器中運行時,全局對象爲Window對象。須要注意的是,若是使用嚴格模式,則第二行會輸出 undefined。

 

 

1.39. 查看以下 JavaScript代碼:

var a= 10;
var foo= {
a: 20,
bar: function () { var a= 30; return this.a} }
console.log(foo.bar( ) ) ;
console.log( (foo.bar= foo.bar) ());

上述代碼運行後,輸出結果是?

參考答案:
上述代碼運行後,先輸出20。這是由於調用對象 foo的 bar()方法時, this關鍵字指向調用它的對象,即 foo,所以,輸出該對象中所定義的屬性值。
第二行將輸出 10。這是屬於函數調用,此時,非嚴格模式下 th is指代全局對象window,所以 a的值爲10。

 

1.40. 簡述你對 JavaScript中原型的理解

 

參考答案:

 

在 JavaScript中,函數自己就是一個包含了方法和屬性的對象。每一個函數中都有一個prototype屬性,該屬性所存儲的就是原型對象。
原型對象用來保存共享屬性和方法,能夠經過原型來實現爲對象擴展屬性,實現繼承。

 

 

1.41. 查看以下 JavaScript代碼:

 

function Emp(ename, salary) {
this.ename= ename;
this.salary= salary;
this.toString= function(){
return this.ename+ ":" + this.salary;
};
}
var emp1 = new Emp("mary",3500);
var emp2 = new Emp("john", 5500);
Emp.prototype.hireDate= "2015/05/01";
delete emp1.ename;
delete Emp.prototype. hireDate;
console.log(emp1.toString() + ":" + emp1.hireDate); console.log(emp2.toString() + ":" + emp2.hireDate);

 

上述代碼運行後,輸出結果是?


參考答案:


第一行輸出爲: undefined:3500:undefined
第二行輸出爲: john:5500:undefined
JavaScript中,每一個函數都有一個 prototype屬性,該屬性引用着該函數的原型對象,原型對象中包含着當前函數全部實例共享的方法和屬性。
使用函數的 prototype屬性能夠向函數的原型對象添加或刪除屬性和方法,而且這些屬性和方法是這一類對象所共享的。
可使用 delete關鍵字刪除對象的屬性,包括自有屬性和原型屬性。

 

1.42. 簡要描述 JavaScript中的自有屬性和原型屬性

 

參考答案:

自有屬性是指,經過對象的引用添加的屬性,此時,其它對象可能無此屬性。對於自有
屬性,是各個對象所特有的、彼此獨立的屬性。好比: 

emp1.job= 'Coder';
原型屬性是指從原型對象中繼承來的屬性,一旦原型對象中屬性值改變,全部繼承自該原型的對象屬性均改變。好比:

 

Emp.prototype.dept= '研發部';

 

當須要檢測對象的自有屬性時,可使用 hasOwnProperty()方法。另,還可使用 in 操做檢測對象及其原型鏈中是否具有指定屬性。
須要注意的是,在檢測對象屬性時,先檢測自有屬性,再檢測原型屬性。

 

1.43. 查看以下 JavaScript代碼:

function Hero() {
this.name= "unknown"; }
Hero.prototype.age= 20;

var hero= new Hero();
console.log('name' in hero);
console.log(hero.hasOwnProperty( 'name' ) ) ; console.log('age' in hero);
console.log(hero.hasOwnProperty( 'age' ) ) ; hero.age= 30;
console.log(hero.hasOwnProperty( 'age' ) ) ;

上述代碼運行後,輸出結果是?

參考答案:

輸出結果分別爲 true、 true、 true、 false和true。
由於在構造函數中定義了屬性 name,所以變量 hero擁有自有屬性 name。所以在
對 hero用 in操做符檢測 name屬性時,先檢測 name屬性爲自有屬性仍是原型屬性,則輸出 true;使用 hasOwnProperty()進行判斷也是輸出 true。
使用函數的 prototype向函數的原型添加屬性時,添加的屬性 age爲原型屬性。所以,下面代碼: 

console.log('age' in hero);
console.log(hero.hasOwnProperty( 'age' ) ) ;
使用 in操做符判斷時,先判斷是否爲自有屬性,若是沒有,則在原型鏈中查找屬性age,所以第一行輸出 true;可是 age並不是自有屬性,因此第二行輸出 false。
此時,再添加代碼:

hero.age= 30;
這是爲 hero定義了同名的自有屬性 age,其值爲30。所以,此時再檢測 hero對象是否有自有屬性 age時,將輸出 true。 

 

1.44. 簡要描述你對原型鏈的理解 

參考答案:

}Hero.prototype.name= "Caesar";21

 

每一個函數中都有 prototype屬性,該函數被 new操做符用於建立對象。將一個函數的prototype屬性指向某個對象,由此造成了一條鏈,稱之爲原型鏈。
可使用 isPrototypeOf()方法斷定一個 prototype對象是否存在於另外一個對象的原型鏈中。若是是,返回 true,不然返回 false。

 

1.45. 簡要描述JavaScript中的繼承

參考答案:

在 JavaScript中,繼承都是源於原型,有多種實現方式。好比:

1. 修改構造函數的原型,爲該構造函數建立的對象指定統一的父級對象。代碼以下: 

B.prototype= new A(); 

2. 只繼承於原型(儘量地將可重用的屬性和方法添加到原型中),代碼以下:

B.prototype= A.prototype; 

3. 單獨修改一個對象的原型,而不影響其餘對象的原型。代碼以下: 

var b1 = new B();
Object.setPrototypeOf(b1, new A() ) ; 

4. 修改構造函數,這將影響使用該構造函數建立的全部對象。代碼以下:

function B() {
Object.setPrototypeOf(this, new A() ) ; }


1.46. 查看以下 JavaScript代碼:

function Hero() {

this.name= "unknown";

var hero= new Hero(); console.log(hero.name) ;

delete hero.name;
console.log(hero.name) ;
delete Hero.prototype.name; console.log(hero.name) ;

上述代碼運行後,輸出結果是?

 

參考答案:

上述代碼運行後,首先輸出 unknown;而後輸出 Caesar;最後輸出 undefined。
查找對象屬性時,先查找自有屬性,所以,第一次輸出的是 hero的自有屬性 name的值,該屬性的值從構造函數中繼承而來,即爲「unknown「;刪除 hero的自有屬性後,再試圖輸出 name屬性時,則查找其原型鏈中的屬性 name的值並輸出,即爲「Caesar」;繼續刪除 hero的原型屬性後,則輸出「undefined」。

 

1.47. 查看以下 JavaScript代碼:

function A() {
this.name= "a";
this.toString= function () { return this.name}; }
function B() {
this.name= "b";
}
var b1 = new B();
console.log(b1 .toString( ) ) ;
B.prototype= new A();
var b2 = new B();
console.log(b2 .toString( ) ) ;

上述代碼運行後,輸出結果是?

參考答案:

上述代碼運行後,首先輸出[object Object];而後輸出 b。
這是由於,雖然修改了 B的原型,可是,隻影響修改以後的對象。所以,對象 b1依然使用默認的從 Object繼承而來的 toString()方法,所以輸出對象的類型和名稱。
對象 b2是在修改了 B的原型以後建立的,所以將使用A中所定義的 toString()方法,將輸出字符「b」。

  

1.48. 簡要描述Call和 apply的區別 

參考答案:

ca l l()和 a pply()都用於間接調用函數。
call方法用於調用一個對象的一個方法,並以另外一個對象替換當前對象。即,任何函數能夠做爲任何對象的方法來調用,哪怕這個函數並不是那個對象的方法。語法如: 

call( [thisObj[,arg1[, arg2[, [, .argN] ] ] ] ] )

其中,第一個參數 thisObj要調用函數的上下文,即將被用做當前對象的對象。其餘參

 

數爲可選參數,表示將被傳遞方法參數序列。
apply()和 ca ll()在做用上是相同的,但二者在參數上有區別的。它倆的第一個參數相同,
不一樣的是第二個參數。對於 apply(),第二個參數是一個參數數組,也就是將多個參數組合成爲一個數組傳入。如:

func.call(func1,var1,var2,var3)
func.apply(func1, [var1,var2,var3] )

 

1.49. 查看以下 JavaScript代碼: 

function A() {
this.name= "a";
this.introduce= function() { console.log("Myname is" + this.name) }; }
function B() {
this.name= "b";
}
var a1 = new A();
var b1 = new B();
a1 .introduce.call(b1 ) ;

上述代碼運行後,輸出結果是?

參考答案:

上述代碼運行後,輸出 My name is b。
代碼 a1.introduce.call(b1);表示對於對象 b1調用 a1的 introduce()方法。

1.50. 查看以下 JavaScript代碼:

 

var a= b= { n: 1 }; a.x= a= { n: 2 };
alert(a.x) ;
alert(b.x.n); 

上述代碼運行後,輸出結果是?

參考答案:

上述代碼運行後,先彈出顯示 undefined,再彈出顯示2。
第一行代碼運行後,變量 a和 b都指向對象{n:1},第二行代碼運行,先爲對象{n:1} 添加新屬性 x,其值爲{n:2}。此時,對象{n:1}形如{ n:1,x:{n:2}}。而後建立新對象{n:2},並將變量 a指向這個新對象,而變量 b依然指向原有對象。
所以, a.x將輸出 undefined,由於此時新對象中只有屬性 n沒有屬性x; b.x.n將表
示向原有對象的中的新屬性,所以輸出2。

2. DOM 

2.1.談談innerHTML、 nodeValue與 textContent之間的區別

參考答案:

innerHTM L屬性讀取或設置節點起始和結束標籤中的 HTM L內容;
nodeValue屬性讀取或設置指定節點的文本內容,適用於文本類型的節點;
textContent屬性讀取或設置指定節點的文本內容,對於元素節點而言,會返回所包含的全部子節點中的文本內容的組合。

2.2. DOM操做中,如何獲取元素的屬性值? 

參考答案:
對於元素節點,獲取其某屬性的值有多種方式,以下所示:一、 element.attributes[下標].value
二、 element.attributes['屬性名'].value
三、 element.getAttributeNode('屬性名').value
四、 element.getAttribute('屬性名')

 

2.3.簡要描述 DOM操做中查找元素的方式

參考答案:

一、 經過 HTML中的信息選取元素,好比:

a) getElementById()方法:根據元素的 id屬性值查詢單個節點;

b) getElementsByTagName()方法:根據元素標籤的名稱查詢節點;

c) getElementsByName()方法:根據元素 name屬性的值查詢節點。

二、 經過 CSS類選取元素

a) getElementsByClassName('className')方法:根據class名稱選取元素;

b) querySelector('selector')和 querySelectorAll('selector')方法:根據 CSS選擇器
選取元素。

三、 經過 document對象選取,如 document.all、 document.body等;

四、 經過節點遍歷選取節點,如 parentNode、 firstChild等。

 

2.4.爲 html頁面上的一個按鈕添加 onclick事件處理,有幾種方法?

參考答案:

一、 直接在 HTML代碼中添加,如:

<input type=」button」 onclick=」funcA();」/>

其中, funcA()爲一個有效函數。

二、 在 js代碼中添加,如: 

btn.onclick= funcA;

 或者

 

btn.onclick= function() {};

其中, btn表示按鈕對象。

三、 定義監聽函數,代碼如: 

btn.addEventListener( 'click' , function( ) { }) ;

 

2.5.簡述window對象除 document之外的一些經常使用子對象,並描述其做用?

參考答案:

window對象有不少子對象,除了 document之外,還有以下經常使用子對象:

 screen對象:此對象包含有關客戶端顯示屏幕的信息,經常使用於獲取屏幕的分
辨率和色彩;
 history對象:此對象包含用戶(在瀏覽器窗口中)訪問過的 URL;
 location對象:此對象包含有關當前 URL的信息,經常使用於獲取和改變當前

瀏覽的網址;
 navigator對象:此對象包含有關瀏覽器的信息,經常使用於獲取客戶端瀏覽器和
操做系統信息;
 event對象:任何事件觸發後將會產生一個 event對象,該對象記錄事件發
生時的鼠標位置、鍵盤按鍵狀態和觸發對象等信息。

2.6.查看以下代碼:

<html>

<head>
<title>bubble</title>
<script type="text/javascript" language="javascript">
function clickP(e) {
var target= e.target || e.srcElement;
alert("clickP, target=" + target.nodeName);
}
function clickDIV(e) {
var target= e.target || e.srcElement;
alert("clickDIV, target=" + target.nodeName);
}
</script>
</head>
<body>
<div onclick="clickDIV(event) ;">
<p onclick="clickP(event) ;">ClickMe</p>
</div>
</body>
</html> 

該代碼在瀏覽器中運行時,點擊段落中的文本「ClickMe「,頁面效果爲?

參考答案:

先彈出「clickP,target=P」,再彈出「clickDIV,target=P」。
單擊段落中的文本「ClickMe」,先觸發<P>元素的 onclick事件,且觸發事件的元素爲段落 P,所以,先彈出「clickP,target=P」;而後事件冒泡,觸發<div>元素的onclick 事件,再彈出「clickDIV,target=P」。

 

2.7.實現每隔一秒鐘彈出一個對話框,且此彈出過程持續5秒鐘 

參考答案:

代碼以下所示: 

var id= setInterval(function() {alert("Hello JavaScript");},1000) setTimeout( function( ) {clearInterval(id) ; } , 5*1000)

2.8.爲頁面動態添加按鈕
使用 js代碼爲頁面動態添加5個按鈕,每一個按鈕上的文本爲「button1」、「button2」…「button5」。單擊每一個按鈕時,分別彈出數字一、2…5。代碼以下: 

for (var i= 1; i< 6; i++) {
var input = document.createElement( 'input' ) ;
(空白處)
document.body. appendChild(input) ;

爲空白處填上代碼,實現所需功能

}}else{ //ieevent.returnValue= false;}}27

 

參考答案:

代碼以下所示: 

for (var i= 1; i< 6; i++) {
var input = document.createElement( 'input' ) ;
input.setAttribute("type", "button") ;
input.setAttribute("value", "button" + i);
(function (n) {
input.onclick= function () { alert(n); }; })(i);
document.body. appendChild(input) ;

 

2.9.文本框驗證(考慮瀏覽器兼容性)
頁面有文本框,須要限制該文本框中只能錄入數字,即:若是用戶按下數字之外的其餘鍵,文本框中沒法錄入;若是用戶粘貼進非數字字符,也須要進行過濾。
請設計 HTML代碼以及 JS代碼,實現上述功能。


參考答案:
首先,須要爲文本框定義 onkeypress事件,用於在錄入文本時作出判斷;併爲文本框定義 onkyeup事件,用於過濾粘貼進來的文本。 HTML代碼以下所示:

 

<h2 >輸入框中只能輸入數字</ h2 >
請輸入您的年齡:
<input onkeypress="digitOnly(event) " onkeyup="filterChar(this) "/>

 

JS代碼以下所示:

 

//當按鍵按下時,阻止非數字字符的輸入
function digitOnly(event) {
var code= event.keyCode | | event.which; //ie| |firefox if( (code<48) | | (code>57) ) {
if(event.preventDefault) { //firefox
event.preventDefault( ) ;

 

}
/ /當按鍵彈起時 , 剔除輸入中的非中文字符——解決複製粘貼進來的非數字function filterChar(input){
input.value= input.value.replace(/ [^0-9] /g, ' ' ) ;
}

2.10. 總結能夠實現頁面跳轉和刷新的方法

參考答案:

一、 使用超級連接,代碼如:

<a href=」url」></a> 

二、 表單提交,代碼如: 

<form action=」url」></form> 

三、 JS代碼,代碼如:

location. href=」url」;location.assign(‘url’) ; location.replace( ) ;location.reload( ) ;window.open(‘url’) ;history.go( ) ;

相關文章
相關標籤/搜索