1、晨曦。
2、js是一門什么樣的語言及特點?
js是一種基於對象和事件驅動的並具有相對安全性的客戶端腳本語言。也是一種廣泛用於web客戶端開發的腳本語言,常用來給html網頁添加動態功能,如響應用戶的各種操作。
主要的目的是為了解決服務器端語言遺留的速度問題,為客戶提供更流暢的瀏覽效果。
(詳細拓展:http://www.360doc.com/content/14/0317/11/10186276_361233415.shtml)
3、js的數據類型?
基本數據類型:String、boolean、Number、undefined、null
引用數據類型:Object、Array、Date、RegExp、Function
拓展:如何判斷數組數據類型?
1、通過專有方法判斷如:push(),pop(); //可自己給變量定義該方法,有時失效
2、 obj instanceof Array 返回值判斷;
3、es5和jquery都有方法Array.isArray()。
4、toString.call(param) 判斷;返回格式 [object Undefined] 5、obj.constructor === Function 返回值判斷
4、獲取所有的checkbox?
var domlist = document.getElementsByTagName("input");
var checkboxlist = [];
var len = domlist.length;
for (var i = 0; i < len; i++) {
if(domlist[i].type == "checkbox"){
checkboxlist.push(domlist[i])
}
}
//(for效率更高)在測試五百多個不同input中,while:for = 3~2ms:1~0ms,顯然for效率更高
5、綁定事件的方式?
1、直接在dom里綁定:<div onclick="test()"></div>
2、在js中通過onclick綁定:xxx.onclick=test;
3、通過事件綁定:dom.addEventListener("click",test,boolean)
(拓展:js事件流模型?)
“事件冒泡”:事件由最具體的元素接收,然后逐級向上傳播;
“事件捕捉”:事件由最不具體的節點先接收,然后逐級向下,一直到最具體元素;
“dom事件流”:三個階段:事件捕捉,目標階段,事件冒泡;
(附:事件流詳解)
ie事件流:冒泡型事件:button->div->body
netscape事件流:捕獲型事件:body->div->button
dom事件模型:body->div->button->button->div->body;
dom事件流同時支持兩種事件模型:但是捕獲事件先發生,從document對象開始,也在document對象結束
ie9以下不支持addEventListener/removeEventListener,采用attachEvent/detachEvent
(無關東東css:<!--[if lt IE 9]><![endif]-->)
(附:阻止事件傳播)
w3c中,使用stopPropagation()方法阻止冒泡;阻止默認事件:preventDefault();
ie中,cancelBubble = true阻止事件冒泡;阻止默認事件:window.event.returnValue = false;
6.什么是Ajax和JSON,它們的優缺點?
Ajax(Asynchronous Javascript And XML/異步的javascript和xml)。
優點:
可以使得頁面不重載全部內容的情況下加載局部內容,降低數據傳輸量。
避免用戶不斷刷新或者跳轉頁面,提高用戶體驗。
缺點:
對搜索引擎不友好。
要實現ajax下的前后退功能成本較大
可能造成請求數的增加
跨域問題限制
JSON:json是一種輕量級的數據交換格式,ECMA(歐洲計算機制造商協會)的一個子集;
優點:輕量級,占用帶寬小、易於人的閱讀和編寫,便於機器(js)解析,支持復合數據類型(數組,對象,字符串,數字),能直接為服務器端代碼使用,大大簡化了服務器端和客戶端的代碼開發量。
缺點:相對xml通用性較差,數據可描述性較差;
(拓展:json與xml的區別?)
xml定義:可拓展標記語言,用於標記電子文件使其具有結構性的標記語言,可以用來標記數據、定義數據類型,是一種允許用戶對自己的標記語言進行定義的語言。xml是SGML(標准通用標記語言)的子集,非常適合web傳輸。
xml提供統一的方法來描述和交換獨立於應用程序或供應商的結構化數據。
xml優點:
1、格式統一,符合標准;
2、容易與其他系統進行交互,數據共享比較方便
缺點:
1、xml文件格式文件龐大,格式復雜,傳輸占用更多帶寬
2、服務器和客戶端都需要花費大量代碼來解析xml,服務器和客戶端代碼變得異常復雜和不容易維護。
3、客戶端不同瀏覽器之間解析xml的方式不一致,需要重復編寫很多代碼。
4、服務器端和客戶端解析xml花費更多資源和時間
與json的優缺點比較?
1、可讀性、可拓展性都很出色,但是xml的編碼難度更高。
2、json的解碼難度幾乎為0,而xml得考慮子父節點;
3、xml的通用性更廣,json則廣泛應用於前端。
4、json相對xml,數據體積更小;與js交互更方便;
5、json對數據的描述性比xml較差;
6、json的無論是傳播還是解析速度遠遠快於xml;
7、什么情況會出現undefined?
當只聲明變量,並未賦值初始化的時候這個變量的值就是undefined;
(拓展:解釋原因?)
var a=null;
console.log(typeof a); // object
null是一個只有一個值的數據類型,這個值就是null。表示一個空指針對象。所以typeof返回object;
8、雙等號的類型轉換?
var undefined;
undefined == null; // true
1 == true; // true
2 == true; // false
0 == false; // true
0 == ''; // true
NaN == NaN; // false
[] == false; // true
[] == ![]; // true
// alert(!![]) //true
// alert(![]) //false
// alert([] == 0) //true
// alert(false == 0) //true
分析:undefined與null 但不全等(===)
當為number與string時,會將string轉換為number;
number和boolean時,會將boolean轉換為number
number或string與Object,會將Object轉換成number或string
(附:js中的數據類型轉換?)
函數轉換:parseInt()、parseFloat()、toString()
強類型轉換:Boolean()、Number()、String()
弱類型轉換:“==”、“-”、“+”、if()
(拓展:for循環中的效率問題?)
1.for(var i=0;i<arr.length;i++)
2.for(var i in arr)
3.for(var i=0,len=arr.length;i<len;i++)
第三種效率更高!
在大數據下:
第三種方式比第一種執行速度快3~4倍;
至於第三種比第三種快100多倍開外(詳細數據:http://www.111cn.net/wy/js-ajax/39368.htm)
9、基礎算法?已知:var str="get-element-by-id",寫一個函數轉化成駝峰形式(你懂得)?
function Naizi(str){
var arr = str.split("-");
var target = "";
for(var i=0,len=arr.length;i<len;i++){
target+=arr[i].substr(0,1).toUpperCase()+arr[i].substr(1);
}
return target;
}
10、基礎API?
數組:
var numberArray = [3,6,2,4,1,5];
倒序:numberArray.reverse();
降序:numberArray.sort(function(a-b){return b-a})
a.concat(b,c,d)
日期:
輸出YYYY-MM-DD
function getYMD(){
var date = new Date();
var y = date.getFullYear();
var m = date.getMonth()+1;
var d = date.getDate();
function getDouble(str){
var str;
if(str < 10){
return str = "0"+str;
}else{
return str = str;
}
}
return y +"-"+getDouble(m)+"-"+getDouble(d);
}
(值得一提:date.getDay() 返回星期0~6 星期日~星期六)
11、正則?
var str = ”<tr><td>{$id}</td><td>{$name}</td></tr>”的{$id}替換成10,{$name}替換成Tony
var target = str.replace(/{\$id}/,"10").replace(/{\$name}/,"Tony");
(拓展:tirm方法實現)
var str = " sdasad ";
function trim(str){
return str.replace(/(^\s*)|(\s*$)/g,"");
}
(拓展:轉義字符方法實現)
function escapeHTML(str){
return str.replace(/[<>"&]/g,function(match,key){
switch(match){
case '<':
return '\<';
break;
case '>':
return '\>';
break;
case '"':
return '\"';
break;
case '&':
return '\&';
break;
}
})
}
(拓展:正則構造函數var reg=new RegExp("xxx")與正則字面量形式var reg=//有什么不同?匹配郵箱?)
使用RegExp()構造函數的時候,不僅需要轉義引號(“\”),並且還需要雙反斜杠\\表示一個\。使用正則字面量形式效率更高;
郵箱匹配:
var reg = /^([a-zA-Z0-9_-])+@([a-zA-Z0-9_-])+(.[a-zA-Z0-9_-]{2,3})$/;
12、短路表達式 || &&?
foo = foo || bar;
如果foo 為真 foo = foo; 否則 foo = bar;
|| 第一個為真則返回第一個,否則返回第二個;
&& 第一個為假則返回第一個,否則返回第二個;
作用:精簡代碼,不過可讀性較低;
13、隨機取10個10-100數?
function getNumArr(n){
var arr = [];
for(var i = 0;i <n;i++){
arr.push(parseInt(Math.random()*90+10))
}
return arr;
}
14、dom增刪查改?
增:
document.createElement(tag);
document.createTextNode();
document.createDocumentFragment()
dom.appendChild(sondom);
dom.insertBefore(newdom,targetdom);
刪:
document.removeChild();
改:
document.replaceChild();
查:
getElementById()
getElementsByTagName()
getElementsByName();
15、字符串操作?
var str = 'http://item.taobao.com/item.html?a=1&b=2&c=&d=xxx&e';
//將GET參數按照鍵值對的形式輸出json
function getGEt(str){
var dataStr = str.split("?")[1];
var result = {};
if(dataStr.indexOf("&") > 0){
var bigArr = dataStr.split("&");
for(var i = 0,len = bigArr.length;i<len;i++){
var smallArr = bigArr[i].split("=");
result[smallArr[0]] = smallArr[1];
}
}else{
var arr = dataStr.split("=");
result[arr[0]] = arr[1];
}
return result;
}
16、閉包的使用?
for(var i = 0,len=domlist.length;i<len;i++){
domlist[i].onclick = function(){
console.log(i);
}
}
都輸出domlist.length;
onclick 是一個異步函數;當onclick執行的時候i此時變成了domlist.length;
解決:(閉包)
for(var i=0,len=domlist.length;i<len;i++){
domlist[i].onclick = (function(a){
return function(){
console.log(a)
}
})(i);
}
//也可以設置私有屬性;
17、js中callee和caller?
caller是返回一個對函數的引用,該函數調用了當前函數;
callee是返回正在被執行的function函數,也就是所指定的對象的正文;
(注:callee是arguments的屬性,只有當函數被調用的時候才會生成arguments,未調用時為null,所以調用callee將會報錯)
var result=[];
function fn(n){ //典型的斐波那契數列
if(n==1){
return 1;
}else if(n==2){
return 1;
}else{
if(result[n]){
return result[n];
}else{
//argument.callee()表示fn()
result[n]=arguments.callee(n-1)+arguments.callee(n-2);
return result[n];
}
}
}
18、實現函數clone,包括Number、String、Object、Array、Boolean?
function clone(param){
var result;
switch(typeof param){
case "object":
if(param instanceof Array){
result = [];
for(var i=0,len=param.length;i<len;i++){
result.push(param[i]);
}
return result;
} else if(param instanceof Object){
result = {};
for(var key in param){
result[key] = param[key];
}
return result;
}else{
return result = param;
}
break;
default:
return result = param;
break;
}
}
19.老掉牙的數組去重?
var arr = [123,"1",123,12,312,3,123,"123",1,23,123,12,312,3,123,123,123,123,12] function gotU(arr){
var result = [];
var json = {};
for(var i = 0,len=arr.length;i<len;i++){
var temp = arr[i];
var type = typeof temp;
if(!json[temp]){
json[temp] = [type];
result.push(temp);
}else{
if(json[temp].indexOf(type) < 0){
json[temp].push(type);
result.push(temp);
}
}
}
return result;
}
20.提取對象屬性與方法?
粗壯的旺財是一條可愛的小狗(Dog),它的叫聲很好聽(wow),每次看到主人的時候就會乖乖叫一聲(yelp)。
function Dog(){
this.name = "粗壯的旺財";
this.type = "cute";
this.animalkind = "dog";
}
Dog.prototype={
sound:function(){
alert("wow SB");
},
seeMaster:function(){
this.sound();
},
seeMasterBeingB:function(){
var bitches = 50;
for(var i=0;i<bitches;i++){
this.seeMaster();
}
}
}
小豬和粗壯的旺財一樣,原來也是一條可愛的小狗,可是突然有一天瘋了(MadDog),一看到人就會每隔半秒叫一聲(wow)地不停叫喚(yelp)。
function MadDog(){
this.name = "小豬";
}
MadDog.prototype = new Dog();
MadDog.prototype.foundSomeoneIsAGay=function(){
var self = this;
this.timer = setInterval(function(){
self.seeMaster();
},500)
}
21、編寫一個js,輸入指定類型選擇器返回匹配的dom節點(id,class,tag),考慮瀏覽器兼容性和性能;
function select(str){
if(str){
var doms;
var result = [];
var first = str.charAt(0);
var other = str.substr(1);
if(first == "#"){
doms = document.getElementById(other);
result.push(doms);
return result;
}else if(first == "."){
if(document.getElementsByClassName){
doms = document.getElementsByClassName(other);
return getArr(doms);
}else{
doms = document.getElementsByTagName("*");
for(var i = 0,len = doms.length;i<len;i++){
if(hasClass(doms[i],other)){
result.push(doms[i])
}
}
return result;
}
}else{
doms = document.getElementsByTagName(str);
return getArr(doms);
}
}
}
function getArr(param){
var result = null;
try{
result = Array.prototype.slice.call(param,0) //非ie
}catch(e){
result = [];
for(var i=0,len=param.length;i<len;i++){
result.push(param[i]);
}
}
return result;
}
function hasClass(dom,classname){
var clas = dom.className;
var arr = [];
if(dom && clas){
arr = clas.split(" ");
for (var i = 0,len = arr.length; i < len; i++) {
if(arr[i] == classname) return true;
}
return false;
}
return false;
}
22、評價代碼,給出意見。
if(window.addEventListener){
var addListener = function(el,type,listener,useCapture){
el.addEventListener(type,listener,useCapture);
};
}else if(document.all){
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;
}
}
(拓展:阻止默認事件與冒泡事件)
function preventEvent(e){
var e = e || window.event;
e.preventEvent || e.returnValue = false;
e.stopPropagation || e.cancelBubble = true;
}
23、String對象添加方法,例:addSpace("hello world") // -> 'h e l l o w o r l d';
String.prototype.addSpace = function() {
if(this.length>0){
var arr = this.split("");
var tempArr = [];
var target;
for(var i=0,len=arr.length;i<len;i++){
if(arr[i] != " "){
tempArr.push(arr[i]);
}
}
return target = tempArr.join(" ");
}
return this;
};
(附:函數聲明與函數表達式的區別?)
在js中,解析器在向執行環境中加載數據時,對函數聲明和函數表達式並非一視同仁的,
解析器會率先讀取函數聲明,並使其在執行任何代碼之前可用(也就是函數聲明提升),
至於函數表達式要等到解析器執行到它所在的代碼,才會真正解析執行。(只有變量名稱提升)
24、定義一個方法代理console.log。
function log(){
console.log.apply(null,arguments);
}
(拓展:apply與call的區別?)
apply與call的作用相同,即調用一個對象的一個方法,改變該方法的this的指針。
在第二個參數:apply傳入的是一個參數數組,而call傳入的是離散型參數。
25、在js中什么是偽數組?如何轉化成真數組?
偽數組:無法直接調用數組的方法,但是仍含有length屬性。
getElementsByTagName/getElementsByClassName/childNodes/arguments 都是偽數組;
通過使用Array.prototype.slice.call(fakeArray)將偽數組轉化為真數組;
(拓展:給log添加前綴?)
function log(){
var args = Array.prototype.slice.call(arguments);
args.unshift("aa");
console.log.apply(null,args);
}
原文地址:http://www.qdfuns.com/notes/38026/5ef8849c800b10ee798e46d05fd12680.html