編寫一個方法 求一個字符串的字節長度
假設:一個英文字符占用一個字節,一個中文字符占用兩個字節
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)進行值復制
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.冒泡排序、快速排序、去重、查找字符串最多值
//冒泡排序 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繼承
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.事件綁定
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.淺克隆和深度克隆
//淺克隆 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.實現一個秒針繞一點轉動的效果
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之間的隨機數,存在數組中,常見排序方法,數組亂序方法
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("外") } }
WEB前端 | H5基礎——(4)流式布局、響應式布局、Viewport
一 、流式布局
<!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、彈性圖片(給寬度,高度會自適應,不失真) 4、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>
二、響應式布局
<!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;
}
11、如何深度克隆
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
2017.8.31收集
JavaScript-有意思的30題_題目
之前在學習時把問題和答案分開了,這兒也分開吧。這樣在看得時候無意識的會多思考一下。茶余飯后,來杯咖啡
1.以下表達式的運行結果是:
["1","2","3"].map(parseInt)
A.["1","2","3"]
B.[1,2,3]
C.[0,1,2]
D.其他
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]。
2.以下表達式的運行結果是:
[typeof null, null instanceof Object]
A.["object",false]
B.[null,false]
C.["object",true]
D.其他
A
typeof用以獲取一個變量或者表達式的類型,typeof一般只能返回如下幾個結果:
number,boolean,string,function(函數),object(NULL,數組,對象),undefined
instanceof 表示某個變量是否是某個對象的實例,null是個特殊的Object類型的值 ,表示空引用的意思 。但null返回object這個其實是最初JavaScript的實現的一個錯誤,
然后被ECMAScript沿用了,成為了現在的標准,不過我們把null可以理解為尚未存在的對象的占位符,這樣就不矛盾了 ,雖然這是一種“辯解”。
對於我們開發人員 還是要警惕這種“語言特性”。最終返回:["object", false]
3.以下表達式的運行結果是:
[[3,2,1].reduce(Math.pow),[].reduce(Math.pow)]
A.報錯
B.[9,0]
C.[9,NaN]
D.[9,undefined]
A
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();會導致錯誤。
4.以下表達式的運行結果是:
var val = 'value';
console.info('Value id '+(val === 'value')?'Something':'Nothing');
A.Something
B.Nothing
C.NaN
D.其他
A
先執行字符串拼接,再執行校驗
var val = 'value';
console.info('Value id '+(val === 'value123')?'Something':'Nothing');
同樣會返回something
5.以下表達式的運行結果是:
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
A
判斷語句被包裹在立即調用函數里,函數內部無法訪問外部值為'World'的name,因此typeof name === 'undefined'為真,執行下一步操作,最終輸出Goodbye Jack
6.以下表達式的運行結果是:
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.其他
D
END = 9007199254740992 ,START = 9007199254740892目的是計算的END和START之間的差。但是2的53次方計算出的結果由於精度問題使得i++失效。
7.以下表達式的運行結果是:
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]
C
filter會接觸到沒有被賦值的元素,即在arr中,長度為10但實際數值元素列表為[0, 1, 2, 10],因此,最終返回一個空的數組[]。
8.以下表達式的運行結果是:
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.其他
C
兩個浮點數相加或者相減,將會導致一定的正常的數據轉換造成的精度丟失問題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)
9.以下表達式的運行結果是:
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
C
使用new String()使用構造函數調用講一個全新的對象作為this變量的值,並且隱式返回這個新對象作為調用的結果,因此showCase()接收的參數為String {0: "A"}為不是我們所認為的“A”
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(String('A'));
A.Case A
B.Case B
C.Do not know
D.undefined
A
直接調用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,成員的屬性
11.以下表達式的運行結果是:
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]
C
function isSane(num){
return isEven(num)||isOdd(num);
}
該函數判斷num是否為正整數,'13'被強制轉換為數值13,-9%2結果為-1,Infinity %2為NaN
12.以下表達式的運行結果是:
[parseInt(3,8),parseInt(3,2),parseInt(3,0)]
A.[3,3,3]
B.[3,3,NaN]
C.[3,NaN,NaN]
D.其他
D
最終結果為[3, NaN, 3];
parseInt() 函數可解析一個字符串,並返回一個整數。當參數 radix 的值為 0,或沒有設置該參數時,parseInt() 會根據 string 來判斷數字的基數。
13.以下表達式的運行結果是:
Array.isArray(Array.prototype)
A.true
B.false
C.報錯
D.其他
A
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
14.以下表達式的運行結果是:
var a = [0];
if([0]){
console.info(a == true);
}else{
console.info("false");
}
A.true
B.false
C."else"
D.其他
B
在if條件判斷語句相對於==比較寬松中,只要if(n),n不為null,0,undefined數值,都會轉換為true。進入console.info(a == true);最終返回false。
15.以下表達式的運行結果是:
[]==[]
A.true
B.false
C.報錯
D.其他
B
數組,在 Javascript 中是對象,對象使用 == 比較都是比較的引用。簡單的說,就是,如果是同一個對象,就相等,如果不是同一個對象,就不等。每次使用 [] 都是新建一個數組對象,所以 [] == [] 這個語句里建了兩個數據對象,它們不等。
16.以下表達式的運行結果是:
[('5'+3),('5'-3)]
A.["53",2]
B.[8,2]
C.報錯
D.其他
A
執行'5'+3,加號具備拼接字符串功能,會將3強制轉換為字符串'3'和'5'拼接。
執行'5'-3,減號只具備數值運算的功能,因此會將'5'轉化為數值,進行5-3的數值運算
17.以下表達式的運行結果是:
1+-+++-+1
A.true
B.false
C.報錯
D.其他
C
18.以下表達式的運行結果是:
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.其他
D
區分賦值和聲明。雖然var arr = Array(3);創建一個長度為3的數組,但是實際只有一個元素被賦值,因此arr的實際長度為1,即最終參與map的只有一個元素,返回[1]
19.以下表達式的運行結果是:
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.其他
D
按照執行步驟,無需多疑,最終結果為10+1+10
20.以下表達式的運行結果是:
var a = 111111111111111110000;
b = 1111;
console.info(a+b);
A.111111111111111111111
B.111111111111111110000
C.NaN
D.Infinity
B
js的精確整數最大為:Math.pow(2,53)-1 =9007199254740991.
var a = 111111111111111110000,
max = 9007199254740992;
a的值大於javascript所能表示的最大整數精度,因此和任何數值相加將會導致失真。
21.以下表達式的運行結果是:
var x = [].reverse;
x();
A.[]
B.undefined
C.報錯
D.window
C
正確調用方式為x.call([])
22.以下表達式的運行結果是:
Number.MIN_VALUE>0
A.true
B.false
C.報錯
D.其他
A
Number.MIN_VALUE表示的最小值為5e-324,MIN_VALUE代表的並不是負最小,而是最接近0的一個數,因此Number.MIN_VALUE>0。
負最小值可以使用-Number.MAX_VALUE表示。
23.以下表達式的運行結果是:
[1<2<3,3<2<1]
A.[true,true]
B.[true,false]
C.報錯
D.其他
A
1<2,返回true,執行true<3,會強制將true轉換為1,1<3,最終返回true。
3<2,返回false,執行false<1,會強制將false轉換為0,0<1,最終返回true。
24.以下表達式的運行結果是:
2 == [[[2]]]
A.true
B.false
C.undefined
D.其他
A
使用a==b判斷a和b對象是否相等,可以會將b對象強制轉換為a對象的類型,即執行2 == [[[2]]],會隱式調用parseInt([[[2]]])將[[[2]]]強制轉化為數字基本量,即2,2==2,最終返回true。
25.以下表達式的運行結果是:
[3.toString(),3..toString(),3...toString()]
A.["3",error,error]
B.["3","3.0",error]
C.[error,"3",error]
D.其他
C
Number中的toString(a),能夠將數值轉化成為a進制的值。但a缺省時,默認轉化為十進制。
一般使用方法為:var n = 3;3.toString();
執行3.toString(),因為3只是為數值型變量,為非Number實例,因此對於3不能直接調用Number方法。而執行3..toString(),會強制將3轉化為數字實例,因此能夠被解釋,輸出3,同樣可以使用(3).toString()。
26.以下表達式的運行結果是:
(function(){
var x1 =y1 =1;
})();
console.info(y1);
console.info(x1);
A.1,1
B.error,error
C.1,error
D.其他
C
在立即調用函數內執行,var x1 =y1 =1;創建局部變量x1和全局變量y1。函數外部試圖訪問函數內部的變量,將會導致錯誤。
27.列舉IE和FF腳本兼容性的問題列舉IE和FF腳本兼容性的問題
(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)
28.以下函數有什么問題?如何改進?
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條:使用立即調用的函數表達式創建局部作用域
29.寫一段代碼
判斷一個字符串中出現次數最多的字符,並統計出現的次數。
使用常規方法和正則表達式匹配兩種算法
/*寫一段代碼。判斷一個字符串中出現次數最多的字符串,並統計出現的次數*/
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);
30.請問一下兩段代碼有什么不同?
(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都需要等待當前事件處理完才能執行。
原文鏈接:一道常被人輕視的前端JS面試題
年前剛剛離職了,分享下我曾經出過的一道面試題,此題是我出的一套前端面試題中的最后一題,用來考核面試者的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中構造函數可以有返回值也可以沒有。
1、沒有返回值則按照其他語言一樣返回實例化對象。
2、若有返回值則檢查其返回值是否為引用類型。如果是非引用類型,如基本類型(string,number,boolean,null,undefined)則與無返回值相同,實際返回其實例化對象。
3、若返回值是引用類型,則實際返回值為這個引用類型。
原題中,返回的是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一些特性。
並祝願大家在新的一年找工作面試中膽大心細,發揮出最好的水平,找到一份理想的工作。
來源:javascript小記一筆——(高階函數、map、reduce、filter、sort、reverse)
高階函數就是可以將函數作為另一個函數的參數。
例如:將兩個數的平方相加,這里匿名函數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)——————
1、新的 HTML5 文檔類型和字符集是?
HTML5 文檔類型很簡單:<!doctype html>
HTML5 使用 UTF-8 編碼示例:
2、HTML5 中如何嵌入音頻?
HTML5 支持 MP3、Wav 和 Ogg 格式的音頻,下面是在網頁中嵌入音頻的簡單示例:
<audio controls> <source src=”jamshed.mp3″ type=”audio/mpeg”> Your browser does’nt support audio embedding feature. </audio>
3、HTML5 中如何嵌入視頻?
和音頻類似,HTML5 支持 MP4、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>
|
更新時間: 2015-10-9
HTML
HTML5的離線儲存怎么使用,工作原理能不能解釋一下?
在用戶沒有與因特網連接時,可以正常訪問站點或應用,在用戶與因特網連接時,更新用戶機器上的緩存文件。
原理:HTML5的離線存儲是基於一個新建的.appcache文件的緩存機制(不是存儲技術),通過這個文件上的解析清單離線存儲資源,這些資源就會像cookie一樣被存儲了下來。之后當網絡在處於離線狀態下時,瀏覽器會通過被離線存儲的數據進行頁面展示。
如何使用:
1、頁面頭部像下面一樣加入一個manifest的屬性;
2、在cache.manifest文件的編寫離線存儲的資源;
CACHE MANIFEST
#v0.11
CACHE:
js/app.js
css/style.css
NETWORK:
resourse/logo.png
FALLBACK:
/ /offline.html
3、在離線狀態時,操作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++) {}