前端开发面试题总结之——JAVASCRIPT.One
相關知識點
數據類型、運算、對象、function、繼承、閉包、作用域、原型鏈、事件、RegExp、JSON、Ajax、DOM、BOM、內存泄漏、跨域、異步加載、模板引擎、前端MVC、前端MVVM、路由、模塊化、Http、Canvas、jQuery、ECMAScript 2015(ES6)、Node.js、AngularJS、Vue、React…
題目&答案
Undefined、Null、Boolean、Number、String
介紹一下 JS 有哪些內置對象。Object 是 JavaScript 中所有對象的父對象
數據封裝類對象:Object、Array、Boolean、Number、String
其他對象:Function、Argument、Math、Date、RegExp、Error
(1)不要在同一行聲明多個變量
(2)如果你不知道數組的長度,使用 push
(3)請使用 =/! 來比較 true/false 或者數值
(4)對字符串使用單引號 ‘’(因為大多時候我們的字符串。特別html會出現")
(5)使用對象字面量替代 new Array 這種形式
(6)絕對不要在一個非函數塊里聲明一個函數,把那個函數賦給一個變量。瀏覽器允許你這么做,但是它們解析不同
(7)不要使用全局函數
(8)總是使用 var 來聲明變量,如果不這么做將導致產生全局變量,我們要避免污染全局命名空間
(9)Switch 語句必須帶有 default 分支
(10)使用 /**…*/ 進行多行注釋,包括描述,指定類型以及參數值和返回值
(11)函數不應該有時候有返回值,有時候沒有返回值
(12)語句結束一定要加分號
(13)for 循環必須使用大括號
(14)if 語句必須使用大括號
(15)for-in 循環中的變量應該使用 var 關鍵字明確限定作用域,從而避免作用域污染
(16)避免單個字符名,讓你的變量名有描述意義
(17)當命名對象、函數和實例時使用駝峰命名規則
(18)給對象原型分配方法,而不是用一個新的對象覆蓋原型,覆蓋原型會使繼承出現問題
(19)當給事件附加數據時,傳入一個哈希而不是原始值,這可以讓后面的貢獻者加入更多數據到事件數據里,而不用找出并更新那個事件的事件處理器
call和apply的功能基本相同,都是實現繼承或者轉換對象指針的作用;
唯一不通的是前者參數是羅列出來的,后者是存到數組中的;
call或apply功能就是實現繼承的;與面向對象的繼承extends功能相似;但寫法不同;
語法:
.call(對象[,參數1,參數2,…]);//此地參數是指的是對象的參數,非方法的參數;
.apply(對象,參數數組)//參數數組的形式:[參數1,參數2,…]
push 方法
將新元素添加到一個數組中,并返回數組的新長度值。
var a=[1,2,3,4];
a.push(5);
pop 方法
移除數組中的最后一個元素并返回該元素。
var a=[1,2,3,4];
a.pop();
shift 方法
移除數組中的第一個元素并返回該元素。
var a=[1,2];
alert(a.shift());
unshift 方法
將指定的元素插入數組開始位置并返回該數組。
if ((screen.width == 1360) && (screen.height == 1024)){
setActiveStyleSheet(CSS1);
}
在函數中:this 通常是一個隱含的參數。
在函數外(頂級作用域中):在瀏覽器中this 指的是全局對象;在Node.js中指的是模塊(module)的導出(exports)。
傳遞到eval()中的字符串:如果eval()是被直接調用的,this 指的是當前對象;如果eval()是被間接調用的,this 就是指全局對象。
每個對象都會在其內部初始化一個屬性,就是prototype(原型),當我們訪問一個對象的屬性時,如果這個對象內部不存在這個屬性,那么他就會去prototype里找這個屬性,這個prototype又會有自己的prototype,于是就這樣一直找下去,也就是我們平時所說的原型鏈的概念。
關系:instance.constructor.prototype = instance.proto
特點:JavaScript對象是通過引用來傳遞的,我們創建的每個新對象實體中并沒有一份屬于自己的原型副本,當我們修改原型時,與之相關的對象也會繼承這一改變。
當我們需要一個屬性時,JavaScript引擎會先看當前對象中是否有這個屬性,如果沒有的話,就會查找它的prototype對象是否有這個屬性,如此遞推下去,一致檢索到Object內建對象。
function Func(){}
Func.prototype.name = “Xiaosong”;
Func.prototype.getInfo = function() {
return this.name;
}
var person = new Func();
console.log(person.getInfo());//“Xiaosong”
console.log(Func.prototype);//Func { name = “Xiaosong”, getInfo = function() }
棧:原始數據類型(Undefined,Null,Boolean,Number,String)
堆:引用數據類型(對象、數組、函數)
兩種類型的區別:
//存儲位置不同
原始數據類型直接存儲在棧(stack)中的簡單數據段,占據空間小、大小固定,屬于被頻繁使用數據,所以放入棧中存儲;
引用數據類型存儲在堆(heap)中的對象,占據空間大、大小不固定,如果存儲在棧中,將會影響程序運行的性能;引用數據類型在棧中存儲了指針,該指針指向堆中該實體的起始地址。當解釋器尋找引用值時,會首先檢索其在棧中的地址,取得地址后從堆中獲得實體。
JavaScript 如何實現繼承?
(1)構造繼承
(2)原型繼承
(3)實例繼承
(4)拷貝繼承
//原型prototype機制或apply和call方法去實現較簡單,建議使用構造函數與原型混合方式。
function Parent() {
this.name = ‘song’;
}
function Child() {
this.age = 28;
}
Child.prototype = new Parent(); //通過原型,繼承了Parent
var demo = new Child();
alert(demo.age);
alert(demo.name); //得到被繼承的屬性
javascript創建對象簡單的說,無非就是使用內置對象或各種自定義對象,當然還可以用JSON;但寫法有很多種,也能混合使用。
//
(1)對象字面量的方式
person={firstname:“Mark”,lastname:“Yun”,age:25,eyecolor:“black”};
(2)用function來模擬無參的構造函數
function Person(){}
var person = new Person(); //定義一個function,如果使用new"實例化",該function可以看作是一個Class
person.name = “Xiaosong”;
person.age = “23”;
person.work = function() {
alert(“Hello " + person.name);
}
person.work();
(3)用function來模擬參構造函數來實現(用this關鍵字定義構造的上下文屬性)
function Person(name,age,hobby) {
this.name = name; //this作用域:當前對象
this.age = age;
this.work = work;
this.info = function() {
alert(“我叫” + this.name + “,今年” + this.age + “歲,是個” + this.work);
}
}
var Xiaosong = new Person(“WooKong”,23,“程序猿”); //實例化、創建對象
Xiaosong.info(); //調用info()方法
(4)用工廠方式來創建(內置對象)
var jsCreater = new Object();
jsCreater.name = “Brendan Eich”; //JavaScript的發明者
jsCreater.work = “JavaScript”;
jsCreater.info = function() {
alert(“我是”+this.work+“的發明者”+this.name);
}
jsCreater.info();
(5)用原型方式來創建
function Standard(){}
Standard.prototype.name = “ECMAScript”;
Standard.prototype.event = function() {
alert(this.name+“是腳本語言標準規范”);
}
var jiaoben = new Standard();
jiaoben.event();
(6)用混合方式來創建
function iPhone(name,event) {
this.name = name;
this.event = event;
}
iPhone.prototype.sell = function() {
alert(“我是”+this.name+”,我是iPhone5s的"+this.event+"~ haha!");
}
var SE = new iPhone(“iPhone SE”,“官方翻新機”);
SE.sell();
它的功能是把對應的字符串解析成JS代碼并運行;
應該避免使用eval,因為不安全,非常耗性能(2次,一次解析成js語句,一次執行)。
null 表示一個對象被定義了,值為“空值”;
undefined 表示不存在這個值。
typeof undefined //“undefined”
undefined :是一個表示"無"的原始值或者說表示"缺少值",就是此處應該有一個值,但是還沒有定義。當嘗試讀取時會返回 undefined;
例如變量被聲明了,但沒有賦值時,就等于undefined。
typeof null //“object”
null : 是一個對象(空對象, 沒有任何屬性和方法);
例如作為函數的參數,表示該函數的參數不是對象;
注意: 在驗證null時,一定要使用 === ,因為 == 無法分別 null 和 undefined
//Event工具集,from:github.com/markyunmarkyun.
Event = {
//頁面加載完成后
readyEvent: function(fn) {
if (fn == null) {
fn = document;
}
var oldonload = window.onload;
if (typeof window.onload != ‘function’) {
window.onload = fn;
}else{
window.onload = function() {
oldonload();
fn();
};
}
},
//視能力分別使用 demo0 || demo1 || IE 方式來綁定事件
//參數:操作的元素,事件名稱,事件處理程序
addEvent: function(element,type,handler) {
if (element.addEventListener) { //事件類型、需要執行的函數、是否捕捉
element.addEventListener(type,handler,false);
}else if (element.attachEvent) {
element.attachEvent(‘on’ + type, function() {
handler.call(element);
});
}else {
element[‘on’ + type] = handler;
}
},
//移除事件
removeEvent: function(element,type,handler) {
if (element.removeEventListener) {
element.removeEventListener(type,handler,false);
}else if (element.datachEvent) {
element.datachEvent(‘on’ + type,handler);
}else{
element[‘on’ + type] = null;
}
},
//阻止事件(主要是事件冒泡,因為IE不支持事件捕獲)
stopPropagation: function(ev) {
if (ev.stopPropagation) {
ev.stopPropagation();
}else {
ev.cancelBubble = true;
}
},
//取消事件的默認行為
preventDefault: function(event) {
if (event.preventDefault) {
event.preventDefault();
}else{
event.returnValue = false;
}
},
//獲取事件目標
getTarget: function(event) {
return event.target || event.srcElemnt;
},
//獲取event對象的引用,取到事件的所有信息,確保隨時能使用event;
getEvent: function(e) {
var ev = e || window.event;
if (!ev) {
var c = this.getEvent.caller;
while? {
ev = c.argument[0];
if (ev && Event == ev.constructor) {
break;
}
c = c.caller;
}
}
retrun ev;
}
};
[1,NaN,NaN]
因為 parseInt 需要兩個參數(val,radix),其中 radix 表示解析時用的基數。
map 傳了3個(element,index,array),對應的 radix 不合法導致解析失敗。
(1)我們在網頁中的某個操作(有的操作對應多個事件)。
例如:當我們點擊一個按鈕就會產生一個事件。是可以被 JavaScript 偵測到的行為。
(2)事件處理機制:IE是事件冒泡、Firefox同時支持兩種事件模型,也就是:捕獲型事件和冒泡型事件;
(3)ev.stopPropagation();(舊ie的方法 ev.cancelBubble = true;)
閉包是指有權訪問另一個函數作用域中變量的函數,創建閉包的最常見的方式就是在一個函數內創建另一個函數,通過另一個函數訪問這個函數的局部變量,利用閉包可以突破作用鏈域,將函數內部的變量和方法傳遞到外部。
//閉包特性:
(1)函數內再嵌套函數
(2)內部函數可以引用外層的參數和變量
(3)參數和變量不會被垃圾回收機制回收
//li節點的onclick事件都能正確的彈出當前被點擊的li索引
- index = 0
- index = 1
- index = 2
- index = 3
use strict是一種ECMAscript 5 添加的(嚴格)運行模式,這種模式使得 Javascript 在更嚴格的條件下運行,使JS編碼更加規范化的模式,消除Javascript語法的一些不合理、不嚴謹之處,減少一些怪異行為。
默認支持的糟糕特性都會被禁用,比如不能用with,也不能在意外的情況下給全局變量賦值;
全局變量的顯示聲明,函數必須聲明在頂層,不允許在非函數代碼塊內聲明函數,arguments.callee也不允許使用;
消除代碼運行的一些不安全之處,保證代碼運行的安全,限制函數中的arguments修改,嚴格模式下的eval函數的行為和非嚴格模式的也不相同;
提高編譯器效率,增加運行速度;
為未來新版本的Javascript標準化做鋪墊。
(1)創建一個空對象,并且 this 變量引用該對象,同時還繼承了該函數的原型。
(2)屬性和方法被加入到 this 引用的對象中。
(3)新創建的對象由 this 所引用,并且最后隱式的返回 this 。
//
var obj = {};
obj.proto = Base.prototype;
Base.call(obj);
hasOwnProperty
//
JavaScript 中 hasOwnProperty 函數方法是返回一個布爾值,指出一個對象是否具有指定名稱的屬性。此方法無法檢查該對象的原型鏈中是否具有該屬性;該屬性必須是對象本身的一個成員。
//
使用方法:object.hasOwnProperty(proName)其中參數object是必選項,一個對象的實例。proName是必選項,一個屬性名稱的字符串值。
//
如果 object 具有指定名稱的屬性,那么JavaScript中hasOwnProperty函數方法返回 true,反之則返回 false。
JSON(JavaScript Object Notation)是一種輕量級的數據交換格式。
它是基于JavaScript的一個子集。數據格式簡單,易于讀寫,占用帶寬小。
如:{“age”:“12”, “name”:“back”}
ajax的全稱:Asynchronous Javascript And XML,異步傳輸+js+xml。
所謂異步,在這里簡單地解釋就是:向服務器發送請求的時候,我們不必等待結果,而是可以同時做其他的事情,等到有了結果它自己會根據設定進行后續操作,與此同時,頁面是不會發生整頁刷新的,提高了用戶體驗。
//
(1)創建XMLHttpRequest對象,也就是創建一個異步調用對象
(2)創建一個新的HTTP請求,并指定該HTTP請求的方法、URL及驗證信息
(3)設置響應HTTP請求狀態變化的函數
(4)發送HTTP請求
(5)獲取異步調用返回的數據
(6)使用JavaScript和DOM實現局部刷新
同步的概念應該是來自于操作系統中關于同步的概念:不同進程為協同完成某項工作而在先后次序上調整(通過阻塞,喚醒等方式)。
同步強調的是順序性,誰先誰后;異步則不存在這種順序性。
//
同步:瀏覽器訪問服務器請求,用戶看得到頁面刷新,重新發請求,等請求完,頁面刷新,新內容出現,用戶看到新內容,進行下一步操作。
//
異步:瀏覽器訪問服務器請求,用戶正常操作,瀏覽器后端進行請求。等請求完,頁面不刷新,新內容也會出現,用戶看到新內容。
jsonp、iframe、window.name、window.postMessage、服務器上設置代理頁面
談一談你對 ECMAScript6 的了解?ECMAScript 6 是JavaScript語言的下一代標準,已經在2015年6月正式發布了。
它的目標,是使得JavaScript語言可以用來編寫復雜的大型應用程序,成為企業級開發語言。
標準的制定者有計劃,以后每年發布一次標準,使用年份作為標準的版本。
因為當前版本的ES6是在2015年發布的,所以又稱ECMAScript 2015。
也就是說,ES6就是ES2015
ES6的class可以看作只是一個語法糖,它的絕大部分功能,ES5都可以做到,新的class寫法只是讓對象原型的寫法更加清晰、更像面向對象編程的語法而已。
//定義類
class Point {
constructor(x,y) {
//構造方法
this.x = x; //this關鍵字代表實例對象
this.y = y;
} toString() {
return ‘(’ + this.x + ‘,’ + this.y + ‘)’;
}
}
(1)defer,只支持 IE
(2)async:
(3)創建 script,插入到 DOM 中,加載完畢后 callBack
- document.write 和 innerHTML 有何區別?
document.write 只能重繪整個頁面innerHTML 可以重繪頁面的一部分
- DOM 操作——怎樣添加、移除、移動、復制、創建和查找節點?
(1)創建新節點
createDocumentFragment() //創建一個DOM片段
createElement() //創建一個具體的元素
createTextNode() //創建一個文本節點
(2)添加、移除、替換、插入
appendChild()
removeChild()
replaceChild()
insertBefore() //在已有的子節點前插入一個新的子節點
(3)查找
getElementsByTagName() //通過標簽名稱
getElementsByName() //通過元素的Name屬性的值(IE容錯能力較強,會得到一個數組,其中包括id等于name值的)
getElementById() //通過元素Id,唯一性
如何編寫高性能 JavaScript ?詳細文章:淺談編寫高性能的Javascript代碼
- 哪些操作會造成內存泄漏?
內存泄漏是指任何對象在您不再擁有或需要它之后任然存在。
垃圾回收器定期掃描對象,并計算引用了每個對象的其他對象的數量,如果一個對象的引用數量為0(沒有其他對象引用過該對象),或對該對象的惟一引用是循環的,那么該對象的內存即可回收。
//
setTimeout 的第一個參數使用字符串而非函數的話,會引發內存泄漏。
閉包、控制臺日志、循環(在兩個對象彼此引用且彼此保留時,就會產生一個循環)
jQuery 中如何將數組轉化為 json 字符串,然后再轉化回來?
jQuery 中沒有提供這個功能,所以需要先編寫兩個 jQuery 的擴展:
$.fn.stringifyArray = function(array) {
return JSON.stringify(array)
}
$.fn.parseArray = function(array) {
return JSON.parse(array)
}
//然后調用:
$("").stringifyArray(array)
- jQuery.extend 與 jQuery.fn.extend 有何區別?
jQuery.extend(object); //為jQuery類添加類方法,可以理解為添加靜態方法
jQuery.extend({
min: function(a, b) { return a < b ? a : b; },
max: function(a, b) { return a > b ? a : b; }
});
jQuery.min(2,3); // 2
jQuery.max(4,5); // 5
jQuery.extend( target, object1, [objectN])用一個或多個其他對象來擴展一個對象,返回被擴展的對象
jQuery.fn.extend(object); //對jQuery.prototype進行的擴展,就是為jQuery類添加“成員函數”。jQuery類的實例可以使用這個“成員函數”。
比如我們要開發一個插件,做一個特殊的編輯框,當它被點擊時,便alert 當前編輯框里的內容。可以這么做:
$.fn.extend({
alertWhileClick:function() {
KaTeX parse error: Expected '}', got 'EOF' at end of input: …ction(){ alert((this).val());
});
}
});
KaTeX parse error: Expected 'EOF', got '#' at position 3: ("#?input1").alertW…("#input1")為一個jQuery實例,當它調用成員方法 alertWhileClick后,便實現了擴展,每次被點擊時它會先彈出目前編輯里的內容。
- 是否了解針對 jQuery 性能的優化方法?
基于Class的選擇性的性能相對于Id選擇器開銷很大,因為需遍歷所有DOM元素。
//
頻繁操作的DOM,先緩存起來再操作。用Jquery的鏈式調用更好。
比如:var str=$(“a”).attr(“href”);
//
for (var i = size; i < arr.length; i++) {}
for 循環每一次循環都查找了數組 (arr) 的.length 屬性,在開始循環的時候設置一個變量來存儲這個數字,可以讓循環跑得更快:
for (var i = size, length = arr.length; i < length; i++) {}
- jQuery 與 jQuery UI 有何區別?
jQuery是一個js庫,主要提供的功能是選擇器,屬性修改和事件綁定等等。
jQuery UI則是在jQuery的基礎上,利用jQuery的擴展性,設計的插件。提供了一些常用的界面元素,諸如對話框、拖動行為、改變大小行為等等
- 如何判斷當前腳本運行在瀏覽器還是 node 環境中?(阿里)
通過判斷 Global 對象是否為 window ,如果不為 window ,當前腳本沒有運行在瀏覽器中
- 怎樣用js實現千位分隔符?
正則 + replace
function commafy(num) {
num = num + ‘’;
var reg = /(-?d+)(d{3})/;
if (reg.test(num)) {
num = num.replace(reg, ‘$1,$2’);
}
return num;
}
- 檢測瀏覽器版本有哪些方式?
功能檢測、userAgent 特征檢測
比如:navigator.userAgent
//“Mozilla/5.0 (Macintosh; Intel Mac OS X 10_10_2) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/41.0.2272.101 Safari/537.36”
- Canvas和SVG的比較;
Canvas SVG
位圖技術,可以保存為.png 矢量圖技術,不能保存為位圖
善于表現顏色和線條細節 可以縮放,不善于表現細節
網頁游戲,統計圖 圖標,統計圖,地圖
一個標簽(canvas)+一個對象(getcontext),
所有圖形圖像都靠ctx繪制 幾十個標簽—每個圖形對應一個標簽
不能被搜索引擎爬蟲所訪問 可以
只能為整個 Canvas綁定監聽函數 每個圖形(標簽)可以綁定事件監聽函數
- 談談你對 JavaScript 中的模塊規范 CommonJS、AMD、CMD 的了解?
CommonJS AMD CMD
Node.js RequireJS SeaJS
//個人拙見
CommonJS AMD CMD
Node.js RequireJS SeaJS
詳細文章:淺析JS中的模塊規范(CommonJS,AMD,CMD)、關于 CommonJS AMD CMD UMD
- 前端 MVC、MVVM
1、MVC
[外鏈圖片轉存失敗,源站可能有防盜鏈機制,建議將圖片保存下來直接上傳(img-7tsS7qmW-1616229664822)(http://upload-images.jianshu.io/upload_images/4749582-b49cc8f09e938eaa.png?imageMogr2/auto-orient/strip%7CimageView2/2/w/1240)]MVC
模型(Model):數據保存
視圖(View):用戶界面
控制器(Controller):業務邏輯
(1)View 傳送指令到 Controller
(2)Controller 完成業務邏輯后,要求 Model 改變狀態
(3)Model 將新的數據發送到 View ,用戶得到反饋所有通信都是單向的。
2、MVVM
MVVM
模型(Model)
視圖(View)
視圖模型(ViewModel)
(1)各部分間都是雙向通信
(2)View 與 Model 不發生聯系,都通過 ViewModel 傳遞
(3)View 非常薄,不部署任何業務邏輯,稱為“被動視圖”(Passive View),即沒有任何主動性;而 ViewModel 非常厚,所有邏輯都部署在那里。
采用雙向綁定(data-binding):View 的變動,自動反映在 ViewModel ,反之亦然。
- HTTP協議的狀態消息都有哪些?(如200、302對應的描述)國內外的JS牛人都知道哪些?
協議是指計算機通信網絡中兩臺計算機之間進行通信所必須共同遵守的規定或規則,超文本傳輸協議(HTTP)是一種通信協議,它允許將超文本標記語言(HTML)文檔從Web服務器傳送到客戶端的瀏覽器
總結
以上是生活随笔為你收集整理的前端开发面试题总结之——JAVASCRIPT.One的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 郑州大学研究生院 郑州大学产业技术研究院
- 下一篇: Java编程图书开始了