溫馨提示×

溫馨提示×

您好,登錄后才能下訂單哦!

密碼登錄×
登錄注冊×
其他方式登錄
點擊 登錄注冊 即表示同意《億速云用戶服務(wù)條款》

js、jQuery面試題大全

發(fā)布時間:2020-07-11 09:20:20 來源:億速云 閱讀:215 作者:Leah 欄目:web開發(fā)

今天就跟大家聊聊有關(guān)js、jQuery面試題大全,可能很多人都不太了解,為了讓大家更加了解,小編給大家總結(jié)了以下內(nèi)容,希望大家根據(jù)這篇文章可以有所收獲。

js、jQuery面試題整理

1.數(shù)據(jù)類型

基本類型:除Object、String、Number、boolean、null、undefined。

引用類型:object。里面包含的 function、Array、Date。

2.數(shù)組方法

join():數(shù)組轉(zhuǎn)為字符串,可帶中間符號

push():數(shù)組尾部添加內(nèi)容,返回新長度

pop():數(shù)組尾部刪除一條內(nèi)容,返回長度

unshift():數(shù)組頭部添加內(nèi)容,返回新長度

shift():數(shù)組頭部刪除一條內(nèi)容,返回刪除內(nèi)容

sort():數(shù)組內(nèi)容從大到小排序

reverse():反轉(zhuǎn)數(shù)組內(nèi)容項

concat():拼接數(shù)組,若無內(nèi)容復制數(shù)組內(nèi)容

slice():截取數(shù)組,從指定下標開始

splice():刪除、插入、替換;

  • 刪除:2 個參數(shù):要刪除的第一項的位置和要刪除的項數(shù)。
  • 插入:3 個參數(shù):起始位置、 0(要刪除的項數(shù))和要插入的項。
  • 替換:3 個參數(shù):起始位置、要刪除的項數(shù)和要插入的任意數(shù)量的項。

3.字符串方法

charAt():根據(jù)下標找到對應(yīng)值

charCodeAt():通過下標值找到對應(yīng)字符Unicode編碼

indexOf():通過字符查找對應(yīng)下標(首次出現(xiàn))

lastIndexOf():通過字符找最后一次出現(xiàn)的下標值

slice():截取字符串,2個參數(shù),(起始位置,結(jié)束位置)

split():把字符串按分隔符分割成數(shù)組

substring():截取字符串,(起始位置,結(jié)束位置)

substr():截取指定位置和長度的字符串,(起始位置,長度)

toLowerCase():字符串轉(zhuǎn)為小寫

toUpperCase():字符串轉(zhuǎn)成大寫

trim():去掉字符串前后所有空格

4.阻止冒泡,阻止默認事件

阻止冒泡:

e.stopPropagation
e.cancleBubble=true(IE)
return false;

阻止默認事件:

e.preventDefault();
e.returnValue=false;(IE)
return false;

5.函數(shù)作用域

函數(shù)作用域是指在函數(shù)內(nèi)聲明的所有變量在函數(shù)體內(nèi)始終是可見的,可以在整個函數(shù)的范圍內(nèi)使用及復用.

全局變量:聲明在函數(shù)外部的變量,在代碼中任何地方都能訪問到的對象擁有全局作用域(所有沒有var直接賦值的變量都屬于全局變量)

局部變量:聲明在函數(shù)內(nèi)部的變量,局部作用域一般只在固定的代碼片段內(nèi)可訪問到,最常見的例如函數(shù)內(nèi)部,所有在一些地方也會看到有人把這種作用域稱為函數(shù)作用域。

6.閉包

外部函數(shù)訪問內(nèi)部函數(shù),能夠讀取其他函數(shù)內(nèi)部變量的函數(shù)。在本質(zhì)上,閉包是將函數(shù)內(nèi)部和函數(shù)外部連接起來的橋梁。

7.原型鏈

每個對象都有一個原型_proto_,這個原型還可以有它自己的原型,以此類推,形成一個原型鏈。

  • prototype屬性,函數(shù)的原型對象,它是函數(shù)所獨有的,它是從一個函數(shù)指向一個對象。
  • __proto__是指向構(gòu)造函數(shù)的原型對象,它是對象獨有的。

8.繼承的幾種方式

  • 構(gòu)造函數(shù)繼承:在Child里面,把Parent的this指向改為是Child的this指向,從而實現(xiàn)繼承
    缺點:只能解決屬性的繼承,使用屬性的值不重復,但是父級類別的方法不能繼承
  • 原型鏈繼承:把Child的原型改為是Parent的實例,從而實現(xiàn)繼承
    缺點:因為Child的原型對象都是New Parent,所以實例化出來的對象的屬性都是一樣的,而且Parent上面的引用類型只要有一個實例對象修改了,其他也會跟著修改.因為他們原型對象都是共用的
  • 組合方式繼承(組合前兩種):
    缺點:父類的原型對象調(diào)用了兩次,沒有必要,而且student實例的構(gòu)造函數(shù)是來自于Person
  • 還有兩種組合式繼承優(yōu)化

9.函數(shù)創(chuàng)建的方式

函數(shù)聲明:

function Fn(){}

字面量/函數(shù)表達式:

var m = function(){}

構(gòu)造函數(shù):

var sum =new Function(“n1”,”n2”,”return n1+n2”)

10.如何解決異步回調(diào)地獄

promise、generator、async/await

  • promise
let getStuPromise = new Promise((resolve,reject)=>{
	getStu(function(res){
		resolve(res.data);
	});});getStuPromise.then((data)=>{
	// 得到每個學生的課程
	getCourse();
	// 還可以繼續(xù)返回promise 對象})
  • generator
function *generatorGetStu(){
	let stus = yield getStu();
	// 等到getStu異步執(zhí)行完才會執(zhí)行g(shù)etCourse
	let course = yield getCourse();}
  • async/await
    async函數(shù)是Generator函數(shù)的語法糖。使用 關(guān)鍵字async來表示,在函數(shù)內(nèi)部使用await來表示異步

11.事件委托理解

通俗的講,事件就是onclick,onmouseover,onmouseout,等就是事件,委托呢,就是讓別人來做,這個事件本來是加在某些元素上的,然而你卻加到別人身上來做,完成這個事件.
原理: 利用冒泡的原理,把事件加到父級上,觸發(fā)執(zhí)行效果。
target 事件屬性可返回事件的目標節(jié)點(觸發(fā) 該事件的節(jié)點)

oUl.onmouseover = function(ev){
    var ev = ev || window.event;
    var target = ev.target || ev.srcElement;
    if(target.nodeeName.toLowerCase() == "li"){
        target.style.background = "red";
    }}

12.圖片的懶加載和預(yù)加載

  • 預(yù)加載:常用的是new Image();,設(shè)置其src來實現(xiàn)預(yù)載,再使用onload方法回調(diào)預(yù)載完成事件。
function loadImage(url, callback){
	var img = new Image(); //創(chuàng)建一個Image對象,實現(xiàn)圖片預(yù)下載
	img.src = url;
	if (img.complete){
		 // 如果圖片已經(jīng)存在于瀏覽器緩存,直接調(diào)用回調(diào)函數(shù)
		callback.call(img);
		return; // 直接返回,不用再處理onload事件
	}
	img.onload = function (){ 
	//圖片下載完畢時異步調(diào)用callback函數(shù)。
	callback.call(img);//將回調(diào)函數(shù)的this替換為Image對象 ,如果你直接用img.width的時候,圖片還沒有完全下載下來
	};}

懶加載:主要目的是作為服務(wù)器前端的優(yōu)化,緩解服務(wù)器前端壓力,一次性請求次數(shù)減少或延遲請求。
實現(xiàn)方式:

  • 1.第一種是純粹的延遲加載,使用setTimeOut、setInterval進行加載延遲.

  • 2.第二種是條件加載,符合某些條件,或觸發(fā)了某些事件才開始異步下載。

  • 3.第三種是可視區(qū)加載,即僅加載用戶可以看到的區(qū)域,這個主要由監(jiān)控滾動條來實現(xiàn),一般會在距用戶看到某圖片前一定距離遍開始加載,這樣能保證用戶拉下時正好能看到圖片。

13.bind,apply,call的區(qū)別

都可以改變函數(shù)內(nèi)部this指向
區(qū)別:

  • callcall傳遞參數(shù)aru1, aru2… 形式
  • apply傳遞參數(shù)必須數(shù)組形式[arg]
  • bind不會調(diào)用函數(shù),可以改變函數(shù)內(nèi)部this指向
  • 主要應(yīng)用場景:
    1、call經(jīng)常做繼承。
    2、apply經(jīng)常跟數(shù)組有關(guān)系。比如借助于數(shù)學對象實現(xiàn)數(shù)組最大值最小值。
    3、bind不會調(diào)用函數(shù),可以改變函數(shù)內(nèi)部this指向。

14.js的節(jié)流和防抖

  • 防抖:當持續(xù)觸發(fā)事件時,一定時間段內(nèi)沒有再觸發(fā)事件,事件處理函數(shù)才會執(zhí)行一次,如果設(shè)定時間到來之前,又觸發(fā)了事件,就重新開始延時。也就是說當一個用戶一直觸發(fā)這個函數(shù),且每次觸發(fā)函數(shù)的間隔小于既定時間,那么防抖的情況下只會執(zhí)行一次。
  • 節(jié)流:當持續(xù)觸發(fā)事件時,保證在一定時間內(nèi)只調(diào)用一次事件處理函數(shù),意思就是說,假設(shè)一個用戶一直觸發(fā)這個函數(shù),且每次觸發(fā)小于既定值,函數(shù)節(jié)流會每隔這個時間調(diào)用一次。時間戳和定時器
  • 區(qū)別:防抖是將多次執(zhí)行變?yōu)樽詈笠淮螆?zhí)行,節(jié)流是將多次執(zhí)行變?yōu)槊扛粢欢螘r間執(zhí)行。

15.前端模塊化和組件化

  • 模塊化:可復用,側(cè)重的功能的封裝,主要是針對Javascript代碼,隔離、組織復制的javascript代碼,將它封裝成一個個具有特定功能的的模塊。
  • 組件化:可復用,更多關(guān)注的UI部分,頁面的每個部件,比如頭部,彈出框甚至確認按鈕都可以成為一個組件,每個組件有獨立的HTML、css、js代碼。

16.js單線程怎么執(zhí)行異步操作

Js作為瀏覽器腳本語言,它的主要用途是與用戶互動,以及操作DOM。這決定了它只能是單線程,否則會帶來很復雜的同步問題。

js怎么異步:瀏覽器只分配給js一個主線程,用來執(zhí)行任務(wù)(函數(shù)),但一次只能執(zhí)行一個任務(wù),這些任務(wù)形成一個任務(wù)隊列排隊等候執(zhí)行,但前端的某些任務(wù)是非常耗時的,比如網(wǎng)絡(luò)請求,定時器和事件監(jiān)聽,如果讓他們和別的任務(wù)一樣,執(zhí)行效率會非常的低,甚至導致頁面的假死。

所以,瀏覽器為這些耗時任務(wù)開辟了另外的線程,主要包括http請求線程,瀏覽器定時觸發(fā)器,瀏覽器事件觸發(fā)線程,這些任務(wù)是異步的。這些異步任務(wù)完成后通過回調(diào)函數(shù)讓主線程知道。

17.手寫promise函數(shù)

三種狀態(tài):pending(過渡)fulfilled(完成)rejected(失敗)

function Promise(exector){
	let _this = this;
	//status表示一種狀態(tài)
	let status = “pending”;
	let value = undefined;
	let reason = undefined;
	//成功
	function resolve(value){
		if(status == “pending”){
			_this.value = value;
			_this.status = “resolve”;
		}
	}
	//執(zhí)行失敗
	function reject(value){
		if(status == “pending”){
			_this.value = value;
			_this.status = “reject”		}
	}
	//異步操作
	try{
		exector(resolve,reject)
	}catch(e){
		reject(e)
	}
	//測試then
	Promise.prototype.then = function(reject,resolve){
		let _this = this;
		if(this.status == “resolve”){
			reject(_this.value)
		}
		if(this.status == “reject”){
			resolve(_this.reason)
		}
	}}//new Promise測試let promise = new Promise((reject,resolve)=>{
	resolve(“return resolve”);});promise.then(data=>{
	console.log(`success${data}`);},err=>{
	console.log(`err${data}`);})

18.數(shù)組去重

1.遍歷并兩個對比,splice刪除重復的第二個

function unique(arr){            
        for(var i=0; i<arr.length; i++){
            for(var j=i+1; j<arr.length; j++){
                if(arr[i]==arr[j]){         //第一個等同于第二個,splice方法刪除第二個
                    arr.splice(j,1);
                    j--;
                }
            }
        }return arr;}

2.indexOf

function unique(arr) {
    var array = [];
    for (var i = 0; i < arr.length; i++) {
        if (array .indexOf(arr[i]) === -1) {
            array .push(arr[i])
        }
    }
    return array;}

3.sort

function unique(arr) {
    arr = arr.sort()
    var arrry= [arr[0]];
    for (var i = 1; i < arr.length; i++) {
        if (arr[i] !== arr[i-1]) {
            arrry.push(arr[i]);
        }
    }
    return arrry;}

4.includes (ES6)

function unique(arr) {
    var array =[];
    for(var i = 0; i < arr.length; i++) {
            if( !array.includes( arr[i]) ) {//includes 檢測數(shù)組是否有某個值
                    array.push(arr[i]);
              }
    }
    return array}

19.數(shù)組排序

  • 冒泡排序:
var arr=[1,5,7,9,16,2,4];//冒泡排序,每一趟找出最大的,總共比較次數(shù)為arr.length-1次,每次的比較次數(shù)為arr.length-1次,依次遞減var temp;for(var i=0;i<arr.length-1;i++){
    for(var j=0;j<arr.length-1;j++){
        if(arr[j]>arr[j+1]){
            temp=arr[j];
            arr[j]=arr[j+1];
            arr[j+1]=temp;
        }
    }}
  • 選擇排序:(相鄰對比)
var arr=[1,23,5,8,11,78,45];var temp;for(var i=0;i<arr.length-1;i++){
    for(var j=i+1;j<arr.length;j++){
        if(arr[i]>arr[j]){
            temp=arr[i];
            arr[i]=arr[j];
            arr[j]=temp;
        }
    }}
  • sort():
var arr=[1,5,7,9,16,2,4];arr.sort(function(a,b){
    return b-a;  //降序排列,return a-b; —>升序排列})  
    //括號里不寫回調(diào)函數(shù),則默認按照字母逐位升序排列,結(jié)果為[1,16,2,4,5,7,9]

20.去除首尾空格

JavaScript 本身并不提供 trim() 方法,不過可以用正則表達式(其中一種)

if(typeof(String.prototype.trim) === "undefined"){
    String.prototype.trim = function() 
    {
        return String(this).replace(/^\s+|\s+$/g, '');
    };}
 if(" dog  ".trim() === "dog") {
    document.write("去除首尾空格成功");    }

21.解決跨域方案

  • jsonp:包含回調(diào)函數(shù)和數(shù)據(jù)
//1、使用JS動態(tài)生成script標簽,進行跨域操作function handleResponse(response){
    console.log('The responsed data is: '+response.data);
    //處理獲得的Json數(shù)據(jù)}var script = document.createElement('script');script.src = 'http://www.example.com/data/?callback=handleResponse';document.body.insertBefore(script, document.body.firstChild);//2、手動生成script標簽function handleResponse(response){
    console.log('The responsed data is: '+response.data);
    //處理獲得的Json數(shù)據(jù)}<script src="http://www.example.com/data/?callback=handleResponse"></script>//3、使用jQuery進行jsonp操作//jquery會自動生成一個全局函數(shù)來替換callback=?中的問號,之后獲取到數(shù)據(jù)后又會自動銷毀//$.getJSON方法會自動判斷是否跨域,不跨域的話,就調(diào)用普通的ajax方法;跨域的話,則會以異步加載js文件的形式來調(diào)用jsonp的回調(diào)函數(shù)。<script>
    $.getJson('http://www.example.com/data/?callback=?',function(jsondata){
    //處理獲得的Json數(shù)據(jù)});</script>
  • window.name + iframe
  • location.hash+iframe
  • window.postMessage(HTML5中的XMLHttpRequest Level 2中的API)
  • 通過document.domain+iframe來跨子域(只有在主域相同的時候才能使用該方法)
  • 使用跨域資源共享(CORS)來跨域
  • 使用Web sockets來跨域
  • 使用flash URLLoader來跨域

22.手寫ajax

ajax的技術(shù)核心是 XMLHttpRequest 對象;
ajax 請求過程:創(chuàng)建 XMLHttpRequest 對象、連接服務(wù)器、發(fā)送請求、接收響應(yīng)數(shù)據(jù);

(理解)<script type="text/javascript">//通過createXHR()函數(shù)創(chuàng)建一個XHR對象:function createXHR() {
    if (window.XMLHttpRequest) {    //IE7+、Firefox、Opera、Chrome 和Safari
         return new XMLHttpRequest();
    } else if (window.ActiveXObject) {   //IE6 及以下
        var versions = ['MSXML2.XMLHttp','Microsoft.XMLHTTP'];
        for (var i = 0,len = versions.length; i<len; i++) {
            try {
                return new ActiveXObject(version[i]);
                break;
            } catch (e) {
                //跳過
            }  
        }
    } else {
        throw new Error('瀏覽器不支持XHR對象!');
    }}//封裝ajax,參數(shù)為一個對象function ajax(obj) {
    var xhr = createXHR();  //創(chuàng)建XHR對象
    //通過使用JS隨機字符串解決IE瀏覽器第二次默認獲取緩存的問題
    obj.url = obj.url + '?rand=' + Math.random();
    obj.data = params(obj.data);  //通過params()將名值對轉(zhuǎn)換成字符串
    //若是GET請求,則將數(shù)據(jù)加到url后面
    if (obj.method === 'get') {
        obj.url += obj.url.indexOf('?') == -1 ? '?' + obj.data : '&' + obj.data;
    }
    if (obj.async === true) {   //true表示異步,false表示同步
        //使用異步調(diào)用的時候,需要觸發(fā)readystatechange 事件
        xhr.onreadystatechange = function () {
            if (xhr.readyState == 4) {   //判斷對象的狀態(tài)是否交互完成
                callback();      //回調(diào)
            }
        };
    }
    //在使用XHR對象時,必須先調(diào)用open()方法,
    //它接受三個參數(shù):請求類型(get、post)、請求的URL和表示是否異步。
    xhr.open(obj.method, obj.url, obj.async);
    if (obj.method === 'post') {
        //post方式需要自己設(shè)置http的請求頭,來模仿表單提交。
        //放在open方法之后,send方法之前。
        xhr.setRequestHeader('Content-Type', 'application/x-www-form-urlencoded');
        xhr.send(obj.data);     //post方式將數(shù)據(jù)放在send()方法里
    } else {
        xhr.send(null);     //get方式則填null
    }
    if (obj.async === false) {  //同步
        callback();
    }
    function callback() {
        if (xhr.status == 200) {  //判斷http的交互是否成功,200表示成功
            obj.success(xhr.responseText);          //回調(diào)傳遞參數(shù)
        } else {
            alert('獲取數(shù)據(jù)錯誤!錯誤代號:' + xhr.status + ',錯誤信息:' + xhr.statusText);
        }  
    }}//名值對轉(zhuǎn)換為字符串function params(data) {
    var arr = [];
    for (var i in data) {
        //特殊字符傳參產(chǎn)生的問題可以使用encodeURIComponent()進行編碼處理
        arr.push(encodeURIComponent(i) + '=' + encodeURIComponent(data[i]));
    }
    return arr.join('&');}</script>

實例:

ajax({
    method : 'het/post',
    url : '...',
    data : {
    },
    success : function (res) {
    },
    error : function(err){
    },
    async : true});

23.ES6

簡述,具體請參考https://blog.csdn.net/Juliet_xmj/article/details/103940173

  • 字符串擴展
  • 解構(gòu)表達式
  • 函數(shù)優(yōu)化
  • 函數(shù)參數(shù)默認值
  • 箭頭函數(shù)
  • 對象的函數(shù)屬性簡寫
  • 箭頭函數(shù)結(jié)合解構(gòu)表達式
  • map:接收一個函數(shù),將原數(shù)組中的所有元素用這個函數(shù)處理后放入新數(shù)組返回。
  • reduce:接收一個函數(shù)(必須)和一個初始值(可選),該函數(shù)接收兩個參數(shù):(上一次reduce處理的結(jié)果,數(shù)組中要處理的下一個元素)
  • promise
const promise = new Promise(function(resolve, reject) {
  // ... 執(zhí)行異步操作
  if (/* 異步操作成功 */){
    resolve(value);// 調(diào)用resolve,代表Promise將返回成功的結(jié)果
  } else {
    reject(error);// 調(diào)用reject,代表Promise會返回失敗結(jié)果  }});promise.then(function(value){
    // 異步執(zhí)行成功后的回調(diào)}).catch(function(error){
    // 異步執(zhí)行失敗后的回調(diào)
	})
  • set:本質(zhì)與數(shù)組類似。不同在于Set中只能保存不同元素,如果元素相同會被忽略。
  • map:本質(zhì)是與Object類似的結(jié)構(gòu)。不同在于,Object強制規(guī)定key只能是字符串。而 Map結(jié)構(gòu)的key可以是任意對象。
  • 模塊化:把代碼進行拆分,方便重復利用
  • 對象擴展
  • 數(shù)組擴展

24.BOM,DOM

  • BOM:指的是瀏覽器對象模型,它使JavaScript有能力與瀏覽器進行“對話”
  • DOM:是指文檔對象模型,通過它,可以范文HTLM文檔的所有元素
  • window對象:是客戶端JavaScript最高層對象之一,由于window對象是其他大部分對象的共同祖先,在調(diào)用window對象的方法和屬性時,可以省略window對象的應(yīng)用。

25.jQuery選擇器

  • 元素選擇器:$("p.intro")選取所有 class=“intro” 的<p>元素。
  • 屬性選擇器:$("[href='#']")選取所有帶有 href 值等于 “#” 的元素。
  • css選擇器:$("p").css("background-color","red");

26.隱式迭代

遍歷內(nèi)部DOM元素(偽數(shù)組形式存儲)的過程,給匹配到的所有元素進行循環(huán)遍歷,執(zhí)行相應(yīng)的方法,而不需要我們自己進行循環(huán)遍歷

<ul>
	<li>web</li>
    <li>前端</li></ul>//js$("li").html("WEB前端夢之藍");
    //將所有的li標簽html內(nèi)容全部換成“WEB前端夢之藍”,這個就屬于隱式迭代

看完上述內(nèi)容,你們對js、jQuery面試題大全有進一步的了解嗎?如果還想了解更多知識或者相關(guān)內(nèi)容,請關(guān)注億速云行業(yè)資訊頻道,感謝大家的支持。

向AI問一下細節(jié)

免責聲明:本站發(fā)布的內(nèi)容(圖片、視頻和文字)以原創(chuàng)、轉(zhuǎn)載和分享為主,文章觀點不代表本網(wǎng)站立場,如果涉及侵權(quán)請聯(lián)系站長郵箱:is@yisu.com進行舉報,并提供相關(guān)證據(jù),一經(jīng)查實,將立刻刪除涉嫌侵權(quán)內(nèi)容。

AI