1.JavaScript是一門什么樣的語言,它有哪些特點?
沒有標准答案。
2.JavaScript的數據類型都有什么?
基本數據類型:String,boolean,Number,Undefined
引用數據類型:Object(Array,Date,RegExp,Function,Null)
那么問題來了,如何判斷某變量是否為數組數據類型?
- 方法一.判斷其是否具有“數組性質”,如slice()方法。可自己給該變量定義slice方法,故有時會失效
- 方法二.obj instanceof Array 在某些IE版本中不正確
- 方法三.方法一二皆有漏洞,在ECMA Script5中定義了新方法Array.isArray(), 保證其兼容性,最好的方法如下:
if(typeof Array.isArray==="undefined") { Array.isArray = function(arg){ return Object.prototype.toString.call(arg)==="[object Array]" }; }
3.已知ID的Input輸入框,希望改變文本框的背景顏色,怎么做?(原生JS)
document.getElementById("id").style.backgroundColor = "red";
4.希望獲取到頁面中所有的checkbox怎么做?(原生JS)
var domList = document.getElementsByTagName(‘input’) var checkBoxList = []; var len = domList.length; //緩存到局部變量 while (len--) { //使用while的效率會比for循環更高 if (domList[len].type == ‘checkbox’) { checkBoxList.push(domList[len]); } }
5.Html事件綁定有幾種方式?
- 直接在DOM里綁定事件:<div onclick=”test()”></div> 這種方式稱為原生事件或者屬性事件
- 在JS里通過onclick綁定:xxx.onclick = test
- Dom標准通過事件添加進行綁定:addEventListener("click",test, false) //第三個參數為是否支持事件捕捉
- IE事件:attachEvent("onclick",test)
那么問題來了,Javascript的事件流模型都有什么?
- “事件捕捉”:事件由最不具體的節點先接收,然后逐級向下,一直到最具體的
- 目標事件
- “事件冒泡”:事件開始由最具體的元素接受,然后逐級向上傳播
- “DOM事件流”:三個階段:事件捕捉,目標階段,事件冒泡
- 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; } }
6.看下列代碼,將會輸出什么?(變量聲明提升)
var a=1; function a(){} alert(a);//打印1
上面的代碼經過變量提升后,等價於下面的代碼
var a;function a(){} a = 1;//只把聲明提到最前面,賦值a=1;保留,函數聲明也會提到最前面 alert(a);//打印
再看下面的輸出結果:
var a=1; var a=function (){} alert(a);//打印a函數
此時打印a函數,不會打印1,因為下面是一個函數表達式,跟變量聲明一樣,只會把var a;提升到最前面,a=function(){}保留,會覆蓋前面的a=1;因此打印函數。
此題目,我再百度面試的時候問到過。
7.掌握樣式的優先級。
!important > style(內聯) > Id(權重100) > class(權重10) > 標簽(權重1) 同類別的樣式,后面的會覆蓋前面的。
百度視頻部門一道面試題是這樣的:
<style> .red{color:red;} .blue{color:blue;} </style> <p class="blue red"></p> <!-- 此時顯示藍色,樣式的顯示跟class里面的先后順序無關,都是類選擇器,后面的會覆蓋前面的,因此藍色覆蓋紅色的 -->
8.怎樣添加、移除、移動、復制、創建和查找節點
1)創建新節點
createDocumentFragment() //創建一個DOM片段
createElement() //創建一個具體的元素
createTextNode() //創建一個文本節點
2)添加、移除、替換、插入
appendChild() //添加
removeChild() //移除
replaceChild() //替換
insertBefore() //插入
3)查找
getElementsByTagName() //通過標簽名稱
getElementsByName() //通過元素的Name屬性的值
getElementById() //通過元素Id,唯一性
9.用js寫一個正則匹配標簽中是否包含一個class(百度面試題)
function hasClassName(id,name){ var cls = document.getElementById(id).className; var reg = new RegExp("(^|\\s)"+name+"($|\\s)","g") return reg.test(cls); } //正則的意思是:以名字開頭或者以空格開頭,最終以名字結束或者以空格結束。
10.事件循環綁定,輸出結果(考察閉包)
var list = document.getElementsByTagName("a");//假設有10個a for(var i=0;i<list.length;i++){ list[i].onclick = function(i){ return function(){ alert(i); } } } //最終點擊的時候,都打印10
通過閉包封裝后的代碼:
var list = document.getElementsByTagName("a"); for(var i=0;i<list.length;i++){ list[i].onclick = (function(i){ return function(){ alert(i); } })(i) } //打印對應的索引
閉包我所知道的兩個作用:
a.通過閉包可以把局部變量傳遞出來,就是通過閉包可以訪問函數內部的變量,比如下面的代碼:
function count(){ var num = 1; return function(){ return num++; } } var countFn = count(); countFn();//輸出1 countFn();//輸出2 countFn();//輸出3 countFn();//輸出4
通過閉包就可以訪問函數內部的局部變量,並且實現數量累加。
b.使用閉包可以避免空間污染,閉包內部的變量都只能在內部使用,這樣有效避免和外部變量的混淆。(個人理解)
11.js數組去重。
var arr = [1,6,3,9,4,9,3,8,2]; var obj = {},newArr = []; function delRepeat(){ for(var i=0,j=arr.length;i<j;i++){ if(!obj[arr[i]]){ newArr.push(arr[i]); obj[arr[i]] = arr[i]; } } } delRepeat();//刪掉重復項 newArr//打印新數組
12.兩個div標簽,如何控制標簽左邊固定,右邊自適應,左邊div標簽的寬度為100px(滴滴面試題)
//a. 左邊左浮動,右邊加個overflow:hidden; #lt{ float: left;width:100px; background: #ff0;} #rt{ overflow: hidden; background: #f0f;} //b.左邊左浮動,右邊加個margin-left; #lt{ float: left; width:100px; background: #ff0;} //以上兩種方式都可以實現
滴滴面試起初問我,現在有並排的三個Div框,如何實現三個div都自適應,我當時就懵了,這個考察的是display:table的使用
<!DOCTYPE html> <html lang="zh-CN"> <head> <meta charset="utf-8"/> <title>等高布局</title> <style> html { font-size: 10px;; } body { font-size: 1.4rem; } .box { background-color: rgba(200,200,200,0.7); margin: 0 1rem; width: 33.33%; padding: 1rem; } .box:nth-child(2) { height: 5rem; background-color: rgba(200,210,230,0.7); } .accordant { display: table-row; } .table { width: 100%; display: table; } .table .accordant { display: table-row; } .table .accordant .box { display: table-cell; vertical-align: middle; text-align: center; } </style> </head> <body> <div class="table"> <div class="accordant"> <div class="box"> <p>這是一個 Figure</p> </div> <div class="box"> <p>這是一個 Figure</p> </div> <div class="box"> <p>這是一個 Figure</p> </div> </div> </div> </body> </html>
13.實現一個函數clone,可以對JavaScript中的5種主要的數據類型(包括Number、String、Object、Array、Boolean)進行值復制
- 考察點1:對於基本數據類型和引用數據類型在內存中存放的是值還是指針這一區別是否清楚
- 考察點2:是否知道如何判斷一個變量是什么類型的
- 考察點3:遞歸算法的設計
// 方法一: Object.prototype.clone = function(){ var o = this.constructor === Array ? [] : {}; for(var e in this){ o[e] = typeof this[e] === "object" ? this[e].clone() : this[e]; } return o; } //方法二: function clone(Obj) { var buf; if (Obj instanceof Array) { buf = []; //創建一個空的數組 var i = Obj.length; while (i--) { buf[i] = clone(Obj[i]); } return buf; }else if (Obj instanceof Object){ buf = {}; //創建一個空對象 for (var k in Obj) { //為這個對象添加新的屬性 buf[k] = clone(Obj[k]); } return buf; }else{ //普通變量直接賦值 return Obj; } }
14.繼承的使用
function Animal(name) { this.name = name; this.showName = function() { console.log(this.name); }; } //第一種繼承方式 function Cat(name) { Animal.call(this, name);//此處注意,call不能繼承對象原型上的方法 } //第二種繼承方式 Cat.prototype = new Animal();//繼承所有屬性和方法 function Dog(name) { Animal.apply(this, name);//同Call一樣 } Dog.prototype = new Animal();
15.請評價以下代碼並給出改進意見
if(window.addEventListener){ var addListener = function(el,type,listener,useCapture){ el.addEventListener(type,listener,useCapture); }; } else if(document.all){ var addListener = function(el,type,listener){ el.attachEvent("on"+type,function(){ listener.apply(el); }); } }
評價:
- 不應該在if和else語句中聲明addListener函數,應該提前先聲明,定義全局變量;
- 不需要使用window.addEventListener或document.all來進行檢測瀏覽器,應該使用能力檢測;
- 由於attachEvent在IE中有this指向問題,所以調用它時需要處理一下
改進如下:
function addEvent(elem, type, handler){ if(elem.addEventListener){ elem.addEventListener(type, handler, false); }else if(elem.attachEvent){ elem.attachEvent('on' + type, handler); }else{ elem['on' + type] = handler; } }
16.對作用域上下文和this的理解,看下列代碼:
var User = { count: 1, getCount: function() { return this.count; } }; console.log(User.getCount()); // 1 var func = User.getCount; console.log(func()); // undefined