JS基礎整理面試題


1、DOM和BOM的區別

DOM:document object model;文檔對象模型,提供操作頁面元素的方法和屬性
BOM:browser object model;瀏覽器對象模型,提供一些屬性和方法可以操作瀏覽器

2、JS有幾種引入方式

1、行內式 直接在標簽中寫js代碼 
2、內嵌式 可以有多個script標簽,從上到下 
3、外聯式 直接導入script標簽,相對路徑 
4、導入式 import

3、innerHTML 和innerText : 區別

innerHTML 可以識別標簽; 
innerText : 不能識別標簽;會把所有的東西當作文本;

4、基本數據類型和引用數據類型的區別?

基本數據類型存儲到棧內存中,引用數據類型存儲到堆內存中 
基本數據類型操作值的,引用數據類型操作的是空間地址;

5、基本數據類型有哪些?

number(數字) string(字符串) boolean(布爾) null undefined;

6、引用數據類型都有哪些?

對象數據類型:

  • 普通的對象、數組 、正則 、Date的實例、Math… 
    函數數據類型
  • 普通函數、類;

7、其他數據類型轉布爾類型是false有且只有哪些?

0 、 “” 、 NaN 、null 、undefined

8、邏輯運算符:與、或、非

|| : 只要其中有一個為true,整體結果是true; 
&& : 只要有一個是false,整體結果是false; 
!:取反 (比較:轉布爾,在取反)

9、null和undefined的區別?

typeof null –> “object”; 空對象指針; 
null 表示現在沒有,但是以后可能會有; 
undefined :現在沒有,以后也不能有;

undefined是訪問一個未初始化的變量時返回的值,而null是訪問一個尚未存在的對象時所返回的值。因此,可以把undefined看作是空的變量,而null看作是空的對象

10、常見的null的情況

1.通過ID獲取元素,如果ID名字不存在,那么返回null; 
2.通過正則進行捕獲時,如果沒有捕獲到內容,那么結果是null; 
3.在清空對象,銷毀堆內存時,給對象賦值時,賦值為null;

11、常見的undefined的情況

1.當獲取對象屬性名對應的屬性值時如果屬性名不存在,那么返回值是undefined; 
2.函數的形參如果沒有實參賦 
值,在函數中默認存儲undefined 
3.如果函數沒有return,那么函數的返回值是undefined; 
4.如果變量只聲明,沒有賦值,那么默認存儲也是undefined;

12、對象的定義

1.首先會開辟一個新的空間地址;空間地址是16進制;0-9a-f; 
2.把鍵值對存儲到當前這個堆內存下; 
3.把這個空間地址給了對象名; 
(函數定義同上,把函數體中的代碼當做字符串存儲到堆內存)

13、JS四種檢測

1、typeOf:只能檢測基本數據類型 
2、instanceOf:檢測當前實例是否屬於某個類的方法 
3、檢測當前實例的構造函數 
4、Object.prototype.toString.call([]); 最准確的方式;

14、continue和break的區別

continue; 結束本輪循環; 
break: 結束整個循環;

15、for…in..和for…of..的區別?

for in 遍歷循環對象

  • 同時for in也可以遍歷數組,但是會出現以下問題 
    1、index索引為字符串型數字,不能直接進行幾何運算 
    2、遍歷順序有可能不是按照實際數組的內部順序 
    3、使用for in會遍歷數組所有的可枚舉屬性,包括原型。

for in遍歷的是數組的索引(即鍵名),而for of遍歷的是數組元素值。

for of 遍歷循環數組

  • for of遍歷的只是數組內的元素,而不包括數組的原型屬性method和索引name

16、什么是函數的封裝?

把實現相同功能的代碼放到一個函數體中,當想實現這個功能時,直接執行這個函數即可;減少了的冗余;高內聚,低耦合

17、堆棧內存

當瀏覽器加載頁面時,會形成兩個虛擬的內存;一個棧內存,堆內存;

棧內存:

  • 1) 提供代碼的運行環境;
  • 2) 存儲基本數據類型;

堆內存: 存儲引用數據類型

18、函數的執行過程

  • 1.首先會形成一個私有的作用域
  • 2.形參賦值
  • 3.變量提升
  • 4.代碼從上到下運行;
  • 5.作用域的銷毀; 
    在函數執行時,函數體中可以找到函數外面的變量;但是函數外面不能訪問里面的變量;

19、閉包

當函數執行時,首先會形成一個私有的作用域,這個私有作用域保護了里面的私有變量不受外界的干擾;這種機制--> "閉包";

20、數據類型之間的比較

NaN 和自己都不相等; 
數據類型比較的規律 
對象==對象: 比較的是空間地址 
對象==字符串 對象默認調用toString方法,先轉字符串,然后再進行比較 
對象==布爾: 對象先轉字符串,再轉數字;布爾直接轉數字; 
對象== 數字 : 對象先調用toString轉換成字符串,然后再轉number; 
布爾== 數字 : 布爾轉數字; 
字符串== 數字: 字符串轉數字; 
布爾== 字符串 : 布爾轉數字,字符串也轉數字,然后進行比較; 
null == undefined : true; 
null 和 undefined 和其他數據類型比較都是false;

21、arguments 類數組對象

任意數求和

function sum() {
let total =null;
for(let i=0;i<arguments.length;i++){
let cur =arguments[i];
if(!isNaN(cur)){
total += Number(cur);
}
}
console.log(total);
}
sum( 1,2,3,4,5)

22、原生JS選項卡片段

// 1.獲取所有的li,和tab這個div盒子下的div;
// 2. 給所有li綁定函數;【循環綁定】;
// 3. 綁定函數中
// 1) : 點擊當前這個li時;清空所有li身上的class;
// 2) : 讓點擊的這個li新增class["select"];
// 3) : 所有div身上select清掉
// 4) : 只要讓和點擊這個li的索引相同的div新增"select";
var tab = document.getElementById("tab");
var oLis = tab.getElementsByTagName("li");
var divs = tab.getElementsByTagName("div");
for(var i=0;i<oLis.length;i++){
// 新增一個屬性;自定義屬性
// 給每一個li新增一個屬性叫index,屬性值當前li的索引;
oLis[i].index = i;
oLis[i].onclick = function () {
for(var j=0;j<oLis.length;j++){
// 通過JS刪除所有li的class;
oLis[j].className = "";// 清空所有li的select;
divs[j].className = "";// 清空所有div的select;
}
// 給點擊的li和對應div新增class;
// 點擊時,循環早已經完成,已經變成最后一個值;3
// 函數中的this,指向當前被綁定的元素;this關鍵字;
this.className = "select";
divs[ this.index].className = "select";
}
}

23、Number的方法

isNaN : 強制轉換成number,在判斷 
Number :將其他數據類型的值強制轉換成number類型; 
parseInt :經常用於字符串提取數字的方法; 
parseFloat:和parseInt 用法一樣;區別是多識別一位小數點 
toFixed : 保留小數點位數的方法;返回值是一個字符串;

24、字符串的方法(13個)

toUpperCase : 把小寫字母轉成大寫 
toLowerCase 把大寫轉小寫 
charAt : 通過索引獲取字符 
charCodeAt : 通過索引獲取對應字符的Unicode編碼; 
substr : 截取 substr(m,n) 從索引m開始,截取n個字符; 
substring: substring(m,n) :從索引m開始,截取到索引n,不包含n; (不支持負數) 
slice(m,n): substring; 從索引m開始,截取到索引n,不包含n (支持負數) 
indexOf : 檢測字符在字符串中第一次出現的索引位置; 
lastIndexOf : 檢測字符在字符串中最后一次出現的索引位置; 
split: 把字符串按照特定的字符分隔數組中的每一項; 
replace:替換;原有字符串不變;用新字符替換舊的字符 
concat : 拼接 
trim : 去空格 : 去除字符串中左右的空格;

25、字符串的運算

- * /: 會先把字符串轉換成數字,然后再進行計算

  1. 任何數字和NaN 計算,結果都是NaN;
  2. 任何數字和undefined運算,得到也是NaN;

+: 字符串拼接;

  • [] : 空數組在進行拼接時,會默認調用toString轉換成空字符串;然后拼接;

26、數組的方法(15個)

push :向數組末尾新增一項;可以傳多個; 
pop : 刪除數組的最后一項;不需要傳參數; 
unshift :向數組開頭新增一項;需要傳參數; 
shift :刪除數組的第一項;不需要傳參

sort:數組的排序 
reverse:將數組顛倒 
原有數組發生改變;

concat:數組的拼接 
join:數組的連接 
indexOf:第一次出現的索引位置 
lastIndexOf:最后一次出現的索引位置 
map:數組的遍歷和映射 
forEach:遍歷數組 
toString:轉字符串 
原有數組不發生改變;

slice :數組的截取 
slice(m,n): 從數組索引m開始,截取到索引n,但是不包含n;[前包后不包] 
slice(m) : 從索引m開始,截取到末尾; 
slice():數組的克隆 slice(0); 
原有數組不發生改變;

splice:刪除數組中的某幾項 
splice(m,n): 從索引開始,刪除n個 
splice(m) : 從索引m開始刪除到末尾; 
splice(0): 
splice(m,x,n);替換從索引m開始,刪除x個,用n替換; 
原有數組發生改變

27、獲取元素的方法

document.getElementById:通過ID名來獲取元素 
document.getElementsByTagName: 通過標簽名來獲取元素 
document.getElementsByClassName(); 類數組集合; 
document.getElementsByName;通過name屬性來獲取元素; 
document.documentElement 獲取當前的html 
body :獲取頁面的body元素; 
document.querySelector();如果是id名加#,如果是class名加. 
document.querySelectorAll();獲取所有的元素

28、DOM四種類型的節點

TYPE nodeType nodeName nodeValue
元素節點 1 大寫的標簽名 null
文本節點 3 text 文本內容
注釋節點 8 comment 注釋內容
document 9 document null

空格和換行都是文本節點;

29、DOM節點的屬性

childNodes : 獲取當前元素所有的子節點; 
children : 獲取當前元素的子元素節點; 
firstChild : 獲取第一子節點; 
lastChild :獲取最后一個子節點 
previousSibling : 獲取上一個哥哥節點 
nextSibling : 獲取下一個弟弟節點 
parentNode: 獲取當前元素的父親節點;

30、封裝previousSibling

// 獲取上一個哥哥的元素節點;
function getBrother(curEle) {
var pre = curEle.previousSibling;
while(pre){
if(pre.nodeType ===1){//不滿足,說明不是一個元素;
return pre;
}
pre = pre.previousSibling;
}
return pre;
}
getBrother(sec);

31、動態操作DOM的方法

document.createElement;創建元素 
appendChild : 向元素的末尾添加子節點; 
removeChild : 刪除子節點; 
replaceChild : 替換節點; 
insertBefore :把元素節點插入某個節點的前面 
cloneNode : 復制節點; 
set/get/remove Attribute : 設置自定義行內屬性;

32、Math的方法

Math.abs(): 取絕對值; 
Math.floor() : 向下取整 
Math.ceil() : 向上取整 
Math.max() : 取最大值 
Math.min() : 取一組數的最小值 
Math.random() 取隨機數,取值范圍[0,1) 
Math.round(): 四舍五入取整 
取m-n之間的隨機整數:Math.round(Math.random()*(n-m)+m) 
Math.pow() : 取冪次方 
Math.sqrt() : 開平方;

33、Date的實例

console. log(typeof new Date());
// "object"
console. log(new Date());
// 獲取本機的系統時間;
var time = new Date();
console. log(time.getFullYear());
// 獲取時間年;
console. log(time.getMonth())
// 獲取時間月 取值范圍【0-11】
console. log(time.getDate());
// 獲取時間日【1-31】
console. log(time.getDay());
// 獲取星期幾;【0-6】 星期日是0;
console. log(time.getHours())
// 獲取小時數 【0-23】
console. log(time.getMinutes());
// 獲取分鍾數 【0-59】
console. log(time.getSeconds());
// 獲取時間秒【0-59】 console.log(time.getMilliseconds());
// 獲取毫秒數【0-999】
console. log(time.getTime());
// 當前時間距離1970-1-1日早上八點的毫秒數;
console. log(Date.now());
// 時間戳:

34、數組的去重

var ary = [ 12,8,88,12,99,88,66,77,66];
var a = [ 12,8,88,99,66,77];
var newAry = [];
forEach map ;

1、indexOf: 判斷當前項在數組中是否存在,不存在返回-1;

for(var i=0;i<ary.length;i++){
var cur = ary[i];
// 判斷當前項在新數組中是否存在,不存在返回-1;
if(newAry.indexOf(cur)===-1){
newAry.push(cur);
}
}
console.log( newAry);//[12, 8, 88, 99, 66, 77]

2、對象的屬性名不能重復;

var obj = {1:10,1:16};
console.log(obj);
var ary = [12,8,88,12,99,88,66,77,12];
var obj = {};// {12:12,8:8,88:88}
for(var i=0;i<ary.length;i++){
var cur = ary[i];// 12
if(obj[cur]===cur){
ary.splice(i, 1); 缺點: 數組塌陷;刪除這一項后面的所有項的索引都要進行重新計算;
ary[i] = ary[ary.length -1];// 把數組最后一項賦值給當前項
ary.length--; // 刪除最后一項;
i--;
continue;// 結束本輪循環
}
obj[cur] = cur; // 新增鍵值對;當屬性名不存在時,執行此處代碼
}
console.log(obj);//
console.log(ary);

3、轉換成數組

var ary = [12,8,88,12,99,88,66,77,12];
var obj = {};// {12:12,8:8,88:88}
for(var i=0;i<ary.length;i++){
var cur = ary[i];// 12
obj[cur] = cur; // 新增鍵值對;當屬性名不存在時,執行此處代碼
}
//轉換成數組
var newAry = [];
for(var key in obj){
newAry.push(obj[key])
}
console.log( newAry);

35、函數的遞歸

遞歸: 針對的是函數; 是JS中一種重要的思想; 
函數: 分為定義和執行 
函數遞歸: 在函數體內部,調用函數自己本身,讓其執行;這就是遞歸;

function sum(num) {
if(num === 0){
return num;
}
if(num%3===0){
return num + sum(num-1);
}
if(num%3!==0){
return sum(num-1);
}
// return sum(99)
// return 99 + sum(98)
// return 99 + sum(97)
// return 99 + sum(96)
// return 99 + 96 + sum(95)....
// return 99 + 96 +... + 3 + sum(2)
// return 99 + 96 +... + 3 + sum(1)
// return 99 + 96 +... + 3 + 0
}
console.log(sum(100));
console.log(sum(200));

36、求1-100之間是3倍數的和

% : 取模;取余數

var total = 0;
for(var i=0;i<100;i++){
if(i%3===0){
total += i;
}
}

37、數組的插入排序

var ary = [12,88,67,98,56,35,45,26,1];
//5 6 7 8 10
//得到的新數組是排好序
//插入排序原理:去原有數組中去取每一項,然后和新數組中的成員進行比較,從新數組后面開始,一一向前比較,比新數組項小,繼續和前一項比較,直到當前項比數組中一項值大時,把它放到這一項的后面;
var newAry = [];
newAry.push(ary[0]);
for(var i=1;i<ary.length;i++){
var cur = ary[i];
for(var j=newAry.length-1;j>=0;j--){
if(cur<newAry[j]){// 如果數組中拿到的這一項比新數組中j的這一項小;那么繼續j--;和上一個成員進行比較;
if(j===0){
newAry.unshift(cur);
break;// 只會中止當前的小循環
}
} else{
// cur<newAry[j]的情況,把當前項放到新數組這一項的后面;
newAry.splice(j+1,0,cur);
break;
}
}
}
// 從前向后
console.log( newAry);
var ary = [12,88,67,98,56,35,45,26,1];
var mAry = [12,67,88];
mAry.push(ary[ 0]);
for(var i=1;i<ary.length;i++){
var cur = ary[i];
for(var j = mAry.length-1;j>=0;j--){
if(cur<mAry[j]){
if(j===0){
mAry.unshift(cur);
break;
}
} else{
mAry.splice(j+ 1,0,cur);
break;
}
}
}

38、數組的冒泡排序

var ary = [12,32,56,67,88,99,101];
// 1. sort
/*ary.sort(function (a,b) {
return a-b;// 從小到大
});*/
// 實現從小到大
// 讓相鄰兩項進行比較,如果前面一項比后面一項大,那么讓這兩項互換位置;如果前比后面一項小,那么不換位置;每循環一整輪,把數組的最大值放到數組的最后面;有多少項,就執行多少次這樣的循環;
for(var j = 0;j<ary.length;j++){
// 當外面的循環循環一次;
var flag = true;// 標識的作用
for(var i=0;i<ary.length-1-j;i++){
// 里面整個循環完一次,實現將最大值放到最后;
if(ary[i]>ary[i+1]){//前面一項比后面大
// 借助第三方變量
//如果能進來,說明數組沒有排好順序;如果進不來,說明數組已經是排好的
var temp = ary[i];
ary[i] = ary[i+ 1];
ary[i+ 1] = temp;
flag = false;
}
}
if(flag){
break;
}
}
console.log(ary);

39、數組的快速排序

快速排序快速排序的原理: 首先取原有數組中的中間項;接下來循環原有的數組每一項,和中間項進行比較,如果比中間項的小的放在左邊的數組中,比中間項大的放在右邊的數組中;然后再對左邊和右邊數組進行剛才的操作;最后把所有的小數組和中間項串在一起就是排好的數組;

var ary = [12,8,89,78,76,56,25,35];
function quickSort(ary) {
console.log(ary);
// 當數組的長度小於等於1;直接return當前的數組;
if(ary.length<=1){
return ary;
}
//獲取
var middleIndex = Math.floor(ary.length/2);
//刪除數組中中間項;並且獲取中間項的值
var middleVal = ary.splice(middleIndex,1)[0];
console.log(middleVal);
var left = [];
var right = [];
for(var i=0;i<ary.length;i++){
var cur = ary[i];
//比中間項的小的放中間項的左邊的數組,比中間項大的放中間項的右邊的數組
if(cur<middleVal){
left.push(cur);
} else{
right.push(cur);
}
}
//對中間左右兩邊的數組進行重新這樣的操作
return quickSort(left).concat(middleVal,quickSort(right))
}
var newAry = quickSort(ary);
console.log(newAry);

40、隨機驗證碼

var code = document.getElementById("code");
function getCode() {
// 准備一個62個字符串;
// 產生隨機數;隨機數可以作為字符的索引;
// 隨機索引范圍【0-61】
var str = "0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ";
// 隨機數;
var i =0;
var newStr = "";
while(i<4){
var num = Math.round(Math.random()*(61-0)+0);
newStr+=str[num];
i++;
}
code.innerHTML = newStr;
}
getCode();
// 把函數的空間地址賦值給code的onclick屬性;
code.onclick = getCode;

41、設置定時器

1) setTimeout() 
2) setInterval()

42、清除定時器

1) clearTimeout() 
2) setInterval()


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM