編寫一個方法 求一個字符串的字節長度
假設:一個英文字符佔用一個字節,一箇中文字符佔用兩個字節javascript
function GetBytes(str){ var len = str.length; var bytes = len; for(var i=0; i<len; i++){ if (str.charCodeAt(i) > 255) bytes++; } return bytes; } alert(GetBytes("你好,as"));
實現一個函數clone,能夠對JavaScript中的5種主要的數據類型(包括Number、String、Object、Array、Boolean)進行值複製css
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; }
79.冒泡排序、快速排序、去重、查找字符串最多值html
//冒泡排序 var bubbleSort = function(arr) { for (var i = 0; i < arr.length-1; i++) { for (var j = i+1; j < arr.length; j++) { if (arr[i]>arr[j]) { var temp = arr[i]; arr[i] = arr[j]; arr[j] = temp; } } } return arr; }; //快速排序 var quickSort = function(arr) { if (arr.length <= 1) { return arr; } var len = arr.length; var midIndex = Math.floor(len/2); var mid = arr.splice(midIndex,1); var left = []; var right = []; for (var i = 0; i < arr.length; i++) { if (arr[i] < mid) { left.push(arr[i]); } else { right.push(arr[i]); } } return quickSort(left).concat(mid,quickSort(right)) } // 去重 var distinct = function(arr) { var map = {}; var result = []; for (var i = 0; i < arr.length; i++) { if (!map[arr[i]]) { map[arr[i]] = true; result.push(arr[i]); } } return result; } //查找字符串中最多的值 var search = function(str) { var json = {}; var max = 0; var char; for (var i = 0; i < str.length; i++) { if (!json[str[i]]) { json[str[i]]=1; } else { json[str[i]]++; } } console.log(json); for(var i in json){ if(json[i]>max){ max = json[i]; char = i; } } console.log(max, char); }
80.函數組合繼承前端
原型繼承、構造函數繼承、call aplly繼承html5
var Super = function(name){ this.name = name; } Super.prototype.func1 = function() { console.log('func1'); } var Sub = function(name,age) { Super.call(this, name); this.age = age; } Sub.prototype = new Super();
81.事件綁定java
var addEvent = function(e, type, handler, capture ) { if (e.addEventListener) { e.addEventListener(type, handler, capture); } else if (e.attachEvent) { e.attachEvent('on'+type, handler); } else { e['on'+type] = handler; } }
82.淺克隆和深度克隆git
//淺克隆 function extendCopy(p) { var c = {}; for (var i in p) { c[i] = p[i]; } c.uber = p; return c; } //深度克隆 var clone = function(v) { var o = v.constructor === Array ? [] : {}; for (var i in v) { o[i] = typeof v[i] === "Object" ? clone(v[i]) : v[i]; } return o; }
83.實現一個秒針繞一點轉動的效果github
animation: move 60s infinite steps(60); /*設置旋轉的中心點爲中間底部*/ transform-origin: center bottom; /*旋轉從0度到360度*/ @keyframes move { from { transform: rotate(0deg); } to { transform: rotate(360deg); } }
72.生成10個20-50之間的隨機數,存在數組中,常見排序方法,數組亂序方法web
var arr = []; for(var i = 0;i<10;i++){ var num = Math.random()*30 + 20; num = parseInt(num, 10); arr.push(num); } arr.sort(function(a,b){ return 0.5 - Math.random(); })
69.實現一個once函數面試
function test () {console.log('test')} var once = function (fn) { var isFirst = true; return function () { if (isFirst) { isFirst = !isFirst; fn(); } }; }; var b = once(test); b(); // 'test' b(); // nothing
65.兩個數組合併成一個數組排序返回
先依次比較兩個數組,按照小的就傳入新的數組。當此次比較完以後可能有一個數組的長度很長,留下一些數組,而後在新數組的末尾插入便可。
functiongetRes(arr1, arr2){ var len1 = arr1.length, len2 = arr2.length, i = 0, j = 0, k = 0, res = new Array(len1+len2); while(i < len1 && j <len2){ res[k++] = arr[(arr[i] > arr[j]) ? j++ : i++]; } While(i < len1) res[k++]= arr1[i++]; While(j < len2) res[k++]= arr2[j++]; Return res; }
62.將url的查詢參數解析成字典對象
function getQueryObject(url) { url = url == null ? window.location.href : url; var search = url.substring(url.lastIndexOf("?") + 1); var obj = {}; var reg = /([^?&=]+)=([^?&=]*)/g; search.replace(reg, function (rs, $1, $2) { var name = decodeURIComponent($1); var val = decodeURIComponent($2); val = String(val); obj[name] = val; return rs; }); return obj; } getQueryObject("http://www.cnblogs.com/leee/p/4456840.html?name=1&dd=ddd**") Object {name: "1", dd: "ddd**"}
53:圖片預加載和懶加載
預加載:
function loadImage(url, callback) { var img = new Image(); img.src = url; if (img.complete) { // 若是圖片已經存在於瀏覽器緩存,直接調用回調函數 防止IE6不執行onload BUG callback.call(img); return; } img.onload = function () { callback.call(img);//將回調函數的this替換爲Image對象 }; };
懶加載:
當網頁滾動的事件被觸發 -> 執行加載圖片操做 -> 判斷圖片是否在可視區域內 -> 在,則動態將data-src的值賦予該圖片。
var aImages = document.getElementById("SB").getElementsByTagName('img'); //獲取id爲SB的文檔內全部的圖片 loadImg(aImages); window.onscroll = function() { //滾動條滾動觸發 loadImg(aImages); }; //getBoundingClientRect 是圖片懶加載的核心 function loadImg(arr) { for(var i = 0, len = arr.length; i < len; i++) { if(arr[i].getBoundingClientRect().top < document.documentElement.clientHeight && !arr[i].isLoad) { arr[i].isLoad = true; //圖片顯示標誌位 //arr[i].style.cssText = "opacity: 0;"; (function(i) { setTimeout(function() { if(arr[i].dataset) { //兼容不支持data的瀏覽器 aftLoadImg(arr[i], arr[i].dataset.imgurl); } else { aftLoadImg(arr[i], arr[i].getAttribute("data-imgurl")); } arr[i].style.cssText = "transition: 1s; opacity: 1;" //至關於fadein }, 500) })(i); } } } function aftLoadImg(obj, url) { var oImg = new Image(); oImg.onload = function() { obj.src = oImg.src; //下載完成後將該圖片賦給目標obj目標對象 } oImg.src = url; //oImg對象先下載該圖像 }
46:聖盃佈局和雙飛翼佈局
【聖盃佈局】
html代碼中 middle部分首先要放在container的最前部分。而後是left,right
1.將三者都 float:left , 再加上一個position:relative (由於相對定位後面會用到)
2.middle部分 width:100%佔滿
3.此時middle佔滿了,因此要把left拉到最左邊,使用margin-left:-100%
4.這時left拉回來了,但會覆蓋middle內容的左端,要把middle內容拉出來,因此在外圍container加上 padding:0 220px 0 200px
5.middle內容拉回來了,但left也跟着過來了,因此要還原,就對left使用相對定位 left:-200px 同理,right也要相對定位還原 right:-220px
6.到這裏大概就自適應好了。若是想container高度保持一致能夠給left middle right都加上min-height:130px
【雙飛翼佈局】
前幾步都同樣 後邊把外圍padding和相對定位作法換成內層margin
給middle增長一個內層div-- middle-inner, 而後margin:0 220px 0 200px
39: 寫一個組合繼承
var Super = function(name){ this.name = name; } Super.prototype.func1 = function() { console.log('func1'); } var Sub = function(name,age) { Super.call(this, name); this.age = age; } Sub.prototype = new Super();
40:深拷貝方案有哪些,手寫一個深拷貝
var clone = function(v) { var o = v.constructor === Array ? [] : {}; for (var i in v) { o[i] = typeof v[i] === "Object" ? clone(v[i]) : v[i]; } return o; }
實現兩欄佈局有哪些方法
*{margin:0; padding: 0;} html,body{ height: 100%;/*高度百分百顯示*/ } #left{ width: 300px; height: 100%; background-color: #ccc; float: left; } #right{ height: 100%; margin-left: 300px; background-color: #eee;
*{margin:0; padding: 0;} html,body{ height: 100%;/*高度百分百顯示*/ } #left{ width: 300px; height: 100%; background-color: #ccc; float: left; } #right{ height: 100%; overflow:hidden; background-color: #eee; }
第二種方法,我利用的是建立一個新的BFC(塊級格式化上下文)來防止文字環繞的原理來實現的。BFC就是一個相對獨立的佈局環境,它內部元素的佈局不受外面佈局的影響。它能夠經過如下任何一種方式來建立:
float 的值不爲 none
position 的值不爲 static 或者 relative
display 的值爲 table-cell , table-caption , inline-block , flex , 或者 inline-flex 中的其中一個
overflow 的值不爲 visible
第三種flex佈局
在一個UI裏有10個li,實現點擊對應的li,輸出對應的下標
var lis = querySelectorAll('li') for(var i=0;i<10;i++){ lis[i].onclick = (function(a) { return function() { alert(a) } })(i) }
如何取出一個數組裏的圖片並按順序顯示出來?
function loadImage(imgList,callback){ if(!$.isArray(imgList) || !$.isFunction(callback)) return ; var imageData = [] ; $.each(imgList, function(i,src){ var img = new Image() ; img.onload = function(){ $(imageData.shift()).appendTo("body") ; if(!imageData.length){ callback() ; return ; } this.onload = null ; } ; img.src= src ; imageData.push(img) ; }) ; } ;
如何在頁面上實現一個圓形的可點擊區域?三種解決方案。
1. map+area
使用Dreamweaver製做熱點會變得很是的容易,最終會造成上面的代碼,具體的操做,能夠參考視頻,http://www.chuanke.com/3885380-190205.html。
2. border-radius(H5)
運行效果
3. 純js實現
須要求一個點在不在圓上簡單算法、獲取鼠標座標等等
兩點之間的距離計算公式
上面公式對於JavaScript代碼以下:
|AB|=Math.abs(Math.sqrt(Math.pow(X2-X1),2)+Math.pow(Y2-Y1,2)))
Math.abs()求絕對值Math.pow(底數,指數)
Math.sqrt()求平方根
示例:假設圓心爲(100,100),半徑爲50,在圓內點擊彈出相應的信息,在圓外顯示不在圓內的信息
document.onclick=function(e){ var r=50;//圓的半徑 var x1=100,y1=100,x2= e.clientX;y2= e.clientY; //計算鼠標點的位置與圓心的距離 var len=Math.abs(Math.sqrt(Math.pow(x2-x1,2)+Math.pow(y2-y1,2))); if(len<=50){ console.log("內") }else{ console.log("外") } }
一 、流式佈局
<!doctype html> <html> <head> <meta charset="utf-8"/> <title>流式佈局</title> <style type="text/css"> body { margin: 0; } .reddiv { width: 30%; /* 單位 vw ViewWidth vh ViewHeight */ height: 30vw; background-color: red; } .big { } .big span { font-size: 2em; } </style> </head> <body> <!-- 流式佈局 百分比佈局 1、寬高設置百分比 2、寬高設置VW VH 3、彈性圖片(給寬度,高度會自適應,不失真) 四、em/rem(都是倍數,em相對於父級,rem相對於html) --> <!-- <div class="reddiv"></div> --> <img src="http://img.taopic.com/uploads/allimg/121009/235045-12100Z31P150.jpg" width="50%" alt=""> <div class="big"> <span>我是span標籤</span> </div> </body> </html>
2、響應式佈局
<!doctype html> <html> <head> <meta charset="utf-8"/> <title>響應式佈局</title> <style type="text/css"> /* @media 媒體查詢、媒體選擇 screen 屏幕 and 後面跟條件 */ /* 經過媒體查詢能夠設置多套佈局,具體使用哪一套,就是根據媒體查詢的條件來定(條件就是and後面的括號and 和括號之間要有空格) */ @media screen and (max-width:150px) { .div1 { background-color: gold; } } @media screen and (min-width: 150px) and (max-width:300px) { .div1 { background-color: red; } } @media screen and (min-width: 300px) and (max-width:600px) { .div1 { background-color: blue; } } @media screen and (min-width: 600px) and (max-width:900px) { .div1 { background-color: green; } } @media screen and (min-width: 900px) and (max-width:1200px) { .div1 { background-color: pink; } } @media screen and (min-width:1200px) { .div1 { background-color: black; } } .div1 { width: 400px; height: 400px; } </style> </head> <body> <div class="div1"></div> </body> </html>
<!doctype html> <html> <head> <meta charset="utf-8"/> <title>viewport</title> <!-- viewport 可視區域 width 寬度,能夠理解爲設置咱們的網頁一個屏幕能看到的寬度 maximum-scale 放大的最大值(網頁能放大幾倍) minimum-scale 縮小的倍數(網頁最小能縮小多少倍) initial-scale=1.0 頁面初始值(通常是1.0) user-scalable=0 是否容許用戶縮放(1能夠,0不能夠) (蘋果設備,須要的圖片像素通常是物理像素的2倍,或3倍) target-densitydpi 值越高看的越清楚 device-dpi 設備本來的dpi high-dpi 高dpi low-dpi 低dpi value 指定一個具體數值,取值範圍 70 - 400 --> <meta name="viewport" content="width=device-width,maximum-scale=2.0,minimum-scale=1.0,initial-scale=1.0,user-scalable=1,target-densitydpi=high-dpi"> <style type="text/css"> body { margin: 0; } .reddiv { width: 210px; height: 80px; background-color: red; border: 1px solid blue; } </style> </head> <body> <label for="name">姓名</label> <input type="text" id="name"/> <div class="reddiv"></div> </body> </html>
JavaScript開發人員在IT界的需求量一直很大。若是你很是精通神這門語言,你會有不少機會換工做,漲薪水。可是在一家公司錄用你以前,你必須順利經過面試,證實你的技能。在本文中,我將向您展現5個關於前端相關的問題,以測試侯選者的JavaScript技能和他們解決問題的能力。有將會很是有趣!
問題1:Scope做用範圍
考慮下面的代碼:
(function() {
var a = b = 5;
})();
console.log(b);
什麼會被打印在控制檯上?回答上面的代碼會打印5。這個問題的訣竅是,這裏有兩個變量聲明,但a使用關鍵字
var聲明的。表明它是一個函數的局部變量。與此相反,b變成了全局變量。這個問題的另外一個訣竅是,它沒有使用嚴格模式 ('use strict';)。若是啓用了嚴格模式,代碼就會引起ReferenceError的錯誤:B沒有定義(b is not defined)。請記住,嚴格模式,則須要明確指定,才能實現全局變量聲明。好比,你應該寫:
(function() {
'use strict';
var a = window.b = 5;
})();
console.log(b);問題2:建立「原生」(native)方法
給字符串對象定義一個repeatify功能。當傳入一個整數n時,它會返回重複n次字符串的結果。例如:
console.log('hello'.repeatify(3));
應打印hellohellohello。回答一個可能的實現以下所示:
String.prototype.repeatify = String.prototype.repeatify ||
function(times) {
var str = '';
for (var i = 0; i < times; i++) {
str += this;
}
return str;
};
如今的問題測試開發者有關JavaScript繼承和prototype的知識點。這也驗證了開發者是否知道該若是擴展內置對象(儘管這不該該作的)。這裏的另外一個要點是,你要知道如何不覆蓋可能已經定義的功能。經過測試一下該功能定義以前並不存在:
String.prototype.repeatify = String.prototype.repeatify ||
function(times) {
/* code here */
};
當你被要求作好JavaScript函數兼容時這種技術特別有用。
問題3:聲明提高(Hoisting)
執行這段代碼,輸出什麼結果。
function test() {
console.log(a);
console.log(foo());
var a = 1;
function foo() {
return 2;
}
}
test();
回答這段代碼的結果是undefined和2。緣由是,變量和函數的聲明都被提早了(移到了函數的頂部),但變量不分配任何值。所以,在打印變量的時候,它在函數中存在(它被聲明瞭),但它仍然是undefined。表示換句話說,上面的代碼等同於如下內容:
function test() {
var a;
function foo() {
return 2;
}
console.log(a);
console.log(foo());
a = 1;
}
test();
問題4:this在JavaScript中如何工做的
下面的代碼會輸出什麼結果?給出你的答案。
var fullname = 'John Doe';
var obj = {
fullname: 'Colin Ihrig',
prop: {
fullname: 'Aurelio De Rosa',
getFullname: function() {
return this.fullname;
}
}
};
console.log(obj.prop.getFullname());
var test = obj.prop.getFullname;
console.log(test());
回答答案是Aurelio De Rosa和John Doe。緣由是,在一個函數中,this的行爲,取決於JavaScript函數的調用方式和定義方式,而不只僅是看它如何被定義的。在第一個console.log()調用中,getFullname()被調用做爲obj.prop對象的函數。因此,上下文指的是後者,函數返回該對象的fullname。與此相反,當getFullname()被分配到test變量時,上下文指的是全局對象(window)。這是由於test是被隱式設置爲全局對象的屬性。出於這個緣由,該函數返回window的fullname,即定義在第一行的那個值。
問題5:call()和apply()
如今讓你解決前一個問題,使最後的console.log()打印Aurelio De Rosa。回答該問題能夠經過強制使用call()或者apply()改變函數上下文。在下面我將使用call(),但在這種狀況下,apply()會輸出相同的結果:
console.log(test.call(obj.prop));結論
在這篇文章中,咱們已經討論了用來測試JavaScript開發者的五個經典問題。面試的概念和涵蓋的主題一般是很是類似的。若是你不知道的一些問題的答案,沒必要擔憂:學習和經驗能夠慢慢積累。若是你有其餘一些有趣的問題,不要猶豫,與咱們分享。它會幫助不少開發者。
11.b繼承a的方法12.寫一個獲取非行間樣式的函數
function getStyle(obj, attr, value)
{
if (!value)
{
if (obj.currentStyle)
{
return obj.currentStyle(attr);
}
else
{
obj.getComputedStyle(attr, false);
}
}
else
{
obj.style[attr] = value;
}
}
22.編寫一個數組去重的方法
function oSort(arr) {
var result = {};
var newArr = [];
for (var i = 0; i < arr.length; i++)
{
if (!result[arr[i]])
{
newArr.push(arr[i]);
result[arr[i]] = 1;
}
}
return newArr;
}
23.排序算法
「快速排序」的思想很簡單,整個排序過程只須要三步:
(1)在數據集之中,找一個基準點
(2)創建兩個數組,分別存儲左邊和右邊的數組
(3)利用遞歸進行下次比較
function quickSort(arr){ if(arr.length<=1){ return arr;//若是數組只有一個數,就直接返回; } var num = Math.floor(arr.length/2);//找到中間數的索引值,若是是浮點數,則向下取整 var numValue = arr.splice(num,1);//找到中間數的值 var left = []; var right = []; for(var i=0;i<arr.length;i++){ if(arr[i]<numValue){ left.push(arr[i]);//基準點的左邊的數傳到左邊數組 } else{ right.push(arr[i]);//基準點的右邊的數傳到右邊數組 } } return quickSort(left).concat([numValue],quickSort(right));//遞歸不斷重複比較 } alert(quickSort([32,45,37,16,2,87]));//彈出「2,16,32,37,45,87」
/**冒泡排序 */
function bubbleSort() {
var array = [5, 4, 3, 2, 1];
var temp = 0;
for (var i = 0; i < array.length; i++)
{
for (var j = 0; j < array.length - i; j++)
{
if (array[j] > array[j + 1])
{
temp = array[j + 1];
array[j + 1] = array[j];
array[j] = temp;
}
}
}
}
(內容3)——————
http: //bbs.blueidea.com/thread-3107428-1-1.html如下都是網上整理出來的JS面試題,答案僅供參考。
2,截取字符串abcdefg的efg alert('abcdefg'.substring(4));
3,判斷一個字符串中出現次數最多的字符,統計這個次數
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 + '次');
6,javascript面向對象中繼承實現
function Person(name) {
this.name = name;
}
Person.prototype.showName = function() {
alert(this.name);
}
function Worker(name, job) {
Person.apply(this, arguments) this.job = job;
}
for (var i in Person.prototype) {
Worker.prototype = Person.prototype;
}
new Worker('sl', 'coders').showName();
7,FF下面實現outerHTML
var oDiv = document.createElement('div');
var oDiv1 = document.getElementById('div1');
var oWarp = document.getElementById('warp');
oWarp.insertBefore(oDiv, oDiv1);
oDiv.appendChild(oDiv1);
var sOut = oDiv.innerHTML;
oWarp.insertBefore(oDiv1, oDiv);
oWarp.removeChild(oDiv);
alert(sOut);
8,編寫一個方法求一個字符串的字節長度假設一箇中文佔兩個字節
var str = '22兩是';
alert(getStrlen(str))
function getStrlen(str) {
var json = {
len: 0
};
var re = /[\u4e00-\u9fa5]/;
for (var i = 0; i < str.length; i++) {
if (re.test(str.charAt(i))) {
json['len']++;
}
};
return json['len'] + str.length;
}
十一、如何深度克隆
var arr = [1, 2, 43];
var json = {
a: 6,
b: 4,
c: [1, 2, 3]
};
var str = 'sdfsdf';
var json2 = clone(json);
alert(json['c']) function clone(obj) {
var oNew = new obj.constructor(obj.valueOf());
if (obj.constructor == Object) {
for (var i in obj) {
oNew[i] = obj[i];
if (typeof(oNew[i]) == 'object') {
clone(oNew[i]);
}
}
}
return oNew;
}
12,JavaScript中如何檢測一個變量是一個String類型?請寫出函數實現typeof(obj) == 'string'obj.constructor == String;
13,網頁中實現一個計算當年還剩多少時間的倒數計時程序,要求網頁上實時動態顯示「××年還剩××天××時××分××秒」
var oDate = new Date();
var oYear = oDate.getFullYear();
var oNewDate = new Date();
oNewDate.setFullYear(oYear, 11, 31, 23, 59, 59);
var iTime = oNewDate.getTime() - oDate.getTime();
var iS = iTime / 1000;
var iM = oNewDate.getMonth() - oDate.getMonth();
var iDate = iS
以前在學習時把問題和答案分開了,這兒也分開吧。這樣在看得時候無心識的會多思考一下。茶餘飯後,來杯咖啡
["1","2","3"].map(parseInt) A.["1","2","3"] B.[1,2,3] C.[0,1,2] D.其餘
map對數組的每一個元素調用定義的回調函數並返回包含結果的數組。["1","2","3"].map(parseInt)對於數組中每一個元素調用paresInt。可是該題目不一樣於:
function testFuc(a){ return parseInt(a); } console.info(["1","2","3"].map(testFuc));
題目等同於:
function testFuc(a,x){ return parseInt(a,x); } console.info(["1","2","3"].map(testFuc));
map中回調函數的語法以下所示:function callbackfn(value, index, array1),可以使用最多三個參數來聲明回調函數。第一參數value,數組元素的值;第二個參數index,數組元素的數組因此;array1,包含該元素的數組對象。
所以,題目等同於[parseInt(1,0),parseInt(2,1),parseInt(3,2)] 最終返回[1, NaN, NaN]。
[typeof null, null instanceof Object] A.["object",false] B.[null,false] C.["object",true] D.其餘
typeof用以獲取一個變量或者表達式的類型,typeof通常只能返回以下幾個結果:
number,boolean,string,function(函數),object(NULL,數組,對象),undefined
instanceof 表示某個變量是不是某個對象的實例,null是個特殊的Object類型的值 ,表示空引用的意思 。但null返回object這個實際上是最初JavaScript的實現的一個錯誤,
而後被ECMAScript沿用了,成爲了如今的標準,不過咱們把null能夠理解爲還沒有存在的對象的佔位符,這樣就不矛盾了 ,雖然這是一種「辯解」。
對於咱們開發人員 仍是要警戒這種「語言特性」。最終返回:["object", false]
[[3,2,1].reduce(Math.pow),[].reduce(Math.pow)] A.報錯 B.[9,0] C.[9,NaN] D.[9,undefined]
pow() 方法可返回 x 的 y 次冪的值。[3,2,1].reduce(Math.pow);等同於:
function testFuc(x,y){ console.info(x +" : "+y); return Math.pow(x,y); } console.info([3,2,1].reduce(testFuc));
執行Math.pow(3,2)和Math.pow(2,1),最終返回9和9。
可是要注意pow的參數都是必須的,[].reduce(Math.pow),等同於執行Math.pow();會致使錯誤。
var val = 'value'; console.info('Value id '+(val === 'value')?'Something':'Nothing'); A.Something B.Nothing C.NaN D.其餘
先執行字符串拼接,再執行校驗
var val = 'value'; console.info('Value id '+(val === 'value123')?'Something':'Nothing');
一樣會返回something
var name = 'World'; (function(){ if(typeof name === 'undefined'){ var name = "Jack"; console.info('Goodbye '+ name); }else{ console.info('Hello ' + name); } })(); A.Goodbye Jack B.Hello Jack C.Goodbye undefined D.Hello undefined
判斷語句被包裹在當即調用函數裏,函數內部沒法訪問外部值爲'World'的name,所以typeof name === 'undefined'爲真,執行下一步操做,最終輸出Goodbye Jack
var START = END -100; var count = 0; for(var i = START ; i <= END ;i++){ count ++; } console.info(count); A.0 B.100 C.101 D.其餘
END = 9007199254740992 ,START = 9007199254740892目的是計算的END和START之間的差。可是2的53次方計算出的結果因爲精度問題使得i++失效。
var arr = [0,1,2]; arr[10] = 10; arr.filter(function(x){return x === undefined}); A.[undefined x 7] B.[0,1,2,10] C.[] D.[undefined]
filter會接觸到沒有被賦值的元素,即在arr中,長度爲10但實際數值元素列表爲[0, 1, 2, 10],所以,最終返回一個空的數組[]。
var two = 0.2; var one = 0.1; var eight = 0.8; var six = 0.6; [two -one == one,eight- six == two]; A.[true,true] B.[false,false] C.[true,false] D.其餘
兩個浮點數相加或者相減,將會致使必定的正常的數據轉換形成的精度丟失問題eight-six = 0.20000000000000007。
JavaScript中的小數採用的是雙精度(64位)表示的,由三部分組成: 符 + 階碼 + 尾數,在十進制中的 1/10,在十進制中能夠簡單寫爲 0.1 ,但在二進制中,他得寫成:0.0001100110011001100110011001100110011001100110011001…..(後面全是 1001 循環)。由於浮點數只有52位有效數字,從第53位開始,就舍入了。這樣就形成了「浮點數精度損失」問題。
更嚴謹的作法是(eight-six ).totoFiexd(1)或者用用Math.round方法迴歸整數運算。判斷兩個浮點數是否相等,仍是建議用逼近的比較,好比if((a-b) < 1E-10)
function showCase(value){ switch(value){ case 'A': console.info('Case A'); break; case 'B': console.info('Case B'); break; case undefined : console.info('undefined'); break; default: console.info('Do not know!'); } } showCase(new String('A')); A.Case A B.Case B C.Do not know D.undefined
使用new String()使用構造函數調用講一個全新的對象做爲this變量的值,而且隱式返回這個新對象做爲調用的結果,所以showCase()接收的參數爲String {0: "A"}爲不是咱們所認爲的「A」
function showCase(value){ switch(value){ case 'A': console.info('Case A'); break; case 'B': console.info('Case B'); break; case undefined : console.info('undefined'); break; default: console.info('Do not know!'); } } showCase(String('A')); A.Case A B.Case B C.Do not know D.undefined
直接調用String("A")建立的變量和"A"無異。
var a="123" '只是設置變量 b=new String('123') '設置一個成員 var a="123"; a.sex=1; alert(a.sex);//輸出未定義,由於不是成員,沒有這屬性 b=new String('123'); b.sex=1; alert(b.sex);//輸出1,成員的屬性
function isOdd(num){ return num % 2 == 1; } function isEven(num){ return num % 2 == 0; } function isSane(num){ return isEven(num)||isOdd(num); } var values = [7,4,'13',-9,Infinity]; values.map(isSane); A.[true, true, true, true, true] B.[true, true, true, true, false] C.[true, true, true, false, false] D.[true, true, false, false, false]
function isSane(num){ return isEven(num)||isOdd(num); }
該函數判斷num是否爲正整數,'13'被強制轉換爲數值13,-9%2結果爲-1,Infinity %2爲NaN
[parseInt(3,8),parseInt(3,2),parseInt(3,0)] A.[3,3,3] B.[3,3,NaN] C.[3,NaN,NaN] D.其餘
最終結果爲[3, NaN, 3];
parseInt() 函數可解析一個字符串,並返回一個整數。當參數 radix 的值爲 0,或沒有設置該參數時,parseInt() 會根據 string 來判斷數字的基數。
Array.isArray(Array.prototype) A.true B.false C.報錯 D.其餘
Array.prototype爲[],Array.isArray(a)是一個判斷a是否爲數組的方法。
判斷對象是否爲數組的方法:
1)ES5函數isArray(),該函數測試對象的內部[[Class]]屬性是否爲Array:Arrray.isArray(a);
2)判斷對象的構造函數是否爲Array:a.constructor === Array
3)使用對象內部[[Class]]屬性建立結果字符串:Object.prototype.toString.call(a)
4)使用instanceof操做符測試對象是否繼承自Array:(但因爲,一個頁面的iframe不會繼承自另一個頁面的iframe,該方法不可靠)
a instanceof Array
var a = [0]; if([0]){ console.info(a == true); }else{ console.info("false"); } A.true B.false C."else" D.其餘
在if條件判斷語句相對於==比較寬鬆中,只要if(n),n不爲null,0,undefined數值,都會轉換爲true。進入console.info(a == true);最終返回false。
[]==[] A.true B.false C.報錯 D.其餘
數組,在 Javascript 中是對象,對象使用 == 比較都是比較的引用。簡單的說,就是,若是是同一個對象,就相等,若是不是同一個對象,就不等。每次使用 [] 都是新建一個數組對象,因此 [] == [] 這個語句裏建了兩個數據對象,它們不等。
[('5'+3),('5'-3)] A.["53",2] B.[8,2] C.報錯 D.其餘
執行'5'+3,加號具有拼接字符串功能,會將3強制轉換爲字符串'3'和'5'拼接。
執行'5'-3,減號只具有數值運算的功能,所以會將'5'轉化爲數值,進行5-3的數值運算
1+-+++-+1 A.true B.false C.報錯 D.其餘
var arr = Array(3); arr[0] = 2 arr.map(function(elem){return '1';}); A.[2,1,1] B.["1","1","1"] C.[2,"1","1"] D.其餘
區分賦值和聲明。雖然var arr = Array(3);建立一個長度爲3的數組,可是實際只有一個元素被賦值,所以arr的實際長度爲1,即最終參與map的只有一個元素,返回[1]
function sidEffecting(arr){ arr[0] = arr[2]; } function bar(a,b,c){ c = 10; sidEffecting(arguments); return a+b+c; } bar(1,1,1); A.3 B.12 C.報錯 D.其餘
按照執行步驟,無需多疑,最終結果爲10+1+10
var a = 111111111111111110000; b = 1111; console.info(a+b); A.111111111111111111111 B.111111111111111110000 C.NaN D.Infinity
js的精確整數最大爲:Math.pow(2,53)-1 =9007199254740991.
var a = 111111111111111110000,
max = 9007199254740992;
a的值大於javascript所能表示的最大整數精度,所以和任何數值相加將會致使失真。
var x = [].reverse; x(); A.[] B.undefined C.報錯 D.window
正確調用方式爲x.call([])
Number.MIN_VALUE>0 A.true B.false C.報錯 D.其餘
Number.MIN_VALUE表示的最小值爲5e-324,MIN_VALUE表明的並非負最小,而是最接近0的一個數,所以Number.MIN_VALUE>0。
負最小值可使用-Number.MAX_VALUE表示。
[1<2<3,3<2<1] A.[true,true] B.[true,false] C.報錯 D.其餘
1<2,返回true,執行true<3,會強制將true轉換爲1,1<3,最終返回true。
3<2,返回false,執行false<1,會強制將false轉換爲0,0<1,最終返回true。
2 == [[[2]]] A.true B.false C.undefined D.其餘
使用a==b判斷a和b對象是否相等,能夠會將b對象強制轉換爲a對象的類型,即執行2 == [[[2]]],會隱式調用parseInt([[[2]]])將[[[2]]]強制轉化爲數字基本量,即2,2==2,最終返回true。
[3.toString(),3..toString(),3...toString()] A.["3",error,error] B.["3","3.0",error] C.[error,"3",error] D.其餘
Number中的toString(a),可以將數值轉化成爲a進制的值。但a缺省時,默認轉化爲十進制。
通常使用方法爲:var n = 3;3.toString();
執行3.toString(),由於3只是爲數值型變量,爲非Number實例,所以對於3不能直接調用Number方法。而執行3..toString(),會強制將3轉化爲數字實例,所以可以被解釋,輸出3,一樣可使用(3).toString()。
(function(){ var x1 =y1 =1; })(); console.info(y1); console.info(x1); A.1,1 B.error,error C.1,error D.其餘
在當即調用函數內執行,var x1 =y1 =1;建立局部變量x1和全局變量y1。函數外部試圖訪問函數內部的變量,將會致使錯誤。
(1)window.event 表示當前的事件對象,IE有這個對象,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)
function initButtons(){ var body = document.body,button,i; for(i =0;i<5;i++){ button = document.createElement("button"); button.innerHTML = "Button" + i; button.addEventListener("click",function(e){ alert(i); },false); body.appendChild(button); } } initButtons();
題目所給出的代碼,除了有addEventListener不兼容IE瀏覽器的問題以外,最突出的一個問題是:
雖然在頁面上會顯示值爲button+i的按鈕,可是點擊任意一個按鈕,最終都會顯示5。
要想點擊相關按鈕,彈出相應的1,2,3,4,5的值,須要理解閉包原理實現和使用當即回調函數。修改後的代碼以下:
function initButtons(){ var body = document.body,button,i; for(i =0;i<5;i++){ (function(i){ button = document.createElement("button"); button.innerHTML = "Button" + i; button.addEventListener("click",function(e){ alert(i); },false); body.appendChild(button); })(i); } } initButtons();
涉及綁定和賦值獲得區別。在運行時,進入一個做用域,javascript會爲每個綁定到該做用域的變量在內存中分配一個「槽」(slot)。函數中,建立變量document.body,button,i,所以當函數體(建立按鈕,併爲按鈕綁定事件)被調用時,函數會爲每一個變量分配一個「槽」。在循環的每次迭代中,循環體都會爲嵌套函數分配一個閉包。咱們可能理解爲,該函數存儲的是嵌套函數建立時變量i的值。但事實上,他存儲的是i的引用。因爲每次函數建立後變量i的值都發生變化,所以函數內部最終看到的是變量i的引用。閉包存儲的是外部變量的引用而非值。
當即調用的函數表達式,是一種不可或缺的解決javascript缺乏塊級做用域的方法。
須要深刻理解,能夠查看《Effective JavaScript》第13條:使用當即調用的函數表達式建立局部做用域
判斷一個字符串中出現次數最多的字符,並統計出現的次數。
使用常規方法和正則表達式匹配兩種算法
/*寫一段代碼。判斷一個字符串中出現次數最多的字符串,並統計出現的次數*/
function toGetTheMostCharsByArray(s){
var r={}; for(var i=0;i<s.length;i++){ if(!r[s[i]]){ r[s[i]] = 1; }else{ r[s[i]]++; } } var max = { "value " :s[0], "num" : r[s[0]] }; for(var n in r){//對象使用in關鍵字,由於沒有length if(r[n]>max.num){ max.num = r[n]; max.value = n; } } return max; } function toGetTheMostCharsByRegex(s){ var a = s.split(''); a.sort(); s = a.join(''); var regex = /(\w)\1+/g ;//\1表明重複的 var max = { "value " :s[0], "num" : 0 }; s.replace(regex,function(a,b){ if(max.num < a.length){ max.num = a.length; max.value= b; } }); return max; } var test = "efdfssssfrhth"; console.info("使用常規方法 ,出現最多的字符串爲:"+toGetTheMostCharsByArray(test).value+" ,出現次數:"+toGetTheMostCharsByArray(test).num); console.info("使用字符串匹配,出現最多的字符串爲:"+toGetTheMostCharsByRegex(test).value+" ,出現次數:"+toGetTheMostCharsByRegex(test).num);
(1)setTimeout(function(){ /*代碼塊*/ setTimeout(arguments.callee,10); },10); (2)setInterval(function(){ /*代碼塊*/ },10);
javascript的引擎是單線程的
javascript的引擎是基於事件驅動的
setTimeout和setInterval都是往事件隊列中增長一個待處理時間而已,setTimeout只觸發一次,而setInterval是循環觸發
setTimeout(function(){ //代碼塊 setTimeout(arguments.callee,10); },10);
上段代碼可以使得setTimeout循環觸發。可是,執行完這段代碼塊才掛起時間,因此兩次執行時間會大於10毫秒
setInterval(function(){ /*代碼塊*/ },10);
而上段代碼,是自動在10的時候掛上這個事件,因此兩次事件的相隔會小於等於10毫秒。
當線程阻塞在一個事件的時候,無論是使用setInterval仍是setTimeout都須要等待當前事件處理完才能執行。
年前剛剛離職了,分享下我曾經出過的一道面試題,此題是我出的一套前端面試題中的最後一題,用來考覈面試者的JavaScript的綜合能力,很惋惜到目前爲止的將近兩年中,幾乎沒有人可以徹底答對,並不是多難只是由於大多面試者過於輕視他。
題目以下:
function Foo() {
getName = function () { alert (1); }; return this; } Foo.getName = function () { alert (2);}; Foo.prototype.getName = function () { alert (3);}; var getName = function () { alert (4);}; function getName() { alert (5);} //請寫出如下輸出結果: Foo.getName(); getName(); Foo().getName(); getName(); new Foo.getName(); new Foo().getName(); new new Foo().getName();
答案是:
function Foo() {
getName = function () { alert (1); }; return this; } Foo.getName = function () { alert (2);}; Foo.prototype.getName = function () { alert (3);}; var getName = function () { alert (4);}; function getName() { alert (5);} //答案: Foo.getName();//2 getName();//4 Foo().getName();//1 getName();//1 new Foo.getName();//2 new Foo().getName();//3 new new Foo().getName();//3
此題是我綜合以前的開發經驗以及遇到的JS各類坑聚集而成。此題涉及的知識點衆多,包括變量定義提高、this指針指向、運算符優先級、原型、繼承、全局變量污染、對象屬性及原型屬性優先級等等。
此題包含7小問,分別說下。
先看此題的上半部分作了什麼,首先定義了一個叫Foo的函數,以後爲Foo建立了一個叫getName的靜態屬性存儲了一個匿名函數,以後爲Foo的原型對象新建立了一個叫getName的匿名函數。以後又經過函數變量表達式建立了一個getName的函數,最後再聲明一個叫getName函數。
第一問的 Foo.getName 天然是訪問Foo函數上存儲的靜態屬性,天然是2,沒什麼可說的。
第二問,直接調用 getName 函數。既然是直接調用那麼就是訪問當前上文做用域內的叫getName的函數,因此跟1 2 3都沒什麼關係。此題有無數面試者回答爲5。此處有兩個坑,一是變量聲明提高,二是函數表達式。
即全部聲明變量或聲明函數都會被提高到當前函數的頂部。
例以下代碼:
console.log('x' in window);//true var x;
x = 0;
代碼執行時js引擎會將聲明語句提高至代碼最上方,變爲:
var x; console.log('x' in window);//true x = 0;
var getName 與 function getName 都是聲明語句,區別在於 var getName 是函數表達式,而 function getName 是函數聲明。關於JS中的各類函數建立方式能夠看 大部分人都會作錯的經典JS閉包面試題 這篇文章有詳細說明。
函數表達式最大的問題,在於js會將此代碼拆分爲兩行代碼分別執行。
例以下代碼:
console.log(x);//輸出:function x(){} var x=1; function x(){}
實際執行的代碼爲,先將 var x=1 拆分爲 var x; 和 x = 1; 兩行,再將 var x; 和 function x(){} 兩行提高至最上方變成:
var x; function x(){} console.log(x); x=1;
因此最終函數聲明的x覆蓋了變量聲明的x,log輸出爲x函數。
同理,原題中代碼最終執行時的是:
function Foo() {
getName = function () { alert (1); }; return this; } var getName;//只提高變量聲明 function getName() { alert (5);}//提高函數聲明,覆蓋var的聲明 Foo.getName = function () { alert (2);}; Foo.prototype.getName = function () { alert (3);}; getName = function () { alert (4);};//最終的賦值再次覆蓋function getName聲明 getName();//最終輸出4
第三問的 Foo().getName(); 先執行了Foo函數,而後調用Foo函數的返回值對象的getName屬性函數。
Foo函數的第一句 getName = function () { alert (1); }; 是一句函數賦值語句,注意它沒有var聲明,因此先向當前Foo函數做用域內尋找getName變量,沒有。再向當前函數做用域上層,即外層做用域內尋找是否含有getName變量,找到了,也就是第二問中的alert(4)函數,將此變量的值賦值爲 function(){alert(1)}。
此處其實是將外層做用域內的getName函數修改了。
注意:此處若依然沒有找到會一直向上查找到window對象,若window對象中也沒有getName屬性,就在window對象中建立一個getName變量。
以後Foo函數的返回值是this,而JS的this問題博客園中已經有很是多的文章介紹,這裏再也不多說。
簡單的講,this的指向是由所在函數的調用方式決定的。而此處的直接調用方式,this指向window對象。
遂Foo函數返回的是window對象,至關於執行 window.getName() ,而window中的getName已經被修改成alert(1),因此最終會輸出1
此處考察了兩個知識點,一個是變量做用域問題,一個是this指向問題。
直接調用getName函數,至關於 window.getName() ,由於這個變量已經被Foo函數執行時修改了,遂結果與第三問相同,爲1
第五問 new Foo.getName(); ,此處考察的是js的運算符優先級問題。
js運算符優先級:
參考連接:https://developer.mozilla.org/zh-CN/docs/Web/JavaScript/Reference/Operators/Operator_Precedence
經過查上表能夠得知點(.)的優先級高於new操做,遂至關因而:
new (Foo.getName)();
因此實際上將getName函數做爲了構造函數來執行,遂彈出2。
第六問 new Foo().getName() ,首先看運算符優先級括號高於new,實際執行爲
(new Foo()).getName()
遂先執行Foo函數,而Foo此時做爲構造函數卻有返回值,因此這裏須要說明下js中的構造函數返回值問題。
在傳統語言中,構造函數不該該有返回值,實際執行的返回值就是此構造函數的實例化對象。
而在js中構造函數能夠有返回值也能夠沒有。
一、沒有返回值則按照其餘語言同樣返回實例化對象。
二、如有返回值則檢查其返回值是否爲引用類型。若是是非引用類型,如基本類型(string,number,boolean,null,undefined)則與無返回值相同,實際返回其實例化對象。
三、若返回值是引用類型,則實際返回值爲這個引用類型。
原題中,返回的是this,而this在構造函數中原本就表明當前實例化對象,遂最終Foo函數返回實例化對象。
以後調用實例化對象的getName函數,由於在Foo構造函數中沒有爲實例化對象添加任何屬性,遂到當前對象的原型對象(prototype)中尋找getName,找到了。
遂最終輸出3。
第七問, new new Foo().getName(); 一樣是運算符優先級問題。
最終實際執行爲:
new ((new Foo()).getName)();
先初始化Foo的實例化對象,而後將其原型上的getName函數做爲構造函數再次new。
遂最終結果爲3
===2016年03月23日更新===
這裏引用 @於明昊 的評論,更詳細的解釋了第7問:
這裏確實是(new Foo()).getName(),可是跟括號優先級高於成員訪問不要緊,實際上這裏成員訪問的優先級是最高的,所以先執行了 .getName,可是在進行左側取值的時候, new Foo() 能夠理解爲兩種運算:new 帶參數(即 new Foo())和函數調用(即 先 Foo() 取值以後再 new),而 new 帶參數的優先級是高於函數調用的,所以先執行了 new Foo(),或得 Foo 類的實例對象,再進行了成員訪問 .getName。
就答題狀況而言,第一問100%均可以回答正確,第二問大概只有50%正確率,第三問能回答正確的就很少了,第四問再正確就很是很是少了。其實此題並無太多刁鑽匪夷所思的用法,都是一些可能會遇到的場景,而大多數人但凡是有1年到2年的工做經驗都應該徹底正確纔對。
只能說有一些人太急躁過輕視了,但願你們經過此文了解js一些特性。
並祝願你們在新的一年找工做面試中膽大心細,發揮出最好的水平,找到一份理想的工做。
高階函數就是能夠將函數做爲另外一個函數的參數。
例如:將兩個數的平方相加,這裏匿名函數fn就是函數被做爲參數。
function add(a,b,fn){ return fn(a)+fn(b); } var fn=function (a){ return a*a; } add(2,3,fn);
1.map做用在數組的每一個元素上的函數。
例如:將數組arr的每一個元素都加上10。
var arr=[5,6,7,8,9]; var fn=function(a){ return a+10; } console.log(arr.map(fn));
2.reduce也做用在數組上,可是每次只能接受兩個參數。
例如:將數組arr的每一個元素相加,由於元素爲字符串,因此鏈接在一塊兒。
var arr=["小","明","喜","歡","學","習"]; var fn=function(a,b){ return a+b; } console.log(arr.reduce(fn));
也能夠寫成:
var arr=["小","明","喜","歡","學","習"]; function fn(arr){ return arr.reduce(function(a,b){ return a+b; }) } console.log(fn(arr));
3.filter用於過濾數組的元素。
例如:過濾掉arr內的偶數。
var arr=[1,2,3,4,5,6,7,8,9,10]; var fn=arr.filter(function(x){ return x%2!=0; }) console.log(fn);
4.sort用於將數組進行排序,此函數默認會將數組內的元素轉換成字符串類型進行排序,且按照大寫在前的規律排序。
var arr=["X","y","Z","A","b","C"]; console.log(arr.sort());
忽略大小寫進行排序。
若是倒敘的話將1與-1的值交換。
function fn(a,b){ var a1=a.toLowerCase(); var b1=b.toLowerCase() if(a1>b1){ return -1; } if(a1<b1){ return 1; } return 0; } var newArr=arr.sort(fn); console.log(newArr);
固然也有一個倒敘的函數
console.log(newArr.reverse());
webSocket例子
[http://www.cnblogs.com/wei2yi/archive/2011/03/23/1992830.html]
是下一代客戶端-服務器的異步通訊方法,該通訊取代了單個的TCP套接字,使用ws或wss協議,可用於任意的客戶端和服務器程序;並且有一個優秀的第三方API,名爲Socket.IO
服務器和客戶端能夠在給定的時間範圍內的任意時刻,相互推送信息;
與ajax的區別:
WebSocket並不限於以Ajax(或XHR)方式通訊,由於Ajax技術須要客戶端發起請求,而WebSocket服務器和客戶端能夠彼此相互推送信息;XHR受到域的限制,而WebSocket容許跨域通訊
// 建立一個Socket實例 var socket = new WebSocket('ws://localhost:8080'); //ws表示socket協議 // 打開Socket socket.onopen = function(event) { // 發送一個初始化消息 socket.send('I am the client and I\'m listening!'); // 監聽消息 socket.onmessage = function(event) { console.log('Client received a message',event); }; // 監聽Socket的關閉 socket.onclose = function(event) { console.log('Client notified socket has closed',event); }; // 關閉Socket.... socket.close() };
(內容5)——————
HTML5 文檔類型很簡單:<!doctype html>
HTML5 使用 UTF-8 編碼示例:
HTML5 支持 MP三、Wav 和 Ogg 格式的音頻,下面是在網頁中嵌入音頻的簡單示例:
<audio controls> <source src=」jamshed.mp3″ type=」audio/mpeg」> Your browser does’nt support audio embedding feature. </audio>
和音頻相似,HTML5 支持 MP四、WebM 和 Ogg 格式的視頻,下面是簡單示例:
1
2
3
4
|
<video width=」450″ height=」340″ controls>
<source src=」jamshed.mp4″ type=」video/mp4″>
Your browser does’nt support video embedding feature.
</video>
|
HTML5的離線儲存怎麼使用,工做原理能不能解釋一下?
在用戶沒有與因特網鏈接時,能夠正常訪問站點或應用,在用戶與因特網鏈接時,更新用戶機器上的緩存文件。 原理:HTML5的離線存儲是基於一個新建的.appcache文件的緩存機制(不是存儲技術),經過這個文件上的解析清單離線存儲資源,這些資源就會像cookie同樣被存儲了下來。以後當網絡在處於離線狀態下時,瀏覽器會經過被離線存儲的數據進行頁面展現。 如何使用: 一、頁面頭部像下面同樣加入一個manifest的屬性; 二、在cache.manifest文件的編寫離線存儲的資源; CACHE MANIFEST #v0.11 CACHE: js/app.js css/style.css NETWORK: resourse/logo.png FALLBACK: / /offline.html 三、在離線狀態時,操做window.applicationCache進行需求實現。
詳細的使用請參考:有趣的HTML5:離線存儲
寫一個通用的事件偵聽器函數。
// event(事件)工具集,來源: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.removeEventListener) { element.removeEventListener(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; } };
什麼是閉包(closure),爲何要用它?
執行say667()後,say667()閉包內部變量會存在,而閉包內部函數的內部變量不會存在.使得Javascript的垃圾回收機制GC不會收回say667()所佔用的資源,由於say667()的內部函數的執行須要依賴say667()中的變量。這是對閉包做用的很是直白的描述. function say667() { // Local variable that ends up within closure var num = 666; var sayAlert = function() { alert(num); } num++; return sayAlert; } var sayAlert = say667(); sayAlert()//執行結果應該彈出的667
模塊化怎麼作?
當即執行函數,不暴露私有成員
var module1 = (function(){ var _count = 0; var m1 = function(){ //... }; var m2 = function(){ //... }; return { m1 : m1, m2 : m2 }; })();
.call() 和 .apply() 的區別?
例子中用 add 來替換 sub,add.call(sub,3,1) == add(3,1) ,因此運行結果爲:alert(4); 注意:js 中的函數實際上是對象,函數名是對 Function 對象的引用。 function add(a,b) { alert(a+b); } function sub(a,b) { alert(a-b); } add.call(sub,3,1);
用jQuery實現數組轉字符串
jQuery中沒有提供這個功能,因此你須要先編寫兩個jQuery的擴展:
$.fn.stringifyArray = function(array) { return JSON.stringify(array) } $.fn.parseArray = function(array) { return JSON.parse(array) } 而後調用: $("").stringifyArray(array)
針對 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++) {}