前端面試之Javascript基礎113+【二】

一、JS基礎

  1. javascript的typeof返回哪些數據類型
	1. alert(typeof [1, 2]); //object
    2. alert(typeof 'leipeng'); //string
   	3.  var i = true; 
   		 alert(typeof i); //boolean
    4. alert(typeof 1); //number
   	5.  var a; 
   	    alert(typeof a); //undefined
   	6.  function a(){;};
        alert(typeof a) //function
  1. 例舉3種強制類型轉換和2種隱式類型轉換?
強制(parseInt(),parseFloat(),Number())
隱式(== ,!!
  1. split() 、join() 的區別

前者是切割成數組的形式,後者是將數組轉換成字符串

  1. 數組方法pop() push() unshift() shift()
push()尾部添加 pop()尾部刪除
unshift()頭部添加 shift()頭部刪除
map() : 遍歷數組中的元素, 返回一個新數組(包含回調函數返回的數據)
filter():遍歷數組中的元素, 返回一個新數組(包含回調函數返回true的元素)
  1. 事件綁定和普通事件有什麼區別
普通添加事件的方法:
var btn = document.getElementById("hello");
btn.onclick = function(){
	alert(1);
}
btn.onclick = function(){
	alert(2);
}
執行上面的代碼只會alert 2 

事件綁定方式添加事件:
var btn = document.getElementById("hello");
btn.addEventListener("click",function(){
	alert(1);
},false);
btn.addEventListener("click",function(){
	alert(2);
},false);
執行上面的代碼會先alert 1 再 alert 2
普通添加事件的方法不支持添加多個事件,最下面的事件會覆蓋上面的,而事件綁定(addEventListener)方式添加事件可以添加多個。
addEventListener不兼容低版本IE
普通事件無法取消
addEventLisntener還支持事件冒泡+事件捕獲
  1. IE和DOM事件流的區別

1.執行順序不一樣、
2.參數不一樣
3.事件加不加on
4.this指向問題

  1. IE和標準下有哪些兼容性的寫法

var ev = ev || window.event
document.documentElement.clientWidth || document.body.clientWidth
var target = ev.srcElement||ev.target

  1. call和apply的區別

功能一樣, 都是將當前函數作爲指定對象的方法執行, 即函數中的this是指定對象
call(thisObj,arg1,arg2…) //將所有參數一個一個傳遞進去
apply(thisObj,[argArray]) //將所有參數放在數組中傳入

  1. Worker繼承Person的方法
//使用構造函數+原型的組合模式
function Person( age, name ){ 
  this.age = age; 
  this.name = name; 
} 
Person.prototype.show = function(){ 
  alert('父級方法'); 
} 

function Worker(age,name,job){ 
  Person.apply( this, arguments); 
  this.job = job; 
} 
Worker.prototype = new Person();

var Person = new Person(14,'張三 '); 
var Worker = new Worker (25,'李四','程序員');
  1. 如何阻止事件冒泡和事件默認行爲
//阻止事件冒泡
if(typeof ev.stopPropagation=='function') {  //標準的
	ev.stopPropagation();
} else { //非標準IE
	window.event.cancelBubble = true;
}
//阻止事件默認行爲
return false
  1. 添加 刪除 替換 插入到某個元素的方法

element.appendChild()
element.insertBefore()
element.replaceChild()
element.removeChild()

  1. javascript的內置對象和宿主對象

內置對象爲Object, Array, Function, Date, Math等
宿主爲瀏覽器自帶的window 等

  1. window.onload 和document ready的區別

window.onload 是在dom文檔樹加載完和所有文件加載完之後執行一個函數document.ready原生中沒有這個方法,jquery中有 $().ready(function),在dom文檔樹加載完之後執行一個函數(注意,這裏面的文檔樹加載完不代表全部文件加載完)。
(document).readywindow.onloadwindow.onload(document).ready要比window.onload先執行 window.onload只能出來一次,(document).ready可以出現多次

  1. ”==”和“===”的不同

前者會自動轉換類型
後者不會

  1. 瀏覽器的同源策略

一段腳本(ajax)只能讀取來自於同一來源的窗口和文檔的屬性,這裏的同一來源指的是主機名、協議和端口號的組合

  1. JavaScript是一門什麼樣的語言,它有哪些特點?

javaScript一種直譯式腳本語言,是一種動態類型、弱類型、基於原型的語言,內置支持類型。它的解釋器被稱爲JavaScript引擎,爲瀏覽器的一部分,廣泛用於客戶端的腳本語言,最早是在HTML網頁上使用,用來給HTML網頁增加動態功能。JavaScript兼容於ECMA標準,因此也稱爲ECMAScript。
基本特點

  1. 是一種解釋性腳本語言(代碼不進行預編譯)。
  2. 主要用來向HTML(標準通用標記語言下的一個應用)頁面添加交互行爲。
  3. 可以直接嵌入HTML頁面,但寫成單獨的js文件有利於結構和行爲的分離。
    跨平臺特性,在絕大多數瀏覽器的支持下,可以在多種平臺下運行(如Windows、Linux、Mac、Android、iOS等)。
  1. JavaScript的數據類型都有什麼?
基本數據類型:String,boolean,Number,Undefined, Null
引用數據類型:Object, Array, Function
那麼問題來了,如何判斷某變量是否爲數組數據類型?
方法一.判斷其是否具有“數組性質”,如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]"
    };  
}
  1. 已知ID的Input輸入框,希望獲取這個輸入框的輸入值,怎麼做?(不使用第三方框架)
document.getElementById(ID).value
  1. 希望獲取到頁面中所有的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]);
  }
}
  1. 設置一個已知ID的DIV的html內容爲xxxx,字體顏色設置爲黑色(不使用第三方框架)

var dom = document.getElementById(“ID”);
dom.innerHTML = “xxxx”
dom.style.color = “#000”

  1. 當一個DOM節點被點擊時候,我們希望能夠執行一個函數,應該怎麼做?

直接在DOM裏綁定事件:


在JS裏通過onclick綁定:xxx.onclick = test
通過事件添加進行綁定:addEventListener(xxx, ‘click’, test)
那麼問題來了,Javascript的事件流模型都有什麼?
“事件冒泡”:事件開始由最具體的元素接受,然後逐級向上傳播
“事件捕捉”:事件由最不具體的節點先接收,然後逐級向下,一直到最具體的
“DOM事件流”:三個階段:事件捕捉,目標階段,事件冒泡

  1. 看下列代碼輸出爲何?解釋原因。
var a;
alert(typeof a); // undefined
alert(b); // 報錯

解釋:Undefined是一個只有一個值的數據類型,這個值就是“undefined”,在使用var聲明變量但並未對其賦值進行初始化時,這個變量的值就是undefined。而b由於未聲明將報錯。注意未申明的變量和聲明瞭未賦值的是不一樣的。
  1. 看下列代碼,輸出什麼?解釋原因。
var a = null;
alert(typeof a); //object

解釋:null是一個只有一個值的數據類型,這個值就是null。表示一個空指針對象,所以用typeof檢測會返回”object”。
看下列代碼,輸出什麼?解釋原因。
var undefined;
undefined == null; // true
1 == true;   // true
2 == true;   // false
0 == false;  // true
0 == '';     // true
NaN == NaN;  // false
[] == false; // true
[] == ![];   // true

undefined與null相等,但不恆等(===)
一個是number一個是string時,會嘗試將string轉換爲number
嘗試將boolean轉換爲number,01
嘗試將Object轉換成number或string,取決於另外一個對比量的類型
所以,對於0、空字符串的判斷,建議使用 “===” 。“===”會先判斷兩邊的值類型,類型不匹配時爲false。
那麼問題來了,看下面的代碼,輸出什麼,foo的值爲什麼?
var foo = "11"+2-"1";
console.log(foo);
console.log(typeof foo);
執行完後foo的值爲111,foo的類型爲String。
  1. 看代碼給答案。
var a = new Object();
a.value = 1;
b = a;
b.value = 2;
alert(a.value);
答案:2(考察引用數據類型細節)
  1. 已知數組var stringArray = [“This”, “is”, “Baidu”, “Campus”],Alert出”This is Baidu Campus”。

alert(stringArray.join(“”))

  1. 已知有字符串foo=”get-element-by-id”,寫一個function將其轉化成駝峯表示法”getElementById”。
function combo(msg){
    var arr=msg.split("-");
    for(var i=1;i<arr.length;i++){
     arr[i]=arr[i].charAt(0).toUpperCase()+arr[i]
.substr(1,arr[i].length-1);
    }
    msg=arr.join("");
    return msg;
}
  1. var numberArray = [3,6,2,4,1,5]; (考察基礎API)
  1. 實現對該數組的倒排,輸出[5,1,4,2,6,3]
    numberArray.reverse()
  2. 實現對該數組的降序排列,輸出[6,5,4,3,2,1]
    numberArray.sort(function(a,b){return b-a})
  1. 輸出今天的日期,以YYYY-MM-DD的方式,比如今天是2014年9月26日,則輸出2014-09-26
var d = new Date();
// 獲取年,getFullYear()返回4位的數字
var year = d.getFullYear();
// 獲取月,月份比較特殊,0是1月,11是12月
var month = d.getMonth() + 1;
// 變成兩位
month = month < 10 ? '0' + month : month;
// 獲取日
var day = d.getDate();
day = day < 10 ? '0' + day : day;
alert(year + '-' + month + '-' + day);
  1. 將字符串”{KaTeX parse error: Expected 'EOF', got '}' at position 3: id}̲</td><td>{name}”中的{KaTeX parse error: Expected 'EOF', got '}' at position 3: id}̲替換成10,{name}替換成Tony (使用正則表達式)
"<tr><td>{$id}</td><td>{$id}_{$name}</td></tr>".replace(/{\$id}/g, '10').replace(/{\$name}/g, 'Tony');
  1. 爲了保證頁面輸出安全,我們經常需要對一些特殊的字符進行轉義,請寫一個函數escapeHtml,將<, >, &, “進行轉義
function escapeHtml(str) {
return str.replace(/[<>”&]/g, function(match) {
    switch (match) {
                   case<:
                      return&lt;;
                   case>:
                      return&gt;;
                   case&:
                      return&amp;;
                   case “\””:
                      return&quot;;
      }
  });
}
  1. foo = foo||bar ,這行代碼是什麼意思?爲什麼要這樣寫?

如果foo存在,值不變,否則把bar的值賦給foo。
短路表達式:作爲”&&”和”||”操作符的操作數表達式,這些表達式在進行求值時,只要最終的結果已經可以確定是真或假,求值過程便告終止,這稱之爲短路求值。

  1. 看下列代碼,將會輸出什麼?(變量聲明提升)
var foo = 1;
(function(){
    console.log(foo);
    var foo = 2;
    console.log(foo);
})()
答案:輸出undefined 和 2。上面代碼相當於:
var foo = 1;
(function(){
    var foo;
    console.log(foo); //undefined
    foo = 2;
    console.log(foo); // 2;   
})()
函數聲明與變量聲明會被JavaScript引擎隱式地提升到當前作用域的頂部,但是隻提升名稱不會提升賦值部分。
  1. 用js實現隨機選取10–100之間的10個數字,存入一個數組,並排序。
function randomNub(aArray, len, min, max) {
               if (len >= (max - min)) {
                   return '超過' + min + '-' + max + '之間的個數範圍' + (max - min - 1) + '個的總數';
               }
               if (aArray.length >= len) {
                   aArray.sort(function(a, b) {
                       return a - b
                   });
                   return aArray;
               }
               var nowNub = parseInt(Math.random() * (max - min - 1)) + (min + 1);
               for (var j = 0; j < aArray.length; j++) {
                   if (nowNub == aArray[j]) {
                       randomNub(aArray, len, min, max);
                       return;
                   }
               }
               aArray.push(nowNub);
               randomNub(aArray, len, min, max);
               return aArray;
           }
var arr=[];
randomNub(arr,10,10,100);
  1. 把兩個數組合並,並刪除第二個元素。
var array1 = ['a','b','c'];
var bArray = ['d','e','f'];
var cArray = array1.concat(bArray);
cArray.splice(1,1);
  1. 怎樣添加、移除、移動、複製、創建和查找節點(原生JS,實在基礎,沒細寫每一步)

1)創建新節點
createDocumentFragment() //創建一個DOM片段
createElement() //創建一個具體的元素
createTextNode() //創建一個文本節點
2)添加、移除、替換、插入
appendChild() //添加
removeChild() //移除
replaceChild() //替換
insertBefore() //插入
3)查找
getElementsByTagName() //通過標籤名稱
getElementsByName() //通過元素的Name屬性的值
getElementById() //通過元素Id,唯一性

  1. 有這樣一個URL:http://item.taobao.com/item.htm?a=1&b=2&c=&d=xxx&e,請寫一段JS程序提取URL中的各個GET參數(參數名和參數個數不確定),將其按key-value形式返回到一個json結構中,如{a:’1′, b:’2′, c:”, d:’xxx’, e:undefined}。
function serilizeUrl(url) {
    var urlObject = {};
    if (/\?/.test(url)) {
        var urlString = url.substring(url.indexOf("?") + 1);
        var urlArray = urlString.split("&");
        for (var i = 0, len = urlArray.length; i < len; i++) {
            var urlItem = urlArray[i];
            var item = urlItem.split("=");
            urlObject[item[0]] = item[1];
        }
        return urlObject;
    }
    return null;
}
  1. 正則表達式構造函數var reg=new RegExp(“xxx”)與正則表達字面量var reg=//有什麼不同?匹配郵箱的正則表達式?
當使用RegExp()構造函數的時候,不僅需要轉義引號(即\”表示”),並且還需要雙反斜槓(即\\表示一個\)。使用正則表達字面量的效率更高。 
郵箱的正則匹配:
	var regMail = /^([a-zA-Z0-9_-])+@([a-zA-Z0-9_-])+((.[a-zA-Z0-9_-]{2,3}){1,2})$/;
  1. 看下面代碼,給出輸出結果。
for(var i=1;i<=3;i++){
  setTimeout(function(){
      console.log(i);    
  },0);  
};
答案:4 4 4。
原因:回調函數是在for結束之後才運行的。追問,如何讓上述代碼輸出1 2 3for(var i=1;i<=3;i++){
   setTimeout((function(j){  //改成立即執行函數
console.log(j);    
   })(i),0);  
};
  1. 寫一個function,清除字符串前後的空格。(兼容所有瀏覽器)
if (!String.prototype.trim) { 
    String.prototype.trim = function() { 
    return this.replace(/^\s+/, "").replace(/\s+$/,"");
 } 
} 
//測試 
var str = " \t\n test string ".trim(); 
alert(str == "test string"); // alerts "true"
  1. Javascript中, 以下哪條語句一定會產生運行錯誤?

var _變量=NaN; B、var 0bj = []; C、var obj = //; D、var obj = {}; 答案( B C )

  1. 以下兩個變量a和b,a+b的哪個結果是NaN? 答案( AC )

A、var a=undefined; b=NaN
B、var a= ‘123’; b=NaN
C、var a =undefined , b =NaN
var a=NaN , b=‘undefined’

  1. var a=10; b=20; c=4; ++b+c+a++ 以下哪個結果是正確的?

A 34 B、35 C、36 D、37 答案( B )

  1. 下面的JavaScript語句中,( D )實現檢索當前頁面中的表單元素中的所有文本框,並將它們全部清空

A. for(vari=0;i< form1.elements.length;i++) {
if(form1.elements.type==”text”)
form1.elements.value=”";}
B. for(vari=0;i<document.forms.length;i++) {
if(forms[0].elements.type==”text”)
forms[0].elements.value=”";
}
C. if(document.form.elements.type==”text”)
form.elements.value=”";
D. for(vari=0;i<document.forms.length; i++){
for(var j=0;j<document.forms.elements.length; j++){
if(document.forms.elements[j].type==”text”)
document.forms.elements[j].value=”";
}
}

  1. 要將頁面的狀態欄中顯示“已經選中該文本框”,下列JavaScript語句正確的是( A )

A. window.status=”已經選中該文本框”
B. document.status=”已經選中該文本框”
C. window.screen=”已經選中該文本框”
D. document.screen=”已經選中該文本框”

  1. 以下哪條語句會產生運行錯誤:(AD)

A.var obj = ();
B.var obj = [];
C.var obj = {};
D.var obj = //;

  1. 以下哪個單詞不屬於javascript保留字:(B)

A.with
B.parent
C.class
D.void

  1. 請選擇結果爲真的表達式:(C)

A.null instanceof Object
B.null === undefined
C.null == undefined
D.NaN == NaN

  1. 分析代碼,得出正確的結果。
var a=10, b=20 , c=30;
	++a;
	a++;
	e=++a + (++b) + (c++) + a++;
	alert(e);
彈出提示對話框:77
  1. 寫出函數DateDemo的返回結果,系統時間假定爲今天
function DateDemo(){
 var d, s="今天日期是:";
 d = new Date();
s += d.getMonth() +1+ "/";
s += d.getDate() + "/";
s += d.getFullYear();
return s;
}
結果:今天日期是:7/21/2016
  1. 寫出程序運行的結果?
for(i=0, j=0; i<10, j<6; i++, j++){
k = i + j;}
結果:10
  1. 閱讀以下代碼,請分析出結果:
	var arr = new Array(1 ,3 ,5);
	arr[4]='z';
	arr2 = arr.reverse();
	arr3 = arr.concat(arr2);
	alert(arr3);
彈出提示對話框:z,,5,3,1,z,,5,3,1
  1. 寫出簡單描述html標籤(不帶屬性的開始標籤和結束標籤)的正則表達式,並將以下字符串中的html標籤去除掉
var str =<div>這裏是div<p>裏面的段落</p></div>;
<scripttype=”text/javascript”>
var reg = /<\/?\w+\/?>/gi;
var str =<div>這裏是div<p>裏面的段落</p></div>;
alert(str.replace(reg,”"));
</script>
截取字符串abcdefg的efg
alert('abcdefg'.substring(4));
  1. 列舉瀏覽器對象模型BOM裏常用的至少4個對象,並列舉window對象的常用方法至少5個

對象:window, document, location, screen, history, navigator
方法:alert(), confirm(), prompt(), open(), close()

  1. 簡述列舉文檔對象模型DOM裏document的常用的查找訪問節點的方法並做簡單說明

document.getElementById 根據元素id查找元素
document.getElementByName 根據元素name查找元素
document.getElementTagName 根據指定的元素名查找元素

  1. 簡述創建函數的幾種方式
第一種(函數聲明): 
function sum1(num1,num2){
   return num1+num2;
}
第二種(函數表達式):
var sum2 = function(num1,num2){
   return num1+num2;
}
第三種(函數對象方式):
var sum3 = new Function("num1","num2","return num1+num2");
  1. Javascript創建對象的幾種方式?
1var obj = {};(使用json創建對象)
如:obj.name = '張三';​
obj.action = function ()
{
alert('吃飯');
};
2var obj = new Object();(使用Object創建對象)
如:obj.name = '張三';​
obj.action = function ()
{
alert('吃飯');
};
3、​通過構造函數創建對象。
(1)、使用this關鍵字​
如:var obj = function (){
this.name ='張三';
this.age = 19;
this.action = function ()
{
alert('吃飯');
};
}
(2)、使用prototype關鍵字
如:function obj (){}
​       obj.prototype.name ='張三';
​obj.prototype.action=function ()
{
alert('吃飯');
};
4、使用內置對象創建對象。
如:var str = new String("實例初始化String");
var str1 = "直接賦值的String";
var func = new Function("x","alert(x)");//示例初始化func
var obj = new Object();//示例初始化一個Object
  1. iframe的優缺點?

優點:

  1. 解決加載緩慢的第三方內容如圖標和廣告等的加載問題
  2. Security sandbox
  3. 並行加載腳本
    缺點:
  4. iframe會阻塞主頁面的Onload事件
  5. 即時內容爲空,加載也需要時間
  6. 沒有語意
  1. 請你談談Cookie的弊端?
  1. Cookie數量和長度的限制。每個domain最多只能有20條cookie,每個cookie長度不能超過4KB,否則會被截掉。
  2. 安全性問題。如果cookie被人攔截了,那人就可以取得所有的session信息。即使加密也與事無補,因爲攔截者並不需要知道cookie的意義,他只要原樣轉發cookie就可以達到目的了。
  3. 有些狀態不可能保存在客戶端。例如,爲了防止重複提交表單,我們需要在服務器端保存一個計數器。如果我們把這個計數器保存在客戶端,那麼它起不到任何作用。
  1. js延遲加載的方式有哪些?
  1. defer和async
  2. 動態創建DOM方式(創建script,插入到DOM中,加載完畢後callBack)
  3. 按需異步載入js
  1. 哪些操作會造成內存泄漏?

內存泄漏指任何對象在您不再擁有或需要它之後仍然存在。
垃圾回收器定期掃描對象,並計算引用了每個對象的其他對象的數量。如果一個對象的引用數量爲 0(沒有其他對象引用過該對象),或對該對象的惟一引用是循環的,那麼該對象的內存即可回收。

  1. setTimeout 的第一個參數使用字符串而非函數的話,會引發內存泄漏。
  2. 閉包
  3. 控制檯日誌
  4. 循環(在兩個對象彼此引用且彼此保留時,就會產生一個循環)
  1. 判斷一個字符串中出現次數最多的字符,統計這個次數
var str = 'asdfssaaasasasasaa';
var json = {};
for (var i = 0; i < str.length; i++) {
        if(!json[str.charAt(i)]){
                json[str.charAt(i)] = 1;
        }else{
                json[str.charAt(i)]++;
        }
};
var iMax = 0;
var iIndex = '';
for(var i in json){
        if(json[i]>iMax){
                iMax = json[i];
                iIndex = i;
        }
}
alert('出現次數最多的是:'+iIndex+'出現'+iMax+'次');
  1. 寫一個獲取非行間樣式的函數
function getStyle(obj,attr,value)
{
	if(!value)
	{
		if(obj.currentStyle)
		{
			return obj.currentStyle(attr);
		}
		else{
			obj.getComputedStyle(attr,false);
		}
	}	
	else
	{
		obj.style[attr] = value;
	}
}
  1. 閉包是什麼,有什麼特性,對頁面有什麼影響
答:當內部函數使用了外部函數的局部變量時, 產生的一個對象(包含了所有使用了的變量)
		作用: 在函數執行完後, 局部變量還會存在
	function outer(){
    var num = 1;
    function inner(){
        var n = 2;
        alert(n + num);
    }
    return inner;
}
var r = outer();
r();
  1. 解釋jsonp的原理,以及爲什麼不是真正的ajax

動態創建script標籤,回調函數
Ajax是頁面無刷新請求數據操作

  1. 字符串反轉,如將 ‘12345678’ 變成 ‘87654321’
//思路:先將字符串轉換爲數組 split(),利用數組的反序函數 reverse()顛倒數組,再利用 jion() 轉換爲字符串
var str = '12345678';
str = str.split('').reverse().join('');
將數字 12345678 轉化成 RMB形式 如: 12,345,678 
//思路:先將數字轉爲字符, str= str + '' ;
//利用反轉函數,每三位字符加一個 ','最後一位不加; re()是自定義的反轉函數,最後再反轉回去!
function re(str) {
    str += '';
    return str.split("").reverse().join("");
}

function toRMB(num) {
	var tmp='';
    for (var  i  =  1;  i  <=  re(num).length;  i++) {    
        tmp  +=  re(num)[i  -  1];    
        if (i  %  3  ==  0  &&  i  !=  re(num).length) {        
            tmp  +=  ',';    
        }
    }
    return re(tmp);
}
  1. 生成5個不同的隨機數;
//思路:5個不同的數,每生成一次就和前面的所有數字相比較,如果有相同的,則放棄當前生成的數字!
var num1 = [];
for(var i = 0; i < 5; i++){
    num1[i] = Math.floor(Math.random()*10) + 1; //範圍是 [1, 10]
    for(var j = 0; j < i; j++){
        if(num1[i] == num1[j]){
            i--;
        }
    }
}
  1. 去掉數組中重複的數字 方法一;
//思路:每遍歷一次就和之前的所有做比較,不相等則放入新的數組中!
//這裏用的原型 個人做法;
Array.prototype.unique = function(){
    var len = this.length,
        newArr = [],
        flag = 1;
    for(var i = 0; i < len; i++, flag = 1){
        for(var j = 0; j < i; j++){
            if(this[i] == this[j]){
                flag = 0;        //找到相同的數字後,不執行添加數據
            }
        }
        flag ? newArr.push(this[i]) : '';
    }
    return newArr;
}
方法二:
var arr=[1,2,3,3,4,4,5,5,6,1,9,3,25,4];
Array.prototype.unique2 = function()
{
	var n = []; //一個新的臨時數組
	for(var i = 0; i < this.length; i++) //遍歷當前數組
	{
		//如果當前數組的第i已經保存進了臨時數組,那麼跳過,
		//否則把當前項push到臨時數組裏面
		if (n.indexOf(this[i]) == -1) n.push(this[i]);
	}
	return n;
}
var newArr2=arr.unique2(arr);
alert(newArr2); //輸出1,2,3,4,5,6,9,25
階乘函數;
//原型方法
Number.prototype.N = function(){
    var re = 1;
    for(var i = 1; i <= this; i++){
        re *= i;
    }
    return re;
}
var num = 5;
alert(num.N());
  1. javascript 中的垃圾回收機制?

在Javascript中,如果一個對象不再被引用,那麼這個對象就會被GC回收。如果兩個對象互相引用,而不再 被第3者所引用,那麼這兩個互相引用的對象也會被回收。因爲函數a被b引用,b又被a外的c引用,這就是爲什麼 函數a執行後不會被回收的原因。

  1. 看題做答:
function f1(){
    var tmp = 1;
    this.x = 3;
    console.log(tmp);    //A
    console.log(this.x)//B
}
var obj = new f1(); //1
console.log(obj.x)     //2
console.log(f1());        //3
        這道題讓我重新認識了對象和函數,首先看代碼(1),這裏實例話化了 f1這個類。相當於執行了 f1函數。所以這個時候 A 會輸出 1, 而 B 這個時候的 this 代表的是 實例化的當前對象 obj B 輸出 3.。 代碼(2)毋庸置疑會輸出 3, 重點 代碼(3)首先這裏將不再是一個類,它只是一個函數。那麼 A輸出 1B呢?這裏的this 代表的其實就是window對象,那麼this.x 就是一個全局變量 相當於在外部 的一個全局變量。所以 B 輸出 3。最後代碼由於f沒有返回值那麼一個函數如果沒返回值的話,將會返回 underfined ,所以答案就是 : 13313, underfined 。
下面輸出多少?
var o1 = new Object();
var o2 = o1;
o2.name = "CSSer";
console.log(o1.name);

如果不看答案,你回答真確了的話,那麼說明你對javascript的數據類型瞭解的還是比較清楚了。js中有兩種數據類型,分別是:基本數據類型和引用數據類型(object Array)。對於保存基本類型值的變量,變量是按值訪問的,因爲我們操作的是變量實際保存的值。對於保存引用類型值的變量,變量是按引用訪問的,我們操作的是變量值所引用(指向)的對象。答案就清楚了:  //CSSer;
再來一個
 function changeObjectProperty (o) {
    o.siteUrl = "http://www.csser.com/";
    o = new Object();
    o.siteUrl = "http://www.popcg.com/";
}
var CSSer = new Object();
changeObjectProperty(CSSer);
console.log(CSSer.siteUrl); // “http://www.csser.com/”
如果CSSer參數是按引用傳遞的,那麼結果應該是"http://www.popcg.com/",但實際結果卻仍是"http://www.csser.com/"。事實是這樣的:在函數內部修改了引用類型值的參數,該參數值的原始引用保持不變。我們可以把參數想象成局部變量,當參數被重寫時,這個變量引用的就是一個局部變量,局部變量的生存期僅限於函數執行的過程中,函數執行完畢,局部變量即被銷燬以釋放內存。    
    (補充:內部環境可以通過作用域鏈訪問所有的外部環境中的變量對象,但外部環境無法訪問內部環境。每個環境都可以向上搜索作用域鏈,以查詢變量和函數名,反之向下則不能。)
  1. a輸出多少?
	var a = 6;
setTimeout(function () {    
    var a = 666;
    alert(a);      // 輸出666,
}, 1000);
因爲var a = 666;定義了局部變量a,並且賦值爲666,根據變量作用域鏈,
全局變量處在作用域末端,優先訪問了局部變量,從而覆蓋了全局變量 。
	var a = 6;
setTimeout(function () {    
    alert(a);      // 輸出undefined 
    var a = 666;
}, 1000);
因爲var a = 666;定義了局部變量a,同樣覆蓋了全局變量,但是在alert(a);之前
a並未賦值,所以輸出undefined。

	var a = 6; 
setTimeout(function(){
    alert(a);
    var a = 66; 
}, 1000);
a = 666; 
alert(a); 
// 666, undefined;
記住: 異步處理,一切OK 聲明提前
  1. 看程序,寫結果
	function setN(obj){
    obj.name='屌絲';
    obj = new Object(); 
    obj.name = '腐女';
};
var per = new Object();
setN(per);
alert(per.name);  //屌絲 內部
  1. 精度問題: JS 精度不能精確到 0.1 所以 。。。。同時存在於值和差值中
var n = 0.3,m = 0.2, i = 0.2, j = 0.1;
alert((n - m) == (i - j)); //false
alert((n-m) == 0.1); //false
alert((i-j)==0.1); //true
加減運算
alert('5'+3); //53 string
alert('5'+'3'); //53 string
alert('5'-3); //2 number
alert('5'-'3'); //2 number
  1. 爲什麼不能定義1px左右的div容器?

IE6下這個問題是因爲默認的行高造成的,解決的方法也有很多,例如:
overflow:hidden | zoom:0.08 | line-height:1px

  1. 結果是什麼?
function foo(){
    foo.a = function(){alert(1)}; 
    this.a = function(){alert(2)};
    a = function(){alert(3)};
    var a = function(){alert(4)};
}; 
foo.prototype.a = function(){alert(5)};
foo.a = function(){alert(6)};
foo.a(); //6
var obj = new foo();
obj.a(); //2
foo.a(); //1
輸出結果
var a = 5; 
function test(){
    a = 0; 
    alert(a); 
    alert(this.a); //沒有定義 a這個屬性
    var a; 
    alert(a)
}
test(); // 0, 5, 0
new test(); // 0, undefined, 0 //由於類它自身沒有屬性a, 所以是undefined
  1. 計算字符串字節數:
new function(s){ 
     if(!arguments.length||!s) return null;  
     if(""==s) return 0;     
     var l=0;
     for(var i=0;i<s.length;i++){        
         if(s.charCodeAt(i)>255) l+=2; else l+=1;  //charCodeAt()得到的是unCode碼   
     }     //漢字的unCode碼大於 255bit 就是兩個字節
     alert(l); 
}("hello world!");
結果是:
	var bool = !!2; alert(bool)//true;
雙向非操作可以把字符串和數字轉換爲布爾值。
  1. 匹配輸入的字符:第一個必須是字母或下劃線開頭,長度5-20
var reg = /^[a-zA-Z_][a-zA-Z0-9_]{5,20}/,
            name1 = 'leipeng',
            name2 = '0leipeng',
            name3 = '你好leipeng',
            name4 = 'hi';
     
        alert(reg.test(name1));
        alert(reg.test(name2));
        alert(reg.test(name3));
        alert(reg.test(name4));
  1. 如何在HTML中添加事件,幾種方法?

1、標籤之中直接添加 οnclick=“fun()”;
2、JS添加 Eobj.onclick = method;
3、綁定事件 IE: obj.attachEvent(‘onclick’, method);
FF: obj.addEventListener(‘click’, method, false);
BOM對象有哪些,列舉window對象?
1、window對象 ,是JS的最頂層對象,其他的BOM對象都是window對象的屬性;
2、document對象,文檔對象;
3、location對象,瀏覽器當前URL信息;
4、navigator對象,瀏覽器本身信息;
5、screen對象,客戶端屏幕信息;
6、history對象,瀏覽器訪問歷史信息;

  1. 請問代碼實現 outerHTML
//說明:outerHTML其實就是innerHTML再加上本身;
	Object.prototype.outerHTML = function(){
        var innerCon = this.innerHTML, //獲得裏面的內容
            outerCon = this.appendChild(innerCon); //添加到裏面
        alert(outerCon); 
    }
    演示代碼:
 <!doctype html>
 <html>
  <head>
    <meta charset="UTF-8">
    <title>Document</title>
  </head>
  <body>
    <div id="outer">
       hello
    </div>
  <script>
    Object.prototype.outerHTML = function(){
    var innerCon = this.innerHTML, //獲得裏面的內容
    outerCon = this.appendChild(innerCon); //添加到裏面
    alert(outerCon); 
      }
    function $(id){
   return document.getElementById(id);
   }
   alert($('outer').innerHTML);
   alert($('outer').outerHTML);
  </script>
 </body>
 </html>
  1. JS中的簡單繼承 call方法!
//定義個父母類,注意:類名都是首字母大寫的哦!
  function Parent(name, money){
            this.name = name;
            this.money = money;
            this.info = function(){
                alert('姓名: '+this.name+' 錢: '+ this.money);
            }
        }
        //定義孩子類
        function Children(name){
            Parent.call(this, name); //繼承 姓名屬性,不要錢。  
            this.info = function(){
                alert('姓名: '+this.name);
            }
        }
        //實例化類
        var per = new Parent('parent', 800000000000);
        var chi = new Children('child');
        per.info();
        chi.info();
  1. bind(), live(), delegate()的區別
bind: 綁定事件,對新添加的事件不起作用,方法用於將一個處理程序附加到每個匹配元素的事件上並返回jQuery對象。
live: 方法將一個事件處理程序附加到與當前選擇器匹配的所有元素(包含現有的或將來添加的)的指定事件上並返回jQuery對象。
delegate: 方法基於一組特定的根元素將處理程序附加到匹配選擇器的所有元素(現有的或將來的)的一個或多個事件上。  
  1. 看下列代碼輸出什麼?
var foo = "11"+2-"1";
console.log(foo);
console.log(typeof foo);
執行完後foo的值爲111,foo的類型爲Number。
看下列代碼,輸出什麼? 
var a = new Object();
a.value = 1;
b = a;
b.value = 2;
alert(a.value);
執行完後輸出結果爲2
  1. 怎樣實現兩欄等高?
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
</head>
<body>
    <div id="container" style="display: table;width: 100%;">
        <div id="left" style="background-color: red;display: table-cell;">
            內容<br/>
            內容<br/>
            內容<br/>
            內容<br/>
            內容<br/>
            內容<br/>
        </div>
        <div style="display:table-cell;"></div>
        <div id="right" style="background-color: blue;display: table-cell">
            內容
        </div>
    </div>
</body>
</html>
  1. 使用js實現這樣的效果:在文本域裏輸入文字時,當按下enter鍵時不換行,而是替換成“{{enter}}”,(只需要考慮在行尾按下enter鍵的情況).
<html>
<head>
    <script>
        function back(ele,event){
            event = event || window.event;
            if(event.keyCode==13){
                event.returnValue = false;
                ele.value+="{{enter}}" 
                return false;
            }
        }
    </script>
</head>
<body>
<textarea rows="3" cols="40" id="te" onkeypress="back(this,event);"></textarea>
</body>
</html>
  1. 以下代碼中end字符串什麼時候輸出
var t=true;
setTimeout(function(){
   console.log(123);
   t=false;
   },1000);
while(t){}
console.log(‘end’);
永遠不輸出
  1. specify(‘hello,world’)//=>’h,e,l,l,o,w,o,r,l,d’實現specify函數
function specify(str){
    var tempArray =  Array.prototype.filter.call(str,function(value,index,array){
        return value >= 'A' &&  value <= 'z' && value != "_";
    });
    return tempArray.join(",");
}

console.log(specify("hedd____df*(%$#a !!!))))))llo,Wo@@@r        ld")); //h,e,l,l,o,W,o,r,l,d
  1. 簡述readyonly與disabled的區別

ReadOnly和Disabled的作用是使用戶不能夠更改表單域中的內容.
但是二者還是有着一些區別的:
1、Readonly只針對input(text/password)和textarea有效,而disabled對於所有的表單元素有效,包括select,radio,checkbox,button等。
2、在表單元素使用了disabled後,我們將表單以POST或者GET的方式提交的話,這個元素的值不會被傳遞出去,而readonly會將該值傳遞出去
請儘可能詳盡的解釋ajax的工作原理
Ajax的工作原理相當於在用戶和服務器之間加了—箇中間層,使用戶操作與服務器響應異步化。這樣把以前的一些服務器負擔的工作轉嫁到客戶端,利於客戶端閒置的處理能力來處理,減輕服務器和帶寬的負擔,從而達到節約ISP的空間及帶寬租用成本的目的。

簡單來說通過XmlHttpRequest對象來向服務器發異步請求,從服務器獲得數據,然後用javascript來操作DOM而更新頁面。這其中最關鍵的一步就是從服務器獲得請求數據。要清楚這個過程和原理,我們必須對 XMLHttpRequest有所瞭解。

  1. 爲什麼擴展javascript內置對象不是好的做法?

因爲你不知道哪一天瀏覽器或javascript本身就會實現這個方法,而且和你擴展的實現有不一致的表現。到時候你的javascript代碼可能已經在無數個頁面中執行了數年,而瀏覽器的實現導致所有使用擴展原型的代碼都崩潰了。。。

  1. 有下面這樣一段HTML結構,使用css實現這樣的效果:
    左邊容器無論寬度如何變動,右邊容器都能自適應填滿父容器剩餘的寬度。
<div class=”warp”>
<div class=”left”></div>
<div class=”right”></div>
</div>

90.下面這段代碼想要循環輸出結果01234,請問輸出結果是否正確,如果不正確,請說明爲什麼,並修改循環內的代碼使其輸出正確結果

for(var i=0;i<5;++i){
	setTimeout(function(){
			console.log(i+’’);
		},100*i);
}
  1. 關於IE的window對象表述正確的有:(ACD)

A. window.opener屬性本身就是指向window對象
B. window.reload()方法可以用來刷新當前頁面 應該是location.reload或者window.location.reload
C. window.location=”a.html”和window.location.href=”a.html”的作用都是把當前頁面替換成a.html頁面
D. 定義了全局變量g;可以用window.g的方式來存取該變量

  1. 下面正確的是 A

A: 跨域問題能通過JsonP方案解決
B:不同子域名間僅能通過修改window.name解決跨域 還可以通過script標籤src jsonp等h5 Java split等
C:只有在IE中可通過iframe嵌套跨域
D:MediaQuery屬性是進行視頻格式檢測的屬性是做響應式的

93.錯誤的是 c

A: Ajax本質是XMLHttpRequest
B: 塊元素實際佔用的寬度與它的width、border、padding屬性有關,與background無關
C: position屬性absolute、fixed、—relative—會使文檔脫標
D: float屬性left也會使div脫標
答案C:relative不會脫離文檔流

  1. 三種彈窗的單詞以及三種彈窗的功能
1.alert  
//彈出對話框並輸出一段提示信息  
    function ale() {  
        //彈出一個對話框  
        alert("提示信息!");  
  
    }  
  
2.confirm
    //彈出一個詢問框,有確定和取消按鈕  
    function firm() {  
        //利用對話框返回的值 (true 或者 false)  
        if (confirm("你確定提交嗎?")) {  
            alert("點擊了確定");  
        }  
        else {  
            alert("點擊了取消");  
        }  
  
    }  
  
3.prompt
    //彈出一個輸入框,輸入一段文字,可以提交  
    function prom() {  
        var name = prompt("請輸入您的名字", ""); //將輸入的內容賦給變量 name ,  
  
        //這裏需要注意的是,prompt有兩個參數,前面是提示的話,後面是當對話框出來後,在對話框裏的默認值  
        if (name)//如果返回的有內容  
        {  
            alert("歡迎您:" + name)  
        }  
    }
  1. 只允許使用 + - * / 和 Math.* ,求一個函數 y = f(x, a, b);當x > 100 時返回 a 的值,否則返回 b 的值,不能使用 if else 等條件語句,也不能使用|,?:,數組。
function f(x, a, b) {
    var temp = Math.ceil(Math.min(Math.max(x - 100, 0), 1));
   
    return a * temp + b * (1 - temp);
}
console.log(f(-10, 1, 2));
  1. JavaScriptalert(0.4*0.2);結果是多少?和你預期的一樣嗎?如果不一樣該如何處理?

有誤差,應該比準確結果偏大。 一般我會將小數變爲整數來處理。當前之前遇到這個問題時也上網查詢發現有人用try catch return寫了一個函數,當然原理也是一致先轉爲整數再計算。

  1. jQuery框架中$.ajax()的常用參數有哪些?寫一個post請求並帶有發送數據和返回數據的樣例
async是否異步
url請求地址
contentType發送信息至服務器時內容編碼類型
data發送到服務器的數據
dataType預期服務器返回的數據類型
type請求類型
success請求成功回調函數
error請求失敗回調函數

$.ajax({
            url: "/jquery/test1.txt",
            type: 'post',
            data: {
                id: 1
            },
            success: function(data) {
                alert(data);
            }
        }
  1. 閉包:下面這個ul,如何點擊每一列的時候alert其index?
<ul id="test">
    <li>這是第一條</li>
    <li>這是第二條</li>
    <li>這是第三條</li>
</ul>
//js
 window.onload = function() {
        var lis = document.getElementById('test').children;
        for (var i = 0; i < lis.length; i++) {
            lis[i].onclick = (function(i) {
                return function() {
                    alert(i)
                };
            })(i);
        };
    }
  1. 列出3條以上ff和IE的腳本兼容問題

(1) window.event:
表示當前的事件對象,IE有這個對象,FF沒有,FF通過給事件處理函數傳遞事件對象

(2) 獲取事件源
IE用srcElement獲取事件源,而FF用target獲取事件源

(3) 添加,去除事件
IE:element.attachEvent(“onclick”, function) element.detachEvent(“onclick”, function)
FF:element.addEventListener(“click”, function, true) element.removeEventListener(“click”, function, true)

(4) 獲取標籤的自定義屬性
IE:div1.value或div1[“value”]
FF:可用div1.getAttribute(“value”)

  1. 寫一個函數可以計算 sum(5,0,-5);輸出0; sum(1,2,3,4);輸出10;
function sum() {
    var result = 0;
    var arr = arguments;
    for (var i = 0; i < arr.length; i++) {
        var num = arguments[i];
        if (typeof num=='number') {
            result += num;
        };
    };
    return result;
}

101.《正則》寫出正確的正則表達式匹配固話號,區號3-4位,第一位爲0,中橫線,7-8位數字,中橫線,3-4位分機號格式的固話號

^[0]\d{2,3}-\d{7,8}-\d{3,4}$

102.《算法》 一下A,B可任選一題作答,兩題全答加分

A:農場買了一隻羊,第一年是小羊,第二年底生一隻,第三年不生,第四年底再生一隻,第五年死掉。
B:寫出代碼對下列數組去重並從大到小排列{5,2,3,6,8,6,5,4,7,1,9}
function fn(arr){
    for (var i = 0; i < arr.length-1; i++) {
        for (var j = 0; j < arr.length-1-i; j++) {
            if(arr[j]<arr[j+1]){
                var temp = arr[j];
                arr[j]=arr[j+1];
                arr[j+1]=temp;
            }

        }

    }
    for (i = 0; i < arr.length; i++) {
        var c=arr[i];
        for (var s = i+1; s < arr.length; s++) {
            if(arr[s]==c){
                //debugger;
                arr.splice(s,1);
                s--;
            }

        }
    }

    return arr;
}
console.log(fn([5,2,3,6,8,6,5,4,7,1,9]).toString());
  1. 請寫出一個程序,在頁面加載完成後動態創建一個form表單,並在裏面添加一個input對象並給它任意賦值後義post方式提交到:http://127.0.0.1/save.php
window.onload=function(){
    var form=document.createElement("form");
    form.setAttribute("method", "post");
    form.setAttribute("action", "http://127.0.0.1/save.php");
    var input=document.createElement("input");
    form.appendChild(input);
    document.body.appendChild(form);
    input.value="cxc";
    form.submit();//提交表單
}
  1. 用JavaScript實現冒泡排序。數據爲23、45、18、37、92、13、24
//升序算法
function sort(arr){
    for (var i = 0; i <arr.length; i++) {
        for (var j = 0; j <arr.length-i; j++) {
            if(arr[j]>arr[j+1]){
                var c=arr[j];//交換兩個變量的位置
                arr[j]=arr[j+1];
                arr[j+1]=c;
            }
        };
    };
    return arr.toString();
}
console.log(sort([23,45,18,37,92,13,24]));
  1. 下列JavaScript代碼執行後,依次alert的結果是
(function test(){
      var a=b=5;
      alert(typeof a);
      alert(typeof b);
})();
alert(typeof a);
alert(typeof b);
答案:number
number
undefined
number
  1. 下列JavaScript代碼執行後,iNum的值是
var iNum = 0;
for(var i = 1; i< 10; i++){
     if(i % 5 == 0){
         continue;
    }
    iNum++;
}
答案:8
  1. 輸出結果是多少?
 1) var a;
var b = a * 0;
if (b == b) {
          console.log(b * 2 + "2" - 0 + 4);
} else {
          console.log(!b * 2 + "2" - 0 + 4);
}
答案:26
 <script>
        var a = 1;
</script>
<script>
var a;
var b = a * 0;
if (b == b) {
        console.log(b * 2 + "2" - 0 + 4);
} else {
        console.log(!b * 2 + "2" - 0 + 4);
}
</script>
答案:6

3var t = 10;
function test(t){
       var t = t++;
}test(t);
console.log(t);
答案:10

4var t = 10;
function test(test){
      var t = test++;
}test(t);
console.log(t);
答案:10

6var t = 10;
function test(test){
       t = test++;
}test(t);
console.log(t);
答案:10

7var t = 10;
function test(test){
      t = t + test;
      console.log(t);
      var t = 3;
}test(t);
console.log(t);
答案:NaN  10

8var a;
var b = a / 0;
if (b == b) {
        console.log(b * 2 + "2" - 0 + 4);
} else {
        console.log(!b * 2 + "2" - 0 + 4);
}
答案:26

9<script>
      var a = 1;
</script>
<script>
    var a;
    var b = a / 0;
    if (b == b) {
        console.log(b * 2 + "2" + 4);
    } else {
        console.log(!b * 2 + "2" + 4);
    }
</script>
答案:Infinity24
  1. 用程序實現找到html中id名相同的元素?
<body>
    <form id='form1'>
        <div id='div1'></div>
        <div id='div2'></div>
        <div id='div3'></div>
        <div id='div4'></div>
        <div id='div5'></div>
        <div id='div3'>id名重複的元素</div>
    </form>
</body>
var nodes=document.querySelectorAll("#form1>*");
for(var i=0,len=nodes.length;i<len;i++){
    var attr=nodes[i].getAttribute("id");
    var s=1;
    for(var j=i+1;j<len;j++){
        if(nodes[j].getAttribute("id")==attr){
            s++;
            alert("id爲:"+attr+"的元素出現"+s+"次");
        }
    }
}
  1. 下列JavaScript代碼執行後,運行的結果是
<button id='btn'>點擊我</button>
var btn = document.getElementById('btn');
var handler = {
    id: '_eventHandler',
    exec: function(){
        alert(this.id);
    }
}
btn.addEventListener('click', handler.exec);
答案:”btn”
  1. 下列JavaScript代碼執行後,依次alert的結果是
var obj = {proto: {a:1,b:2}};
function F(){};
F.prototype = obj.proto;
var f = new F();
obj.proto.c = 3;
obj.proto = {a:-1, b:-2};
alert(f.a);
alert(f.c);
delete F.prototype['a'];
alert(f.a);
alert(obj.proto.a);
答案:
1
3
undefined
-1
  1. 下列JavaScript代碼執行後的效果是
<ul id='list'>
    <li>item</li>
    <li>item</li>
    <li>item</li>
    <li>item</li>
    <li>item</li>
</ul>
var items = document.querySelectorAll('#list>li');
for(var i = 0;i < items.length; i++){
     setTimeout(function(){
           items[i].style.backgroundColor = '#fee';
    }, 5);
}
答案:報錯,因爲i一直等於5,items[i]獲取不到元素
  1. 下列JavaScript代碼執行後的li元素的數量是
<ul>
    <li>Item</li>
    <li></li>
    <li></li>
    <li>Item</li>
    <li>Item</li>
</ul>
 
var items = document.getElementsByTagName('li');
for(var i = 0; i< items.length; i++){
    if(items[i].innerHTML == ''){
        items[i].parentNode.removeChild(items[i]);
    }
}
  1. 下列控制檯都輸出什麼
1題:
function setName(){
	name="張三";
}
setName();
console.log(name);
答案:"張三"2題:
//考點:1、變量聲明提升 2、變量搜索機制
var a=1;
function test(){
	console.log(a);
	var a=1;
}
test();
答案:undefined
第3題:
var b=2;
function test2(){
	window.b=3;
	console.log(b);
}
test2();
答案:34題:
c=5;//聲明一個全局變量c 
function test3(){
	window.c=3;
	console.log(c);		//答案:undefined,原因:由於此時的c是一個局部變量c,並且沒有被賦值
	var c;
	console.log(window.c);//答案:3,原因:這裏的c就是一個全局變量c
}
test3();5題:
var arr = [];
arr[0]  = 'a';
arr[1]  = 'b';
arr[10] = 'c';
alert(arr.length);	//答案:11
console.log(arr[5]);	//答案:undefined6題:
var a=1;
console.log(a++);		//答案:1
console.log(++a);		//答案:37題:
console.log(null==undefined);	//答案:true
console.log("1"==1);		//答案:true,因爲會將數字1先轉換爲字符串1
console.log("1"===1);		//答案:false,因爲數據類型不一致8題:
typeof 1;		"number"
typeof "hello";		"string"
typeof /[0-9]/;		"object"
typeof {};		"object"
typeof null;		"object"
typeof undefined;	"undefined"
typeof [1,2,3];		"object"
typeof function(){};	//"function"9題:
parseInt(3.14);			//3
parseFloat("3asdf");		//3
parseInt("1.23abc456");
parseInt(true);//"true" NaN10題:
//考點:函數聲明提前
function bar() {
    return foo;
    foo = 10;
    function foo() {}
    //var foo = 11;
}
alert(typeof bar());//"function"11題: 
//考點:函數聲明提前
var foo = 1;
function bar() {
	foo = 10;
	return;
	function foo() {}
}
bar();
alert(foo);//答案:112題:
console.log(a);//是一個函數
var a = 3;
function a(){}
console.log(a);////313題:
//考點:對arguments的操作
function foo(a) {
    arguments[0] = 2;
    alert(a);//答案:2,因爲:a、arguments是對實參的訪問,b、通過arguments[i]可以修改指定實參的值
}
foo(1);14題:
function foo(a) {
    alert(arguments.length);//答案:3,因爲arguments是對實參的訪問
}
foo(1, 2, 3);15bar();//報錯
var foo = function bar(name) {
	console.log("hello"+name);
	console.log(bar);
};
//alert(typeof bar);
foo("world");//"hello"
console.log(bar);//undefined
console.log(foo.toString());
bar();//報錯16題: 
function test(){
	console.log("test函數");
}
setTimeout(function(){
	console.log("定時器回調函數");
}, 0)
test();
結果:
test函數
定時器回調函數

114.Ajax 是什麼? 如何創建一個Ajax?

Ajax並不算是一種新的技術,全稱是asychronous javascript and xml,可以說是已有技術的組合,主要用來實現客戶端與服務器端的異步通信效果,實現頁面的局部刷新,早期的瀏覽器並不能原生支持ajax,可以使用隱藏幀(iframe)方式變相實現異步效果,後來的瀏覽器提供了對ajax的原生支持
使用ajax原生方式發送請求主要通過XMLHttpRequest(標準瀏覽器)、ActiveXObject(IE瀏覽器)對象實現異步通信效果
基本步驟:
var xhr =null;//創建對象 
if(window.XMLHttpRequest){
	xhr = new XMLHttpRequest();
}else{
	xhr = new ActiveXObject("Microsoft.XMLHTTP");
}
     xhr.open(“方式”,”地址”,”標誌位”);//初始化請求 
     xhr.setRequestHeader(“”,””);//設置http頭信息 
     xhr.onreadystatechange =function(){}//指定回調函數 
     xhr.send();//發送請求 
js框架(jQuery/EXTJS等)提供的ajax  API對原生的ajax進行了封裝,熟悉了基礎理論,再學習別的框架就會得心應手,好多都是換湯不換藥的內容 
下的服務器負載。
  1. 一個頁面從輸入 URL 到頁面加載顯示完成,這個過程中都發生了什麼?

分爲4個步驟:

  1. 當發送一個 URL 請求時,不管這個 URL 是 Web 頁面的 URL 還是 Web 頁面上每個資源的 URL,瀏覽器都會開啓一個線程來處理這個請求,同時在遠程 DNS 服務器上啓動一個 DNS 查詢。這能使瀏覽器獲得請求對應的 IP 地址。
  2. 瀏覽器與遠程 Web 服務器通過 TCP 三次握手協商來建立一個 TCP/IP 連接。該握手包括一個同步報文,一個同步-應答報文和一個應答報文,這三個報文在 瀏覽器和服務器之間傳遞。該握手首先由客戶端嘗試建立起通信,而後服務器應答並接受客戶端的請求,最後由客戶端發出該請求已經被接受的報文。
  3. 一旦 TCP/IP 連接建立,瀏覽器會通過該連接向遠程服務器發送 HTTP 的 GET 請求。遠程服務器找到資源並使用 HTTP 響應返回該資源,值爲 200 的 HTTP 響應狀態表示一個正確的響應。
  4. 此時,Web 服務器提供資源服務,客戶端開始下載資源。

116.請說出三種減低頁面加載時間的方法

1、壓縮css、js文件
2、合併js、css文件,減少http請求
3、外部js、css文件放在最底下
4、減少dom操作,儘可能用變量替代不必要的dom操作

117.HTTP狀態碼都有那些。

200 OK //客戶端請求成功
400 Bad Request //客戶端請求有語法錯誤,不能被服務器所理解
403 Forbidden //服務器收到請求,但是拒絕提供服務
404 Not Found //請求資源不存在,輸入了錯誤的URL
500 Internal Server Error //服務器發生不可預期的錯誤
503 Server Unavailable //服務器當前不能處理客戶端的請求,一段時間後可能恢復正常

  1. 實現一個函數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;
}
//方法二:
     /**
     * 克隆一個對象
     * @param Obj
     * @returns
     */
    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;   
        }   
    }
  1. 如何消除一個數組裏面重復的元素?
var arr=[1,2,3,3,4,4,5,5,6,1,9,3,25,4];
        function deRepeat(){
            var newArr=[];
            var obj={};
            var index=0;
            var l=arr.length;
            for(var i=0;i<l;i++){
                if(obj[arr[i]]==undefined)
                  {
                    obj[arr[i]]=1;
                    newArr[index++]=arr[i];
                  }
                else if(obj[arr[i]]==1)
                  continue;
            }
            return newArr;
        }
        var newArr2=deRepeat(arr);
        alert(newArr2); //輸出1,2,3,4,5,6,9,25
  1. 小賢是一條可愛的小狗(Dog),它的叫聲很好聽(wow),每次看到主人的時候就會乖乖叫一聲(yelp)。從這段描述可以得到以下對象:
function Dog() {
      this.wow = function() {
               alert(’Wow’);
      }
      this.yelp = function() {
              this.wow();
      }
}
小芒和小賢一樣,原來也是一條可愛的小狗,可是突然有一天瘋了(MadDog),一看到人就會每隔半秒叫一聲(wow)地不停叫喚(yelp)。請根據描述,按示例的形式用代碼來實。(繼承,原型,setInterval)

	function MadDog() {
    this.yelp = function() {
          var self = this;          
          setInterval(function() {
                self.wow();      
          }, 500);
      }
}
MadDog.prototype = new Dog();         
//for test
var dog = new Dog();
dog.yelp();
var madDog = new MadDog();
madDog.yelp();
  1. 定義一個log方法,讓它可以代理console.log的方法。
可行的方法一:
function log(msg) {
    console.log(msg);
}
log("hello world!") // hello world!
如果要傳入多個參數呢?顯然上面的方法不能滿足要求,所以更好的方法是:
function log(){
    console.log.apply(console, arguments);
};
到此,追問apply和call方法的異同。
對於apply和call兩者在作用上是相同的,即是調用一個對象的一個方法,以另一個對象替換當前對象。將一個函數的對象上下文從初始的上下文改變爲由 thisObj 指定的新對象。
但兩者在參數上有區別的。對於第一個參數意義都一樣,但對第二個參數: apply傳入的是一個參數數組,也就是將多個參數組合成爲一個數組傳入,而call則作爲call的參數傳入(從第二個參數開始)。 如 func.call(func1,var1,var2,var3)對應的apply寫法爲:func.apply(func1,[var1,var2,var3])
  1. 對作用域上下文和this的理解,看下列代碼:
var User = {
  count: 1,
  getCount: function() {
    return this.count;
  }
};
console.log(User.getCount());  // what?
var func = User.getCount;
console.log(func());  // what?
問兩處console輸出什麼?爲什麼?

答案是1和undefined。
func是在winodw的上下文中被執行的,所以會訪問不到count屬性。
繼續追問,那麼如何確保Uesr總是能訪問到func的上下文,即正確返回1。正確的方法是使用Function.prototype.bind。兼容各個瀏覽器完整代碼如下:
Function.prototype.bind = Function.prototype.bind || function(context){
   var self = this;
   return function(){
      return self.apply(context, arguments);
   };
}
var func = User.getCount.bind(User);
console.log(func());
  1. 原生JS的window.onload與Jquery的
$(document).ready(function(){})有什麼不同?如何用原生JS實現Jq的ready方法?
window.onload()方法是必須等到頁面內包括圖片的所有元素加載完畢後才能執行。
$(document).ready()DOM結構繪製完畢後就執行,不必等到加載完畢。
/*
 * 傳遞函數給whenReady()
 * 當文檔解析完畢且爲操作準備就緒時,函數作爲document的方法調用
 */
var whenReady = (function() {               //這個函數返回whenReady()函數
    var funcs = [];             //當獲得事件時,要運行的函數
    var ready = false;          //當觸發事件處理程序時,切換爲true
    //當文檔就緒時,調用事件處理程序
    function handler(e) {
        if(ready) return;       //確保事件處理程序只完整運行一次
        //如果發生onreadystatechange事件,但其狀態不是complete的話,那麼文檔尚未準備好
        if(e.type === 'onreadystatechange' && document.readyState !== 'complete') {
            return;
        }
        //運行所有註冊函數
        //注意每次都要計算funcs.length
        //以防這些函數的調用可能會導致註冊更多的函數
        for(var i=0; i<funcs.length; i++) {
            funcs[i].call(document);
        }
        //事件處理函數完整執行,切換ready狀態, 並移除所有函數
        ready = true;
        funcs = null;
    }
    //爲接收到的任何事件註冊處理程序
    if(document.addEventListener) {
        document.addEventListener('DOMContentLoaded', handler, false);
        document.addEventListener('readystatechange', handler, false);            //IE9+
        window.addEventListener('load', handler, false);
    }else if(document.attachEvent) {
        document.attachEvent('onreadystatechange', handler);
        window.attachEvent('onload', handler);
    }
    //返回whenReady()函數
    return function whenReady(fn) {
        if(ready) { fn.call(document); }
        else { funcs.push(fn); }
    }
})();
如果上述代碼十分難懂,下面這個簡化版:
function ready(fn){
    if(document.addEventListener) {//標準瀏覽器
        document.addEventListener('DOMContentLoaded', function() {
            //註銷事件, 避免反覆觸發
            document.removeEventListener('DOMContentLoaded',arguments.callee, false);
            fn();//執行函數
        }, false);
    }else if(document.attachEvent) {//IE
        document.attachEvent('onreadystatechange', function() {
            if(document.readyState == 'complete') {
                document.detachEvent('onreadystatechange', arguments.callee);
                fn();//函數執行
            }
        });
    }
};
將循環控制量保存到局部變量
順序無關的遍歷時,用 while 替代 for
將條件分支,按可能性順序從高到低排列
在同一條件子的多( >2 )條件分支時,使用 switch 優於 if
使用三目運算符替代條件分支 
需要不斷執行的時候,優先考慮使用 setInterval
  1. javascript對象的幾種創建方式?
  1. 工廠模式
  2. 構造函數模式
  3. 原型模式
  4. 混合構造函數和原型模式
  5. 動態原型模式
  6. 寄生構造函數模式
  7. 穩妥構造函數模式
  1. javascript繼承的 6 種方法?
  1. 原型鏈繼承
  2. 借用構造函數繼承
  3. 組合繼承(原型+借用構造)
  4. 原型式繼承
  5. 寄生式繼承
  6. 寄生組合式繼承
  1. eval是做什麼的?
  1. 它的功能是把對應的字符串解析成JS代碼並運行
  2. 應該避免使用eval,不安全,非常耗性能(2次,一次解析成js語句,一次執行)
  1. 關於javascript中apply()和call()方法的區別?

相同點:兩個方法產生的作用是完全一樣的
不同點:方法傳遞的參數不同
Object.call(this,obj1,obj2,obj3)
Object.apply(this,arguments)
apply()接收兩個參數,一個是函數運行的作用域(this),另一個是參數數組。
call()方法第一個參數與apply()方法相同,但傳遞給函數的參數必須列舉出來。

  1. JavaScript原型,原型鏈 ? 有什麼特點?
  • 原型對象也是普通的對象,是對象一個自帶隱式的 proto 屬性,原型也有可能有自己的原型,如果一個原型對象的原型不爲null的話,我們就稱之爲原型鏈。
  • 原型鏈是由一些用來繼承和共享屬性的對象組成的(有限的)對象鏈。
  1. JavaScript的數據對象有那些屬性值?

writable:這個屬性的值是否可以改。
  configurable:這個屬性的配置是否可以刪除,修改。
  enumerable:這個屬性是否能在for…in循環中遍歷出來或在Object.keys中列舉出來。
  value:屬性值。

  • 當我們需要一個屬性的時,Javascript引擎會先看當前對象中是否有這個屬性, 如果沒有的話,就會查找他的Prototype對象是否有這個屬性。
    function clone(proto) {
      function Dummy() { }
      Dummy.prototype = proto;
      Dummy.prototype.constructor = Dummy;
      return new Dummy(); //等價於Object.create(Person);
    }
    function object(old) {
    function F() {};
    F.prototype = old;
    return new F();
    }
    var newObj = object(oldObject);
    1. 寫一個通用的事件偵聽器函數
// event(事件)工具集,來源:https://github.com/markyun
markyun.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();
            };
        }
    },
    // 視能力分別使用dom0||dom2||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.removeEnentListener) {
            element.removeEnentListener(type, handler, false);
        } else if (element.datachEvent) {
            element.detachEvent('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.srcElement;
    },
    // 獲取event對象的引用,取到事件的所有信息,確保隨時能使用event;
    getEvent : function(e) {
        var ev = e || window.event;
        if (!ev) {
            var c = this.getEvent.caller;
            while (c) {
                ev = c.arguments[0];
                if (ev && Event == ev.constructor) {
                    break;
                }
                c = c.caller;
            }
        }
        return ev;
    }
}; 
  1. new操作符具體幹了什麼呢?
  1. 創建一個空對象,並且 this 變量引用該對象,同時還繼承了該函數的原型。
  2. 屬性和方法被加入到 this 引用的對象中。
  3. 新創建的對象由 this 所引用,並且最後隱式的返回 this 。
    var obj = {};
    obj.proto = Base.prototype;
    Base.call(obj);
  1. 前端開發的優化問題(看雅虎14條性能優化原則)。

(1) 減少http請求次數:CSS Sprites, JS、CSS源碼壓縮、圖片大小控制合適;網頁Gzip,CDN託管,data緩存 ,圖片服務器。
(2) 前端模板 JS+數據,減少由於HTML標籤導致的帶寬浪費,前端用變量保存AJAX請求結果,每次操作本地變量,不用請求,減少請求次數
(3) 用innerHTML代替DOM操作,減少DOM操作次數,優化javascript性能。
(4) 當需要設置的樣式很多時設置className而不是直接操作style。
(5) 少用全局變量、緩存DOM節點查找的結果。減少IO讀取操作。
(6) 避免使用CSS Expression(css表達式)又稱Dynamic properties(動態屬性)。
(7) 圖片預加載,將樣式表放在頂部,將腳本放在底部 加上時間戳。
(8) 避免在頁面的主體佈局中使用table,table要等其中的內容完全下載之後纔會顯示出來,顯示比div+css佈局慢。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章