【編碼題篇】收集整理來自網絡上的一些常見的 經典前端、H5面試題 Web前端開發面試題

 

編寫一個方法 求一個字符串的字節長度
假設:一個英文字符佔用一個字節,一箇中文字符佔用兩個字節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

<img src="t.jpg" width="1366" height="768" border="0" usemap="#Map" />
<map name="Map" id="Map">
 <area shape="circle" coords="821,289,68" href="www.baidu.com" target="_blank" />
</map>

使用Dreamweaver製做熱點會變得很是的容易,最終會造成上面的代碼,具體的操做,能夠參考視頻,http://www.chuanke.com/3885380-190205.html。

2. border-radius(H5)

<style>
 .disc{
     width:100px;
     height:100px;
     background-color:dimgray;
     border-radius: 50%;
     cursor: pointer;
     position: absolute;
     left:50px;
     top:50px;    
     line-height: 100px;
     text-align: center;
     color: white;
 }
</style>
<div class="disc">智學無憂</div>

運行效果

 
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、彈性圖片(給寬度,高度會自適應,不失真)
            四、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>

 

3、Viewport
<!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>
 
(內容1)——————

5個經典的前端面試問題,你行嗎?

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

 

 

2017.8.31收集

JavaScript-有意思的30題_題目

來源:溫故js系列(13.2)-有意思的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運算符優先級:

image_thumb

參考連接: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中構造函數能夠有返回值也能夠沒有。

一、沒有返回值則按照其餘語言同樣返回實例化對象。

image_thumb1

二、如有返回值則檢查其返回值是否爲引用類型。若是是非引用類型,如基本類型(string,number,boolean,null,undefined)則與無返回值相同,實際返回其實例化對象。

image_thumb2

三、若返回值是引用類型,則實際返回值爲這個引用類型。

image_thumb3

原題中,返回的是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)——————

10個最多見的 HTML5 面試題及答案

一、新的 HTML5 文檔類型和字符集是?

HTML5 文檔類型很簡單:<!doctype html>

HTML5 使用 UTF-8 編碼示例:

<meta charset=」UTF-8″>

二、HTML5 中如何嵌入音頻?

HTML5 支持 MP三、Wav 和 Ogg 格式的音頻,下面是在網頁中嵌入音頻的簡單示例:

<audio controls>
    <source src=」jamshed.mp3″ type=」audio/mpeg」>
    Your browser does’nt support audio embedding feature.
</audio>

三、HTML5 中如何嵌入視頻?

和音頻相似,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>
 

更新時間: 2015-10-9

HTML

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++) {}
相關文章
相關標籤/搜索