那些面試題

都是本身整理的,除了題目,其餘都別當真。(答案不是100分的對/(ㄒoㄒ)/~~)php

jQuery和zepto的區別


zepto主要針對移動設備上的,只支持較新的瀏覽器,好處是代碼量小,性能較好;zepto有一些基礎的觸摸事件,如tap、swipe;css

jQuery主要是兼容性好,能夠跑在PC也能夠移動設備上,好處是兼容性好,缺點是代碼量大,性能不夠好,jQuery的2.X版本也不支持IE678也是基於這個考慮的。html

大多數在jQuery 經常使用的API 和方法zepto都有,zepto種有些方法jQuery反而沒有,大部分都能兼容。
具體的一些區別:html5

  • on事件委託的區別node

  • Zepto 的each 方法只能遍歷 數組,不能遍歷JSON對象。jquery

  • width()和height()的區別:Zepto由盒模型(box-sizing)決定,用.width()返回賦值的width,用.css('width')返回加border等的結果;jQuery會忽略盒模型,始終返回內容區域的寬/高(不包含padding、border)。css3

  • offset()的區別:Zepto返回{top,left,width,height};jQuery返回{width,height}。程序員

jQuery的$.fn.extend和$.extend的區別


jQuery即是一個封裝得很是好的類,好比,$("#btn1") 會生成一個 jQuery類的實例,理解這一點很重要。
$.extend是用來擴展jQuery類的,能夠理解爲添加靜態方法,是全局性的,直接用jQuery類調用便可。ajax

$.extend({minValue:function(a,b){return a<b?a:b;}})
$.minValue(5.6);

也能夠把這類函數稱做爲工具函數,不直接操做DOM元素,而是操做Javascript的非元素對象,或者執行其餘非對象的特定操做。
$.extend還能夠用一個或多個其餘對象來擴展一個對象,返回被擴展的對象json

var settings = { validate: false, limit: 5, name: "foo" }; 
var options = { validate: true, name: "bar" }; 
$.extend(settings, options);
//settings == { validate: true, limit: 5, name: "bar" }

$.fn是指jQuery的命名空間,它是對jQuery.prototype進得擴展,就是爲jQuery類添加「成員函數」。jQuery類的實例可使用這個「成員函數」。

$.fn.extend({
       theAlert:function(){
          alert("自定義的函數");
        }
  })
  $("thediv").theAlert()

cookie、localStorage、sessionStorage的區別


LocalStorage(本地存儲)和sessionStorage(會話存儲) 是HTML5 Web Storage API 提供的,這兩種方式都容許開發者使用js設置的鍵值對進行操做,在在從新加載不一樣的頁面的時候讀出它們。這一點與cookie相似。

  • 數據的生命期:
    cookie通常由服務器生成,可設置失效時間。若是在瀏覽器端生成Cookie,默認是關閉瀏覽器後失效;localStorage除非被清除,不然永久保存;sessionStroage僅在當前會話下有效,關閉頁面或瀏覽器後被清除;

  • 存放數據大小:
    cookie:4K左右;localStorage和sessionStorage通常爲5MB;

  • 與服務器端通訊:
    cookie每次都會攜帶在HTTP頭中,若是使用cookie保存過多數據會帶來性能問題;localStorage和sessionStorage僅在客戶端(即瀏覽器)中保存,不參與和服務器的通訊

  • 易用性:
    cookie須要程序員本身封裝,源生的Cookie接口不友好;localStorage和sessionStorage源生接口能夠接受,亦可再次封裝來對Object和Array有更好的支持

JS跨域(ajax跨域、iframe跨域)解決方法


只要協議、域名、端口有任何一個不一樣,都被看成是不一樣的域。
要解決跨域的問題,咱們可使用如下幾種方法:

  • 經過jsonp跨域:
    在js中,咱們直接用XMLHttpRequest請求不一樣域上的數據時,是不能夠的。可是,在頁面上引入不一樣域上的js腳本文件倒是能夠的,jsonp正是利用這個特性來實現的。jsonp的原理就是,經過script標籤引入一個js文件,這個js文件載入成功後會執行咱們在url參數中指定的函數,而且會把咱們須要的json數據做爲參數傳入。因此jsonp是須要服務器端的頁面進行相應的配合的。若是你的頁面使用jquery,那麼經過它封裝的方法$.getJSON(url,data,success(data,status,xhr))

function dosometing(jsondata){
    //處理得到的數據
}
<script src=" http://example.com/data.php?callback=dosometing"></script>

咱們看到獲取數據的地址後面還有一個callback參數,按慣例是用這個參數名,可是你用其餘的也同樣。固然若是獲取數據的jsonp地址頁面不是你本身能控制的,就得按照提供數據的那一方的規定格式來操做了。

由於是當作一個js文件來引入的,因此 http://example.com/data.php 返回的必須是一個能執行的js文件,因此這個頁面的php代碼多是這樣的:

<?php
$callback = $_GET['callback'];//獲得回調函數名
$data = array('a','b','c');//要返回的數據
echo $callback.'('.json_encode($data).')';//輸出
?>

最終那個頁面輸出的是:dosomething(['a','b','c'])

  • 經過修改document.domain來跨子域:
    要注意的是,document.domain的設置是有限制的,咱們只能把document.domain設置成自身或更高一級的父域,且主域必須相同。

  • 使用window.name來進行跨域:
    window對象有個name屬性,該屬性有個特徵:即在一個窗口(window)的生命週期內,窗口載入的全部的頁面都是共享一個window.name的,每一個頁面對window.name都有讀寫的權限,window.name是持久存在一個窗口載入過的全部頁面中的,並不會因新頁面的載入而進行重置。注意,window.name的值只能是字符串的形式,這個字符串的大小最大能容許2M左右甚至更大的一個容量,具體取決於不一樣的瀏覽器,但通常是夠用了。

<!--www.cnblogs.com/data.html頁面的代碼-->
window.name = "消息";

<!-- www.example.com/a.html頁面的代碼-->
function getData(){//iframe載入data.html頁面後臺執行的函數
    var iframe = document.getElementById("iframe");
    iframe.onload = function(){//這個時候a.html和data.html已是處於同一個域了,能夠互相訪問
        var data = iframe.contentWindow.name;//獲取iframe的window.name,也就是data.html頁面給她設置的數據
        alert(data);
    }
    iframe.src = "b.html";//這裏的b.html只要和a.html同一個域就好了,目的是讓a能訪問iframe裏的東西,設置成about:blank也能夠
}
<iframe id="iframe" src="www.cnblogs.com/data.html" style="display:none" onload = "getData()">
  • 使用HTML5中新引進的window.postMessage方法來跨域傳送數據
    window.postMessage(message,targetOrigin) 方法是html5新引進的特性,可使用它來向其它的window對象發送消息,不管這個window對象是屬於同源或不一樣源,目前IE8+、FireFox、Chrome、Opera等瀏覽器都已經支持window.postMessage方法。

<!-- http://test.com/a.html 的代碼 -->
function frameLoad(){
var iframe = document.getElementById("iframe");
    var win = iframe.contentWindow;//獲取window對象
    win.postMessage("消息","*");//向不一樣域的頁面發送消息
    }
    <iframe id = "ifrmae" src = "www.test.com/b.html" onload = "frameLoad()"></iframe>

<!-- http://www.test.com/b.html 的代碼 -->

window.onmessage = function(e){
    e = e || event;//獲取時間對象
    alert(e.data);//經過data屬性獲得傳送的消息
}

HTTP協議的主要特色


超文本傳輸協議(HTTP)是一種通訊協議,它容許將超文本標記語言(HTML)文檔從Web服務器傳送到客戶端的瀏覽器。目前咱們使用的是HTTP/1.1 版本。
http協議是無狀態的,同一個客戶端的此次請求和上次請求是沒有對應關係,對http服務器來講,它並不知道這兩個請求來自同一個客戶端。 爲了解決這個問題, Web程序引入了Cookie機制來維護狀態.

HTTP協議的主要特色可歸納以下:

  1. 支持客戶/服務器模式。

  2. 簡單快速:客戶向服務器請求服務時,只需傳送請求方法和路徑。請求方法經常使用的有GET、HEAD、POST。每種方法規定了客戶與服務器聯繫的類型不一樣。因爲HTTP協議簡單,使得HTTP服務器的程序規模小,於是通訊速度很快。

  3. 靈活:HTTP容許傳輸任意類型的數據對象。正在傳輸的類型由Content-Type加以標記。

  4. 無鏈接:無鏈接的含義是限制每次鏈接只處理一個請求。服務器處理完客戶的請求,並收到客戶的應答後,即斷開鏈接。採用這種方式能夠節省傳輸時間。

  5. 無狀態:HTTP協議是無狀態協議。無狀態是指協議對於事務處理沒有記憶能力。缺乏狀態意味着若是後續處理須要前面的信息,則它必須重傳,這樣可能致使每次鏈接傳送的數據量增大。另外一方面,在服務器不須要先前信息時它的應答就較快。

http請求由三部分組成,分別是:請求行、消息報頭、請求正文
HTTP響應也是由三個部分組成,分別是:狀態行、消息報頭、響應正文

HTTP響應的狀態代碼有三位數字組成,第一個數字定義了響應的類別,且有五種可能取值:

1xx:指示信息--表示請求已接收,繼續處理
2xx:成功--表示請求已被成功接收、理解、接受
3xx:重定向--要完成請求必須進行更進一步的操做
4xx:客戶端錯誤--請求有語法錯誤或請求沒法實現
5xx:服務器端錯誤--服務器未能實現合法的請求

常見狀態代碼、狀態描述、說明:

200 OK      //客戶端請求成功
400 Bad Request  //客戶端請求有語法錯誤,不能被服務器所理解
401 Unauthorized //請求未經受權,這個狀態代碼必須和WWW-Authenticate報頭域一塊兒使用 
403 Forbidden  //服務器收到請求,可是拒絕提供服務
404 Not Found  //請求資源不存在,eg:輸入了錯誤的URL
500 Internal Server Error //服務器發生不可預期的錯誤
503 Server Unavailable  //服務器當前不能處理客戶端的請求,一段時間後可能恢復正常

GET和POST方法的區別


Http協議定義了不少與服務器交互的方法,最基本的有4種,分別是GET,POST,PUT,DELETE. 一個URL地址用於描述一個網絡上的資源,而HTTP中的GET, POST, PUT, DELETE就對應着對這個資源的查,改,增,刪4個操做。 咱們最多見的就是GET和POST了。GET通常用於獲取/查詢資源信息,而POST通常用於更新資源信息.

  1. GET提交的數據會放在URL以後,以?分割URL和傳輸數據,參數之間以&相連,如EditPosts.aspx?name=test1&id=123456. POST方法是把提交的數據放在HTTP包的Body中.

  2. GET提交的數據大小有限制(由於瀏覽器對URL的長度有限制),而POST方法提交的數據沒有限制.

  3. GET方式須要使用Request.QueryString來取得變量的值,而POST方式經過Request.Form來獲取變量的值。

  4. GET方式提交數據,會帶來安全問題,好比一個登陸頁面,經過GET方式提交數據時,用戶名和密碼將出如今URL上,若是頁面能夠被緩存或者其餘人能夠訪問這臺機器,就能夠從歷史記錄得到該用戶的帳號和密碼.

js的變量做用域


在js當中,變量的做用域就是定義這個變量的區域。變量分爲:局部變量和全局變量。在函數內聲明的變量只在這個函數內有定義,做用域是局部的,函數的參數也是局部變量。
理解做用域鏈能夠更好的理解變量的做用域,每一個JavaScript執行環境都有一個和它關聯在一塊兒的做用域鏈。在變量解析過程當中首先查找局部的做用域鏈,而後查找外部的做用域鏈。

閉包的概念


閉包就是可以讀取其餘函數內部變量的函數。因爲在Javascript語言中,只有函數內部的子函數才能讀取局部變量,所以能夠把閉包簡單理解成"定義在一個函數內部的函數"。
因此,在本質上,閉包就是將函數內部和函數外部鏈接起來的一座橋樑。

  

閉包的用途:
最大用處有兩個,一個是前面提到的能夠讀取函數內部的變量,另外一個就是讓這些變量的值始終保持在內存中。

  function f1(){
    var n=999;
    nAdd=function(){n+=1}//沒有var的全局變量,nAdd的值是一個匿名函數,而這個匿名函數自己也是一個閉包,能夠在函數外部對函數內部的局部變量進行操做。
    function f2(){//f1是f2的父函數,而f2被賦給了一個全局變量,這致使f2始終在內存中,而f2的存在依賴於f1,所以f1也始終在內存中,不會在調用結束後,被垃圾回收機制(garbage collection)回收。
      alert(n);
    }
    return f2;
  }
  var result=f1();
  result(); // 999
  nAdd();
  result(); // 1000

使用閉包的注意點:

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

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

this和閉包的解讀代碼

var name = "The Window";
   var object = {
    name : "My Object",
    getNameFunc : function(){
      return function(){//閉包函數
        return this.name;//到父函數getNameFunc找name變量,找不到,到外部找,找到"The Window"
      };
    }
  };
  alert(object.getNameFunc()());//The Window
  
    var name = "The Window";
  var object = {
    name : "My Object",
    getNameFunc : function(){
      var that = this;
      return function(){
        return that.name;
      };
    }
  };
  alert(object.getNameFunc()());//由於this的對象引用就是object,因此返回值在Object中開始查找,找到了Obeject中的name就不到全局變量中查找。
  

this 的用法


this是Javascript語言的一個關鍵字。
它表明函數運行時,自動生成的一個內部對象,只能在函數內部使用。
隨着函數使用場合的不一樣,this的值會發生變化。可是有一個總的原則,那就是this指的是,調用函數的那個對象。

function test(){
 alert(this.x);
}
var o = {
    x:1,
    m:test
};
o.m.apply();//undefined

function test(){
 alert(this.x);
}
var o = {
    x:1,
    m:test
};
o.m.apply(o);//1 
  

call和apply兩個方法的區別


這兩函數的做用其實就是更改對象的內部指針,即改變對象的this指向的內容,這兩個方法都能劫持另一個對象的方法,繼承另一個對象的屬性.

function add(c, d){
  return this.a + this.b + c + d;
}

var o = {a:1, b:3};

// 第一個參數對象o將代替add類裏this對象
// 後面的參數就是須要逗號隔開的參數列表
add.call(o, 5, 7); // 1 + 3 + 5 + 7 = 16

// 第一個參數對象o將代替add類裏this對象
// 第二個參數爲數組,就是須要傳遞的參數列表
add.apply(o, [10, 20]); // 1 + 3 + 10 + 20 = 34

//apply的一個例子,
    function Person(name,age){   //定義一個類
        this.name=name;     //名字
        this.age=age;       //年齡
        this.sayhello=function(){alert(this.name)}; 
    } 
    function Print(){            //顯示類的屬性
        this.funcName="Print"; 
        this.show=function(){ 
            var msg=[]; 
            for(var key in this){ 
                if(typeof(this[key])!="function"){ 
                    msg.push([key,":",this[key]].join("")); 
                } 
            } 
            alert(msg.join(" ")); 
        }; 
    } 
    function Student(name,age,grade,school){    //學生類
        Person.apply(this,arguments);//比call優越的地方
        Print.apply(this,arguments); 
        this.grade=grade;                //年級
        this.school=school;                 //學校
    } 
    var p1=new Person("卜開化",80); 
    p1.sayhello(); 
    var s1=new Student("白雲飛",40,9,"嶽麓書院"); 
    s1.show(); 
    s1.sayhello(); 
    alert(s1.funcName);

另一個須要注意的:傳null或undefined時,將是JS執行環境的全局變量。瀏覽器中是window,其它環境(如node)則是global。

function fun() {
        alert(this);
    }
    fun.call(1);//「1」
    fun.call('a');//「a」
    fun.call(true);//「true」
    fun.call({name:'jack'}); //「[object Object]」
    fun.call(null); // window or global
    fun.call(undefined); // window or global

嚴格模式下狀況又有所不一樣,ES3比較寬容儘可能去揣測代碼意圖。ES5嚴格模式(ie6/7/8/9除外)則再也不揣測,給call/apply傳入的任何參數再也不轉換。

'use strict'
    function fun() {
        alert(this);
    }
    fun.call(null)      // null
    fun.call(undefined) // undefined

js的繼承機制


js中有三種繼承方式:
一、js原型(prototype)繼承:

function Person(name,age){ 
    this.name=name; 
    this.age=age; 
} 
Person.prototype.sayHello=function(){ 
    alert("使用原型獲得Name:"+this.name); 
} 
var per=new Person("馬小倩",21); 
per.sayHello(); //輸出:使用原型獲得Name:馬小倩 
function Student(){} 
Student.prototype=new Person("洪如彤",21); 
var stu=new Student(); 
Student.prototype.grade=5; 
Student.prototype.intr=function(){ 
    alert(this.grade); 
} 
stu.sayHello();//輸出:使用原型獲得Name:洪如彤 
stu.intr();//輸出:5

二、構造函數繼承

function  Parent(name){ 
    this.name=name; 
    this.sayParent=function(){ 
        alert("Parent:"+this.name); 
    } 
} 

function  Child(name,age){ 
    this.tempMethod=Parent; 
    this.tempMethod(name); 
    this.age=age; 
    this.sayChild=function(){ 
        alert("Child:"+this.name+"age:"+this.age); 
    } 
} 

var parent=new Parent("江劍臣"); 
parent.sayParent(); //輸出:「Parent:江劍臣」 
var child=new Child("李鳴",24); //輸出:「Child:李鳴 age:24」 
child.sayChild();

三、call、apply實現繼承

function  Person(name,age,love){ 
        this.name=name; 
        this.age=age; 
        this.love=love; 
        this.say=function say(){ 
            alert("姓名:"+name); 
        } 
    } 

    //call方式 
    function student(name,age){ 
        Person.call(this,name,age); 
    } 

    //apply方式 
    function teacher(name,love){ 
        Person.apply(this,[name,love]); 
        //Person.apply(this,arguments); //跟上句同樣的效果,arguments 
    } 

    //call與aplly的異同: 
    //1,第一個參數this都同樣,指當前對象 
    //2,第二個參數不同:call的是一個個的參數列表;apply的是一個數組(arguments也能夠) 

    var per=new Person("武鳳樓",25,"魏熒屏"); //輸出:「武鳳樓」 
    per.say(); 
    var stu=new student("曹玉",18);//輸出:「曹玉」 
    stu.say(); 
    var tea=new teacher("秦傑",16);//輸出:「秦傑」 
    tea.say();

transition transfrom translate animation有什麼區別?


transition:過渡;transfrom:變換;translate:平移;animation:動畫;

CSS3動畫和js動畫


css3在性能上能夠快速加載,可是缺點就是 IE8或如下不支持,並且複雜的動畫效果寫起來比較困難
js兼容性比較強,能實現比較複雜的代碼,缺點就是加載須要時間

bootsrtap封裝jQuery插件的方式


用button.js舉例

!function ($) {
     "use strict";
    var Button = function(element, options){
        this.$element  = $(element)
        this.options   = $.extend({}, Button.DEFAULTS, options)
    }
    Button.DEFAULTS = {}
    Button.prototype.toggle = function(){}
    
    function Plugin(options){
        return this.each(function(){
        ...
        new Button(this,options)
        ...
        })
    }
    
    var old = $.fn.Button;
    
    $.fn.Button = Plugin;
    $.fn.Buttn.Contructor = Button;//將插件類暴露給外界,能夠修改和添加類裏面的方法,如$.fn.Buttn.Contructor.prototype.show = function(){}
    
    // 避免命名空間衝突
    $.fn.Button.noConflict = function(){
        $.fn.Button = old;
        return this;
    }
}(window.jQuery);

js中new關鍵字的理解


new是用來實例化一個對象。

// 定義類 類名字是 classA
function classA(){
    this.name=1;
}
classA.prototype.show = function(){
    alert(this.name);
};
// 用new實例化
var b = new classA();
b.show();

var b = new classA();這句話,new的做用流程是:

一、建立一個新的對象,這個對象的類型是object;二、查找class的prototype上的全部方法、屬性,複製一份給建立的Object三、將構造函數classA內部的this指向建立的Object四、建立的Object的__proto__指向classA的prototype,b.__proto__ = classA.portotype五、執行構造函數classA六、返回新建立的對象給變量b 句話總結:new關鍵字以ClassA()爲模板建立了一個新的對象,它複製了ClassA構造器中的全部成員變量,同時this指向新建立的對象。

相關文章
相關標籤/搜索