2018年web前端經典面試題及答案

閱讀目錄javascript

本篇收錄了一些面試中常常會遇到的經典面試題以及本身面試過程當中遇到的一些問題,而且都給出了我在網上收集的答案。立刻就要過春節了,開年就是嶄新的一年,相信不少的前端開發者會有一些跳槽的悸動,經過對本篇知識的整理以及經驗的總結,但願能幫到更多的前端面試者。(若有錯誤或更好的答案,歡迎指正,水平有限,望各位不吝指教。:)css

另外,宣傳一下本身發佈不久的一個前端vue的項目:基於vue2.0 +vuex+ element-ui後臺管理系統。但願有興趣的同窗,能夠一塊兒共同窗習。html

- 【效果演示地址】【github地址前端

javascript:

 JavaScript中如何檢測一個變量是一個String類型?請寫出函數實現

方法一、vue

function isString(obj){
    return typeof(obj) === "string"? true: false;
    // returntypeof obj === "string"? true: false;
}

方法二、java

function isString(obj){
    return obj.constructor === String? true: false;
}

方法3.jquery

function isString(obj){
     return Object.prototype.toString.call(obj) === "[object String]"?true:false;
}
如:
var isstring = isString('xiaoming');
console.log(isstring);  // true

請用js去除字符串空格?

方法一:使用replace正則匹配的方法

去除全部空格: str = str.replace(/\s*/g,"");      css3

去除兩頭空格: str = str.replace(/^\s*|\s*$/g,"");nginx

去除左空格: str = str.replace( /^\s*/, 「」);git

去除右空格: str = str.replace(/(\s*$)/g, "");

str爲要去除空格的字符串,實例以下:

var str = " 23 23 ";
var str2 = str.replace(/\s*/g,"");
console.log(str2); // 2323

方法二:使用str.trim()方法

str.trim()侷限性:沒法去除中間的空格,實例以下:

var str = "   xiao  ming   ";
var str2 = str.trim();
console.log(str2);   //xiao  ming 

同理,str.trimLeft(),str.trimRight()分別用於去除字符串左右空格。

方法三:使用jquery,$.trim(str)方法

$.trim(str)侷限性:沒法去除中間的空格,實例以下:

var str = "   xiao  ming   ";
var str2 = $.trim(str)
console.log(str2);   //  xiao  ming

你如何獲取瀏覽器URL中查詢字符串中的參數?

測試地址爲:http://www.runoob.com/jquery/misc-trim.html?channelid=12333&name=xiaoming&age=23

實例以下:

function showWindowHref(){
    var sHref = window.location.href;
    var args = sHref.split('?');
    if(args[0] == sHref){
        return "";
    }
    var arr = args[1].split('&');
    var obj = {};
    for(var i = 0;i< arr.length;i++){
        var arg = arr[i].split('=');
        obj[arg[0]] = arg[1];
    }
    return obj;
}
var href = showWindowHref(); // obj
console.log(href['name']); // xiaoming

 

js 字符串操做函數

  我這裏只是列舉了經常使用的字符串函數,具體使用方法,請參考網址

  • concat() – 將兩個或多個字符的文本組合起來,返回一個新的字符串。

  • indexOf() – 返回字符串中一個子串第一處出現的索引。若是沒有匹配項,返回 -1 。

  • charAt() – 返回指定位置的字符。

  • lastIndexOf() – 返回字符串中一個子串最後一處出現的索引,若是沒有匹配項,返回 -1 。

  • match() – 檢查一個字符串是否匹配一個正則表達式。

  • substr() 函數 -- 返回從string的startPos位置,長度爲length的字符串

  • substring() – 返回字符串的一個子串。傳入參數是起始位置和結束位置。

  • slice() – 提取字符串的一部分,並返回一個新字符串。

  • replace() – 用來查找匹配一個正則表達式的字符串,而後使用新字符串代替匹配的字符串。

  • search() – 執行一個正則表達式匹配查找。若是查找成功,返回字符串中匹配的索引值。不然返回 -1 。

  • split() – 經過將字符串劃分紅子串,將一個字符串作成一個字符串數組。

  • length – 返回字符串的長度,所謂字符串的長度是指其包含的字符的個數。

  • toLowerCase() – 將整個字符串轉成小寫字母。

  • toUpperCase() – 將整個字符串轉成大寫字母。

怎樣添加、移除、移動、複製、建立和查找節點?

 1)建立新節點

  createDocumentFragment() //建立一個DOM片斷
  createElement() //建立一個具體的元素
  createTextNode() //建立一個文本節點

2)添加、移除、替換、插入
  appendChild() //添加
  removeChild() //移除
  replaceChild() //替換
  insertBefore() //插入

3)查找
  getElementsByTagName() //經過標籤名稱
  getElementsByName() //經過元素的Name屬性的值
  getElementById() //經過元素Id,惟一性

寫出3個使用this的典型應用

(1)、在html元素事件屬性中使用,如:

<input type=」button」 onclick=」showInfo(this);」 value=」點擊一下」/>

(2)、構造函數

function Animal(name, color) {
  this.name = name;
  this.color = color;
}

(3)、input點擊,獲取值

<input type="button" id="text" value="點擊一下" />
<script type="text/javascript">
    var btn = document.getElementById("text");
    btn.onclick = function() {
        alert(this.value);    //此處的this是按鈕元素
    }
</script>

(4)、apply()/call()求數組最值

var  numbers = [5, 458 , 120 , -215 ]; 
var  maxInNumbers = Math.max.apply(this, numbers);  
console.log(maxInNumbers);  // 458
var maxInNumbers = Math.max.call(this,5, 458 , 120 , -215); 
console.log(maxInNumbers);  // 458

比較typeof與instanceof?

相同點:JavaScript 中 typeof 和 instanceof 經常使用來判斷一個變量是否爲空,或者是什麼類型的。

typeof的定義和用法:返回值是一個字符串,用來講明變量的數據類型。

細節:

(1)、typeof 通常只能返回以下幾個結果:number,boolean,string,function,object,undefined。

(2)、typeof 來獲取一個變量是否存在,如 if(typeof a!="undefined"){alert("ok")},而不要去使用 if(a) 由於若是 a 不存在(未聲明)則會出錯。

(3)、對於 Array,Null 等特殊對象使用 typeof 一概返回 object,這正是 typeof 的侷限性。

Instanceof定義和用法:instanceof 用於判斷一個變量是否屬於某個對象的實例。

實例演示:

a instanceof b?alert("true"):alert("false"); //a是b的實例?真:假

var a = new Array(); 
alert(a instanceof Array);  // true
alert(a instanceof Object)  // true

如上,會返回 true,同時 alert(a instanceof Object) 也會返回 true;這是由於 Array 是 object 的子類。

function test(){};
var a = new test();
alert(a instanceof test)   // true

細節:

(1)、以下,獲得的結果爲‘N’,這裏的 instanceof 測試的 object 是指 js 語法中的 object,不是指 dom 模型對象。

if (window instanceof Object){ alert('Y')} else {  alert('N');}  // 'N'

 如何理解閉包?

一、定義和用法:當一個函數的返回值是另一個函數,而返回的那個函數若是調用了其父函數內部的其它變量,若是返回的這個函數在外部被執行,就產生了閉包。

二、表現形式:使函數外部可以調用函數內部定義的變量。

三、實例以下:

(1)、根據做用域鏈的規則,底層做用域沒有聲明的變量,會向上一級找,找到就返回,沒找到就一直找,直到window的變量,沒有就返回undefined。這裏明顯count 是函數內部的flag2 的那個count 。

var count=10;   //全局做用域 標記爲flag1
function add(){
    var count=0;    //函數全局做用域 標記爲flag2
    return function(){
        count+=1;   //函數的內部做用域
        alert(count);
    }
}
var s = add()
s();//輸出1
s();//輸出2

四、變量的做用域

要理解閉包,首先必須理解Javascript特殊的變量做用域。

變量的做用域分類:全局變量和局部變量。

特色:

一、函數內部能夠讀取函數外部的全局變量;在函數外部沒法讀取函數內的局部變量。

二、函數內部聲明變量的時候,必定要使用var命令。若是不用的話,你實際上聲明瞭一個全局變量!

 五、使用閉包的注意點

1)濫用閉包,會形成內存泄漏:因爲閉包會使得函數中的變量都被保存在內存中,內存消耗很大,因此不能濫用閉包,不然會形成網頁的性能問題,在IE中可能致使內存泄露。解決方法是,在退出函數以前,將不使用的局部變量所有刪除。

2)會改變父函數內部變量的值。因此,若是你把父函數看成對象(object)使用,把閉包看成它的公用方法(Public Method),把內部變量看成它的私有屬性(private value),這時必定要當心,不要隨便改變父函數內部變量的值。

 

 什麼是跨域?跨域請求資源的方法有哪些?

一、什麼是跨域?

因爲瀏覽器同源策略,凡是發送請求url的協議、域名、端口三者之間任意一與當前頁面地址不一樣即爲跨域。存在跨域的狀況:

  • 網絡協議不一樣,如http協議訪問https協議。

  • 端口不一樣,如80端口訪問8080端口。

  • 域名不一樣,如qianduanblog.com訪問baidu.com。

  • 子域名不一樣,如abc.qianduanblog.com訪問def.qianduanblog.com。

  • 域名和域名對應ip,如www.a.com訪問20.205.28.90.

二、跨域請求資源的方法:

(1)、porxy代理

定義和用法:proxy代理用於將請求發送給後臺服務器,經過服務器來發送請求,而後將請求的結果傳遞給前端。

實現方法:經過nginx代理;

注意點:一、若是你代理的是https協議的請求,那麼你的proxy首先須要信任該證書(尤爲是自定義證書)或者忽略證書檢查,不然你的請求沒法成功。

(2)、CORS 【Cross-Origin Resource Sharing】

定義和用法:是現代瀏覽器支持跨域資源請求的一種最經常使用的方式。

使用方法:通常須要後端人員在處理請求數據的時候,添加容許跨域的相關操做。以下:

res.writeHead(200, {
    "Content-Type": "text/html; charset=UTF-8",
    "Access-Control-Allow-Origin":'http://localhost',
    'Access-Control-Allow-Methods': 'GET, POST, OPTIONS',
    'Access-Control-Allow-Headers': 'X-Requested-With, Content-Type'
});

(3)、jsonp

定義和用法:經過動態插入一個script標籤。瀏覽器對script的資源引用沒有同源限制,同時資源加載到頁面後會當即執行(沒有阻塞的狀況下)。

特色:經過狀況下,經過動態建立script來讀取他域的動態資源,獲取的數據通常爲json格式。

實例以下:

<script>
    function testjsonp(data) {
       console.log(data.name); // 獲取返回的結果
    }
</script>
<script>
    var _script = document.createElement('script');
    _script.type = "text/javascript";
    _script.src = "http://localhost:8888/jsonp?callback=testjsonp";
    document.head.appendChild(_script);
</script>

缺點:

  一、這種方式沒法發送post請求(這裏)

  二、另外要肯定jsonp的請求是否失敗並不容易,大多數框架的實現都是結合超時時間來斷定。

談談垃圾回收機制方式及內存管理

回收機制方式

一、定義和用法:垃圾回收機制(GC:Garbage Collection),執行環境負責管理代碼執行過程當中使用的內存。

二、原理:垃圾收集器會按期(週期性)找出那些不在繼續使用的變量,而後釋放其內存。可是這個過程不是實時的,由於其開銷比較大,因此垃圾回收器會按照固定的時間間隔週期性的執行。

三、實例以下:

function fn1() {
    var obj = {name: 'hanzichi', age: 10};
}
function fn2() {
    var obj = {name:'hanzichi', age: 10};
   return obj;
}
var a = fn1();
var b = fn2();

fn1中定義的obj爲局部變量,而當調用結束後,出了fn1的環境,那麼該塊內存會被js引擎中的垃圾回收器自動釋放;在fn2被調用的過程當中,返回的對象被全局變量b所指向,因此該塊內存並不會被釋放。

 四、垃圾回收策略:標記清除(較爲經常使用)和引用計數。

標記清除:

  定義和用法:當變量進入環境時,將變量標記"進入環境",當變量離開環境時,標記爲:"離開環境"。某一個時刻,垃圾回收器會過濾掉環境中的變量,以及被環境變量引用的變量,剩下的就是被視爲準備回收的變量。

  到目前爲止,IE、Firefox、Opera、Chrome、Safari的js實現使用的都是標記清除的垃圾回收策略或相似的策略,只不過垃圾收集的時間間隔互不相同。

引用計數:

  定義和用法:引用計數是跟蹤記錄每一個值被引用的次數。

  基本原理:就是變量的引用次數,被引用一次則加1,當這個引用計數爲0時,被視爲準備回收的對象。

 內存管理

一、何時觸發垃圾回收?

垃圾回收器週期性運行,若是分配的內存很是多,那麼回收工做也會很艱鉅,肯定垃圾回收時間間隔就變成了一個值得思考的問題。

IE6的垃圾回收是根據內存分配量運行的,當環境中的變量,對象,字符串達到必定數量時觸發垃圾回收。垃圾回收器一直處於工做狀態,嚴重影響瀏覽器性能。

IE7中,垃圾回收器會根據內存分配量與程序佔用內存的比例進行動態調整,開始回收工做。

二、合理的GC方案:(1)、遍歷全部可訪問的對象; (2)、回收已不可訪問的對象。

三、GC缺陷:(1)、中止響應其餘操做;

四、GC優化策略:(1)、分代回收(Generation GC);(2)、增量GC

開發過程當中遇到的內存泄露狀況,如何解決的?

一、定義和用法:

內存泄露是指一塊被分配的內存既不能使用,又不能回收,直到瀏覽器進程結束。C#和Java等語言採用了自動垃圾回收方法管理內存,幾乎不會發生內存泄露。咱們知道,瀏覽器中也是採用自動垃圾回收方法管理內存,但因爲瀏覽器垃圾回收方法有bug,會產生內存泄露。

二、內存泄露的幾種狀況:

(1)、當頁面中元素被移除或替換時,若元素綁定的事件仍沒被移除,在IE中不會做出恰當處理,此時要先手工移除事件,否則會存在內存泄露。

實例以下:

<div id="myDiv">
    <input type="button" value="Click me" id="myBtn">
</div>
<script type="text/javascript">
    var btn = document.getElementById("myBtn");
    btn.onclick = function(){
        document.getElementById("myDiv").innerHTML = "Processing...";
    }
</script>

解決方法以下:

<div id="myDiv">
    <input type="button" value="Click me" id="myBtn">
</div>
<script type="text/javascript">
    var btn = document.getElementById("myBtn");
    btn.onclick = function(){
    btn.onclick = null;
        document.getElementById("myDiv").innerHTML = "Processing...";
    }
</script>
(2)、因爲是函數內定義函數,而且內部函數--事件回調的引用外暴了,造成了閉包。閉包能夠維持函數內局部變量,使其得不到釋放。
實例以下:
function bindEvent(){
    var obj=document.createElement("XXX");
    obj.onclick=function(){
        //Even if it's a empty function
    }
}

解決方法以下:

function bindEvent(){
    var obj=document.createElement("XXX");
    obj.onclick=function(){
         //Even if it's a empty function
    }
    obj=null;
}

 javascript面向對象中繼承實現?

面向對象的基本特徵有:封閉、繼承、多態。

在JavaScript中實現繼承的方法:

1. 原型鏈(prototype chaining)

2. call()/apply()

3. 混合方式(prototype和call()/apply()結合)

4. 對象冒充

繼承的方法以下:

一、prototype原型鏈方式:

function teacher(name){
    this.name = name;
}
teacher.prototype.sayName = function(){
    console.log("name is "+this.name);
}
var teacher1 = new teacher("xiaoming");
teacher1.sayName();

function student(name){
    this.name = name;
}
student.prototype = new teacher()
var student1 = new student("xiaolan");
student1.sayName();
//  name is xiaoming
//  name is xiaolan
二、call()/apply()方法
function teacher(name,age){
    this.name = name;
    this.age = age;
    this.sayhi  = function(){
      alert('name:'+name+",  age:"+age);
   }
}
function student(){
  var args = arguments;
  teacher.call(this,args[0],args[1]);
  // teacher.apply(this,arguments);
}
var teacher1 = new teacher('xiaoming',23);
teacher1.sayhi();

var student1 = new student('xiaolan',12);
student1.sayhi();

// alert: name:xiaoming,  age:23
// alert: name:xiaolan,  age:12
三、混合方法【prototype,call/apply】
function teacher(name,age){
   this.name = name;
   this.age = age;
}
teacher.prototype.sayName = function(){
   console.log('name:'+this.name);
}
teacher.prototype.sayAge = function(){
   console.log('age:'+this.age);
}

function student(){
  var args = arguments;
  teacher.call(this,args[0],args[1]);
}
student.prototype = new teacher();

var student1 = new student('xiaolin',23);
student1.sayName();
student1.sayAge();
// name:xiaolin
// age:23
四、對象冒充
function Person(name,age){
   this.name = name;
   this.age = age;
   this.show = function(){
         console.log(this.name+",  "+this.age);
   }
}

function Student(name,age){ 
   this.student = Person;       //將Person類的構造函數賦值給this.student
   this.student(name,age);   //js中其實是經過對象冒充來實現繼承的
   delete this.student;           //移除對Person的引用
}

var s = new Student("小明",17);
s.show();

var p = new Person("小花",18);
p.show();
// 小明,  17
// 小花,  18

javascript相關程序計算題

一、判斷一個字符串中出現次數最多的字符,統計這個次數

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;
    }
}        
console.log('出現次數最多的是:'+iIndex+'出現'+iMax+'次');

結果以下:出現次數最多的是:a出現9次

JavaScript 數組(Array)對象

一、Array相關的屬性和方法

這裏只是作了相關的列舉,具體的使用方法,請參考網址

Array 對象屬性

constructor 返回對建立此對象的數組函數的引用。

var test=new Array();

if (test.constructor==Array)
{
document.write("This is an Array");
}
if (test.constructor==Boolean)
{
document.write("This is a Boolean");
}
if (test.constructor==Date)
{
document.write("This is a Date");
}
if (test.constructor==String)
{
document.write("This is a String");
}

length 設置或返回數組中元素的數目。

prototype 使您有能力向對象添加屬性和方法。

Array 對象方法

concat() 鏈接兩個或更多的數組,並返回結果。

var arr = [1,2,3,4];
var arr2 = [5,6,7,8];
var arr3 = arr.concat(arr2);
console.log(arr3); // 鏈接以後返回的數組爲:[1, 2, 3, 4, 5, 6, 7, 8]

join() 把數組的全部元素放入一個字符串。元素經過指定的分隔符進行分隔。

var arr = ['xiao','lin','qiqi','mingtian'];
var arr2 = arr.join(',');
console.log(arr2); // 根據','隔開返回的字符串爲:"xiao,lin,qiqi,mingtian"

pop() 刪除並返回數組的最後一個元素。  

var arr = [2,3,4,5];
var arr2 = arr.pop();
console.log(arr2); // 刪除的數組的最後一個元素爲:5
console.log(arr);  // 刪除元素以後的數組爲:[2, 3, 4]

shift() 刪除並返回數組的第一個元素

var arr = [2,3,4,5];
var arr2 = arr.shift();
console.log(arr2); // 刪除的數組的第一個元素爲:2
console.log(arr);  // 刪除元素以後的數組爲:[3, 4,5]

push() 向數組的末尾添加一個或更多元素,並返回新的長度。

var arr = [2,3,4,5];
var arr2 = arr.push(6);
console.log(arr2);  // 返回的數組長度:5 
console.log(arr);  // [2, 3, 4, 5, 6]

unshift() 向數組的開頭添加一個或更多元素,並返回新的長度。

var arr = ['xiao','ming','qiqi','aiming'];
var arr1 = arr.unshift('lang');
console.log(arr1);  // 返回的數組的長度:  5
console.log(arr);  //向數組開頭添加元素返回的結果:["lang", "xiao", "ming", "qiqi", "aiming"]

reverse() 顛倒數組中元素的順序。

var arr = [2,3,4,5];
arr.reverse();
console.log(arr);   //  [5, 4, 3, 2]

slice() 從某個已有的數組返回選定的元素

var arr = [2,3,4,5];
var arr2 = arr.slice(1,3);
console.log(arr2);  // 截取區間返回的數組爲:[3, 4]
console.log(arr);  // [2, 3, 4, 5]

sort() 對數組的元素進行排序

藉助排序函數,實現數值由小到大排序
function sortNumber(a,b){
    return a - b
}
var arr = [23,30,42,5];
var arr2 = arr.sort(sortNumber);
console.log(arr2);  // [5, 23, 30, 42]
console.log(arr);   // [5, 23, 30, 42]

藉助排序函數,實現數值由大到小排序
function sortNumber(a,b){
    return b - a
}
var arr = [23,30,42,5];
var arr2 = arr.sort(sortNumber);
console.log(arr2);  // [42, 30, 23, 5]
console.log(arr);  // [42, 30, 23, 5]

splice() 刪除元素,並向數組添加新元素。

語法:arrayObject.splice(index,howmany,item1,.....,itemX)
index:必需。整數,規定添加/刪除項目的位置,使用負數可從數組結尾處規定位置。
howmany:必需。要刪除的項目數量。若是設置爲 0,則不會刪除項目。
item1, ..., itemX:可選。向數組添加的新項目。

// 建立一個新數組,並向其添加一個元素
var arr = [1,2,3,4];
arr.splice(2,0,5);
console.log(arr);  // [1, 2, 5, 3, 4]

// 刪除位於 index 2 的元素,並添加一個新元素來替代被刪除的元素:
var arr = [1,2,3,4];
arr.splice(2,1,5);
console.log(arr);  // [1, 2, 5, 4]

toSource() 返回該對象的源代碼。

瀏覽器支持
只有 Gecko 核心的瀏覽器(好比 Firefox)支持該方法,也就是說 IE、Safari、Chrome、Opera 等瀏覽器均不支持該方法。
<script type="text/javascript">
function employee(name,job,born){
    this.name=name;
    this.job=job;
    this.born=born;
}
var bill = new employee("Bill Gates","Engineer",1985);
document.write(bill.toSource());
</script>
輸出:({name:"Bill Gates", job:"Engineer", born:1985}) 

toString() 把數組轉換爲字符串,並返回結果。

var arr = ['xiao','ming','qiqi','aiming'];
arr.toString();
console.log(arr);  // ["xiao", "ming", "qiqi", "aiming"]

toLocaleString() 把數組轉換爲本地數組,並返回結果。

var arr = ['xiao','ming','qiqi','aiming'];
arr.toLocaleString();
console.log(arr);  // ["xiao", "ming", "qiqi", "aiming"]

valueOf() 返回數組對象的原始值

var arr = ['xiao','ming','qiqi','aiming'];
arr.valueOf('lang');
console.log(arr); // ["xiao", "ming", "qiqi", "aiming"]

二、編寫一個方法 去掉一個數組的重複元素

方法一:

var arr = [0,2,3,4,4,0,2];
var obj = {};
var tmp = [];
for(var i = 0 ;i< arr.length;i++){
   if( !obj[arr[i]] ){
      obj[arr[i]] = 1;
      tmp.push(arr[i]);
   }
}
console.log(tmp);

結果以下: [0, 2, 3, 4]

 方法二:

var arr = [2,3,4,4,5,2,3,6],
   arr2 = [];
for(var i = 0;i< arr.length;i++){
    if(arr2.indexOf(arr[i]) < 0){
        arr2.push(arr[i]);
    }
}
console.log(arr2);

結果爲:[2, 3, 4, 5, 6]

 方法三:

var arr = [2,3,4,4,5,2,3,6];
var arr2 = arr.filter(function(element,index,self){
return self.indexOf(element) === index;
});
console.log(arr2);

結果爲:[2, 3, 4, 5, 6]

三、求數組的最值?

方法一:

  • 求數組最大值:Math.max.apply(null,arr);

var arr = [3,43,23,45,65,90];
var max = Math.max.apply(null,arr);
console.log(max);
// 90

  • 求數組最小值:Math.min.apply(null,arr);

var arr = [3,43,23,45,65,90];
var min = Math.min.apply(null,arr);
console.log(min);
// 3

方法二:Array.max = function(arr){} / Array.min = function(arr){}

var array = [3,43,23,45,65,90];

Array.max = function( array ){ 
   return Math.max.apply( Math, array );
};
Array.min = function( array ){ 
   return Math.min.apply( Math, array );
};

var max = Array.max(array);
console.log(max);  // 90

var min = Array.min(array);
console.log(min);  // 3

方法三:Array.prototype.max = function(){};Array.prototype.min = function(){};

  • 求數組最大值(基本思路:將數組中的第一個值賦值給變量max ,將數組進行循環與max進行比較,將數組中的大值賦給max,最後返回max;)

var arr = [3,43,23,45,65,90];
Array.prototype.max = function() { 
    var max = this[0];
    var len = this.length; 
    for (var i = 0; i < len; i++){ 
        if (this[i] > max) { 
          max = this[i]; 
        } 
    } 
    return max;
}
var max = arr.max();
console.log(max);  // 90
  • 求數組最小值:
var arr = [3,43,23,45,65,90];
Array.prototype.min = function() { 
    var min = this[0];
    var len = this.length;
    for(var i = 0;i< len;i++){
        if(this[i] < min){
            min = this[i];
        }
    }
    return min;
}
var min = arr.min();
console.log(min);  // 3

四、數組排序相關

    結合sort和函數排序:

  • 數組由小到大進行排序:sort,sortnum;
var arr = [3,43,23,45,65,90];
function sortnum(a,b){
  return a-b;
}
arr = arr.sort(sortnum);
console.log(arr);
// [3, 23, 43, 45, 65, 90]
  • 數組由大到小進行排序:sort,sortnum;
var arr = [3,43,23,45,65,90];
function sortnum(a,b){
  return a+b;
}
arr = arr.sort(sortnum);
console.log(arr);
// [90, 65, 45, 23, 43, 3]

冒泡排序:即實現數組由小到大進行排序;思路爲:每次比較相鄰的兩個數,若是後一個比前一個小,換位置。若是要實現由大到小排序,使用reverse()便可;

var arr = [3, 1, 4, 6, 5, 7, 2];

function bubbleSort(arr) {
    var len = arr.length;
    for (var i = len; i >= 2; --i) {
        for (var j = 0; j < i - 1; j++) {
            if (arr[j + 1] < arr[j]) {
                var temp;
                temp = arr[j];
                arr[j] = arr[j + 1];
                arr[j + 1] = temp;
            }
        }
    }
    return arr;
}

var arr2 = bubbleSort(arr); 
console.log(arr2); // [1, 2, 3, 4, 5, 6, 7]
var arr3 = arr2.reverse();
console.log(arr3); //  [7, 6, 5, 4, 3, 2, 1]

快速排序:

思路:採用二分法,取出中間數,數組每次和中間數比較,小的放到左邊,大的放到右邊。

var arr = [3, 1, 4, 6, 5, 7, 2];
function quickSort(arr) {
    if(arr.length == 0) {
        return [];  // 返回空數組
    }
    var cIndex = Math.floor(arr.length / 2);
    var c = arr.splice(cIndex, 1);
    var l = [];
    var r = [];

    for (var i = 0; i < arr.length; i++) {
        if(arr[i] < c) {
            l.push(arr[i]);
        } else {
            r.push(arr[i]);
        }
    }
    return quickSort(l).concat(c, quickSort(r));
}
console.log(quickSort(arr));
//[1, 2, 3, 4, 5, 6, 7]

五、數組的翻轉(非reverse())

方法一:

var arr = [1,2,3,4];
var arr2 = [];
while(arr.length) {
    var num = arr.pop(); //刪除數組最後一個元素並返回被刪除的元素
    arr2.push(num);
}
console.log(arr2);
// [4, 3, 2, 1]

方法二:

var arr = [1,2,3,4];
var arr2 = [];
while(arr.length){
    var num = arr.shift(); //刪除數組第一個元素並返回被刪除的元素
    arr2.unshift(num);
}
console.log(arr2);

 

jquery相關

一、 jQuery 庫中的 $() 是什麼?

  $() 函數是 jQuery() 函數的別稱。$() 函數用於將任何對象包裹成 jQuery 對象,接着你就被容許調用定義在 jQuery 對象上的多個不一樣方法。你能夠將一個選擇器字符串傳入 $() 函數,它會返回一個包含全部匹配的 DOM 元素數組的 jQuery 對象。

二、如何找到全部 HTML select 標籤的選中項?

$('[name=selectname] :selected')

三、$(this) 和 this 關鍵字在 jQuery 中有何不一樣?

$(this) 返回一個 jQuery 對象,你能夠對它調用多個 jQuery 方法,好比用 text() 獲取文本,用val() 獲取值等等。

而 this 表明當前元素,它是 JavaScript 關鍵詞中的一個,表示上下文中的當前 DOM 元素。你不能對它調用 jQuery 方法,直到它被 $() 函數包裹,例如 $(this)。

四、jquery怎麼移除標籤onclick屬性?

得到a標籤的onclick屬性: $("a").attr("onclick")

刪除onclick屬性:$("a").removeAttr("onclick");

設置onclick屬性:$("a").attr("onclick","test();");

五、jquery中addClass,removeClass,toggleClass的使用。

$(selector).addClass(class):爲每一個匹配的元素添加指定的類名

$(selector).removeClass(class):從全部匹配的元素中刪除所有或者指定的類,刪除class中某個值;

$(selector).toggleClass(class):若是存在(不存在)就刪除(添加)一個類

$(selector).removeAttr(class);刪除class這個屬性;

六、JQuery有幾種選擇器?

(1)、基本選擇器:#id,class,element,*;

(2)、層次選擇器:parent > child,prev + next ,prev ~ siblings

(3)、基本過濾器選擇器::first,:last ,:not ,:even ,:odd ,:eq ,:gt ,:lt

(4)、內容過濾器選擇器: :contains ,:empty ,:has ,:parent

(5)、可見性過濾器選擇器::hidden ,:visible

(6)、屬性過濾器選擇器:[attribute] ,[attribute=value] ,[attribute!=value] ,[attribute^=value] ,[attribute$=value] ,[attribute*=value]

(7)、子元素過濾器選擇器::nth-child ,:first-child ,:last-child ,:only-child

(8)、表單選擇器: :input ,:text ,:password ,:radio ,:checkbox ,:submit 等;

(9)、表單過濾器選擇器::enabled ,:disabled ,:checked ,:selected

七、jQuery中的Delegate()函數有什麼做用?

   delegate()會在如下兩個狀況下使用到:

 一、若是你有一個父元素,須要給其下的子元素添加事件,這時你可使用delegate()了,代碼以下:

$("ul").delegate("li", "click", function(){ $(this).hide(); });

 二、當元素在當前頁面中不可用時,可使用delegate()

八、$(document).ready()方法和window.onload有什麼區別?

 (1)、window.onload方法是在網頁中全部的元素(包括元素的全部關聯文件)徹底加載到瀏覽器後才執行的。

 (2)、$(document).ready() 方法能夠在DOM載入就緒時就對其進行操縱,並調用執行綁定的函數。

九、如何用jQuery禁用瀏覽器的前進後退按鈕?

實現代碼以下:

<script type="text/javascript" language="javascript">
  $(document).ready(function() {
    window.history.forward(1);
      //OR window.history.forward(-1);
  });
</script>

十、 jquery中$.get()提交和$.post()提交有區別嗎?

相同點:都是異步請求的方式來獲取服務端的數據;

異同點:

一、請求方式不一樣:$.get() 方法使用GET方法來進行異步請求的。$.post() 方法使用POST方法來進行異步請求的。

二、參數傳遞方式不一樣:get請求會將參數跟在URL後進行傳遞,而POST請求則是做爲HTTP消息的實體內容發送給Web服務器的,這種傳遞是對用戶不可見的。

三、數據傳輸大小不一樣:get方式傳輸的數據大小不能超過2KB 而POST要大的多

四、安全問題: GET 方式請求的數據會被瀏覽器緩存起來,所以有安全問題。

十一、寫出一個簡單的$.ajax()的請求方式?

$.ajax({
    url:'http://www.baidu.com',
    type:'POST',
    data:data,
    cache:true,
    headers:{},
    beforeSend:function(){},
    success:function(){},
    error:function(){},
    complete:function(){}
}); 

 

 

十二、jQuery的事件委託方法bind 、live、delegate、on之間有什麼區別?

(1)、bind 【jQuery 1.3以前】

定義和用法:主要用於給選擇到的元素上綁定特定事件類型的監聽函數;

語法:bind(type,[data],function(eventObject));

特色:

  (1)、適用於頁面元素靜態綁定。只能給調用它的時候已經存在的元素綁定事件,不能給將來新增的元素綁定事件。

  (2)、當頁面加載完的時候,你才能夠進行bind(),因此可能產生效率問題。

實例以下:$( "#members li a" ).bind( "click", function( e ) {} );

(2)、live 【jQuery 1.3以後】

定義和用法:主要用於給選擇到的元素上綁定特定事件類型的監聽函數;

語法:live(type, [data], fn);

特色:

  (1)、live方法並無將監聽器綁定到本身(this)身上,而是綁定到了this.context上了。

  (2)、live正是利用了事件委託機制來完成事件的監聽處理,把節點的處理委託給了document,新添加的元素沒必要再綁定一次監聽器。

  (3)、使用live()方法但卻只能放在直接選擇的元素後面,不能在層級比較深,連綴的DOM遍歷方法後面使用,即$(「ul」").live...能夠,但$("body").find("ul").live...不行; 

實例以下:$( document ).on( "click", "#members li a", function( e ) {} );

(3)、delegate 【jQuery 1.4.2中引入】

定義和用法:將監聽事件綁定在就近的父級元素上

語法:delegate(selector,type,[data],fn)

特色:

  (1)、選擇就近的父級元素,由於事件能夠更快的冒泡上去,可以在第一時間進行處理。

  (2)、更精確的小範圍使用事件代理,性能優於.live()。能夠用在動態添加的元素上。

實例以下:

$("#info_table").delegate("td","click",function(){/*顯示更多信息*/});

$("table").find("#info").delegate("td","click",function(){/*顯示更多信息*/});

(4)、on 【1.7版本整合了以前的三種方式的新事件綁定機制】

定義和用法:將監聽事件綁定到指定元素上。

語法:on(type,[selector],[data],fn)

實例以下:$("#info_table").on("click","td",function(){/*顯示更多信息*/});參數的位置寫法與delegate不同。

說明:on方法是當前JQuery推薦使用的事件綁定方法,附加只運行一次就刪除函數的方法是one()。

 總結:.bind(), .live(), .delegate(),.on()分別對應的相反事件爲:.unbind(),.die(), .undelegate(),.off()

HTML & CSS:

一、什麼是盒子模型?

在網頁中,一個元素佔有空間的大小由幾個部分構成,其中包括元素的內容(content),元素的內邊距(padding),元素的邊框(border),元素的外邊距(margin)四個部分。這四個部分佔有的空間中,有的部分能夠顯示相應的內容,而有的部分只用來分隔相鄰的區域或區域。4個部分一塊兒構成了css中元素的盒模型。

二、行內元素有哪些?塊級元素有哪些? 空(void)元素有那些?

行內元素:a、b、span、img、input、strong、select、label、em、button、textarea
塊級元素:div、ul、li、dl、dt、dd、p、h1-h六、blockquote
空元素:即系沒有內容的HTML元素,例如:br、meta、hr、link、input、img

三、CSS實現垂直水平居中

一道經典的問題,實現方法有不少種,如下是其中一種實現:
HTML結構:

<div class="wrapper">
     <div class="content"></div>
</div>

CSS:

.wrapper {
    position: relative;
    width: 500px;
    height: 500px;
    border: 1px solid red; 
 }
.content{
    position: absolute;
    width: 200px;
    height: 200px;
    /*top、bottom、left和right 均設置爲0*/
    top: 0;
    bottom: 0;
    left: 0;
    right: 0;
    /*margin設置爲auto*/
    margin:auto;
    border: 1px solid green;    
} 

效果以下:

四、簡述一下src與href的區別

href 是指向網絡資源所在位置,創建和當前元素(錨點)或當前文檔(連接)之間的連接,用於超連接。

src是指向外部資源的位置,指向的內容將會嵌入到文檔中當前標籤所在位置;在請求src資源時會將其指向的資源下載並應用到文檔內,例如js腳本,img圖片和frame等元素。

當瀏覽器解析到該元素時,會暫停其餘資源的下載和處理,直到將該資源加載、編譯、執行完畢,圖片和框架等元素也如此,相似於將所指向資源嵌入當前標籤內。這也是爲何將js腳本放在底部而不是頭部。

五、簡述同步和異步的區別

同步是阻塞模式,異步是非阻塞模式。
同步就是指一個進程在執行某個請求的時候,若該請求須要一段時間才能返回信息,那麼這個進程將會一直等待下去,直到收到返回信息才繼續執行下去;
異步是指進程不須要一直等下去,而是繼續執行下面的操做,無論其餘進程的狀態。當有消息返回時系統會通知進程進行處理,這樣能夠提升執行的效率。

 六、px和em的區別

相同點:px和em都是長度單位;

異同點:px的值是固定的,指定是多少就是多少,計算比較容易。em得值不是固定的,而且em會繼承父級元素的字體大小。
瀏覽器的默認字體高都是16px。因此未經調整的瀏覽器都符合: 1em=16px。那麼12px=0.75em, 10px=0.625em。

七、瀏覽器的內核分別是什麼?

IE: trident內核
Firefox:gecko內核
Safari:webkit內核
Opera:之前是presto內核,Opera現已改用Google Chrome的Blink內核
Chrome:Blink(基於webkit,Google與Opera Software共同開發)

 

 八、什麼叫優雅降級和漸進加強?

漸進加強 progressive enhancement:
針對低版本瀏覽器進行構建頁面,保證最基本的功能,而後再針對高級瀏覽器進行效果、交互等改進和追加功能達到更好的用戶體驗。

優雅降級 graceful degradation:
一開始就構建完整的功能,而後再針對低版本瀏覽器進行兼容。

區別:

a. 優雅降級是從複雜的現狀開始,並試圖減小用戶體驗的供給

b. 漸進加強則是從一個很是基礎的,可以起做用的版本開始,並不斷擴充,以適應將來環境的須要

c. 降級(功能衰減)意味着往回看;而漸進加強則意味着朝前看,同時保證其根基處於安全地帶

 9、sessionStorage 、localStorage 和 cookie 之間的區別

 共同點:用於瀏覽器端存儲的緩存數據

不一樣點:

(1)、存儲內容是否發送到服務器端:當設置了Cookie後,數據會發送到服務器端,形成必定的寬帶浪費;

        web storage,會將數據保存到本地,不會形成寬帶浪費;

(2)、數據存儲大小不一樣:Cookie數據不能超過4K,適用於會話標識;web storage數據存儲能夠達到5M;

(3)、數據存儲的有效期限不一樣:cookie只在設置了Cookid過時時間以前一直有效,即便關閉窗口或者瀏覽器;

        sessionStorage,僅在關閉瀏覽器以前有效;localStorage,數據存儲永久有效;

(4)、做用域不一樣:cookie和localStorage是在同源同學口中都是共享的;sessionStorage不在不一樣的瀏覽器窗口中共享,即便是同一個頁面;

 十、Web Storage與Cookie相比存在的優點:

(1)、存儲空間更大:IE8下每一個獨立的存儲空間爲10M,其餘瀏覽器實現略有不一樣,但都比Cookie要大不少。

(2)、存儲內容不會發送到服務器:當設置了Cookie後,Cookie的內容會隨着請求一併發送的服務器,這對於本地存儲的數據是一種帶寬浪費。而Web Storage中的數據則僅僅是存在本地,不會與服務器發生任何交互。

(3)、更多豐富易用的接口:Web Storage提供了一套更爲豐富的接口,如setItem,getItem,removeItem,clear等,使得數據操做更爲簡便。cookie須要本身封裝。

(4)、獨立的存儲空間:每一個域(包括子域)有獨立的存儲空間,各個存儲空間是徹底獨立的,所以不會形成數據混亂。

 十一、Ajax的優缺點及工做原理?

定義和用法:

AJAX = Asynchronous JavaScript and XML(異步的 JavaScript 和 XML)。Ajax 是一種用於建立快速動態網頁的技術。Ajax 是一種在無需從新加載整個網頁的狀況下,可以更新部分網頁的技術。

傳統的網頁(不使用 Ajax)若是須要更新內容,必須重載整個網頁頁面。

優勢:

1.減輕服務器的負擔,按需取數據,最大程度的減小冗餘請求

2.局部刷新頁面,減小用戶心理和實際的等待時間,帶來更好的用戶體驗

3.基於xml標準化,並被普遍支持,不需安裝插件等,進一步促進頁面和數據的分離

缺點:

1.AJAX大量的使用了javascript和ajax引擎,這些取決於瀏覽器的支持.在編寫的時候考慮對瀏覽器的兼容性.

2.AJAX只是局部刷新,因此頁面的後退按鈕是沒有用的.

3.對流媒體還有移動設備的支持不是太好等

AJAX的工做原理:

1.建立ajax對象(XMLHttpRequest/ActiveXObject(Microsoft.XMLHttp))

2.判斷數據傳輸方式(GET/POST)

3.打開連接 open()

4.發送 send()

5.當ajax對象完成第四步(onreadystatechange)數據接收完成,判斷http響應狀態(status)200-300之間或者304(緩存)執行回調函數

十二、請指出document load和document ready的區別?

共同點:這兩種事件都表明的是頁面文檔加載時觸發。

異同點:

ready 事件的觸發,表示文檔結構已經加載完成(不包含圖片等非文字媒體文件)。

onload 事件的觸發,表示頁面包含圖片等文件在內的全部元素都加載完成。

 

 

 正則表達式

 一、寫一個function,清除字符串先後的空格。(兼容全部瀏覽器)

function trim(str) {
    if (str && typeof str === "string") {
        return str.replace(/(^\s*)|(\s*)$/g,""); //去除先後空白符
    }
}

 二、使用正則表達式驗證郵箱格式

 var reg = /^(\w)+(\.\w+)*@(\w)+((\.\w{2,3}){1,3})$/;
 var email = "example@qq.com";
 console.log(reg.test(email));  // true  

開發及性能優化

一、規避javascript多人開發函數重名問題

  • 命名空間
  • 封閉空間
  • js模塊化mvc(數據層、表現層、控制層)
  • seajs
  • 變量轉換成對象的屬性
  • 對象化

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

  • 壓縮css、js文件
  • 合併js、css文件,減小http請求
  • 外部js、css文件放在最底下
  • 減小dom操做,儘量用變量替代沒必要要的dom操做

三、你所瞭解到的Web攻擊技術

(1)XSS(Cross-Site Scripting,跨站腳本攻擊):指經過存在安全漏洞的Web網站註冊用戶的瀏覽器內運行非法的HTML標籤或者JavaScript進行的一種攻擊。
(2)SQL注入攻擊
(3)CSRF(Cross-Site Request Forgeries,跨站點請求僞造):指攻擊者經過設置好的陷阱,強制對已完成的認證用戶進行非預期的我的信息或設定信息等某些狀態更新。

 四、web前端開發,如何提升頁面性能優化?

內容方面:

1.減小 HTTP 請求 (Make Fewer HTTP Requests)

2.減小 DOM 元素數量 (Reduce the Number of DOM Elements)

3.使得 Ajax 可緩存 (Make Ajax Cacheable)

針對CSS:

1.把 CSS 放到代碼頁上端 (Put Stylesheets at the Top)

2.從頁面中剝離 JavaScript 與 CSS (Make JavaScript and CSS External)

3.精簡 JavaScript 與 CSS (Minify JavaScript and CSS)

4.避免 CSS 表達式 (Avoid CSS Expressions)

針對JavaScript :

1. 腳本放到 HTML 代碼頁底部 (Put Scripts at the Bottom)

2. 從頁面中剝離 JavaScript 與 CSS (Make JavaScript and CSS External)

3. 精簡 JavaScript 與 CSS (Minify JavaScript and CSS)

4. 移除重複腳本 (Remove Duplicate Scripts)

面向圖片(Image):

1.優化圖片

2 不要在 HTML 中使用縮放圖片

3 使用恰當的圖片格式

4 使用 CSS Sprites 技巧對圖片優化

五、前端開發中,如何優化圖像?圖像格式的區別?

優化圖像:

一、不用圖片,儘可能用css3代替。 好比說要實現修飾效果,如半透明、邊框、圓角、陰影、漸變等,在當前主流瀏覽器中均可以用CSS達成。

二、 使用矢量圖SVG替代位圖。對於絕大多數圖案、圖標等,矢量圖更小,且可縮放而無需生成多套圖。如今主流瀏覽器都支持SVG了,因此可放心使用!

3.、使用恰當的圖片格式。咱們常見的圖片格式有JPEG、GIF、PNG。

基本上,內容圖片多爲照片之類的,適用於JPEG。

而修飾圖片一般更適合用無損壓縮的PNG。

GIF基本上除了GIF動畫外不要使用。且動畫的話,也更建議用video元素和視頻格式,或用SVG動畫取代。

四、按照HTTP協議設置合理的緩存。

五、使用字體圖標webfont、CSS Sprites等。

六、用CSS或JavaScript實現預加載。

七、WebP圖片格式能給前端帶來的優化。WebP支持無損、有損壓縮,動態、靜態圖片,壓縮比率優於GIF、JPEG、JPEG2000、PG等格式,很是適合用於網絡等圖片傳輸。

 圖像格式的區別:

矢量圖:圖標字體,如 font-awesome;svg 

位圖:gif,jpg(jpeg),png

區別:

  一、gif:是是一種無損,8位圖片格式。具備支持動畫,索引透明,壓縮等特性。適用於作色彩簡單(色調少)的圖片,如logo,各類小圖標icons等。

  二、JPEG格式是一種大小與質量相平衡的壓縮圖片格式。適用於容許輕微失真的色彩豐富的照片,不適合作色彩簡單(色調少)的圖片,如logo,各類小圖標icons等。

  三、png:PNG能夠細分爲三種格式:PNG8,PNG24,PNG32。後面的數字表明這種PNG格式最多能夠索引和存儲的顏色值。

關於透明:PNG8支持索引透明和alpha透明;PNG24不支持透明;而PNG32在24位的PNG基礎上增長了8位(256階)的alpha通道透明;

優缺點:

  一、能在保證最不失真的狀況下儘量壓縮圖像文件的大小。

  二、對於須要高保真的較複雜的圖像,PNG雖然能無損壓縮,但圖片文件較大,不適合應用在Web頁面上。 

六、瀏覽器是如何渲染頁面的?

渲染的流程以下:

1.解析HTML文件,建立DOM樹。

   自上而下,遇到任何樣式(link、style)與腳本(script)都會阻塞(外部樣式不阻塞後續外部腳本的加載)。

2.解析CSS。優先級:瀏覽器默認設置<用戶設置<外部樣式<內聯樣式<HTML中的style樣式;

3.將CSS與DOM合併,構建渲染樹(Render Tree)

4.佈局和繪製,重繪(repaint)和重排(reflow)

相關文章
相關標籤/搜索