都是本身整理的,除了題目,其餘都別當真。(答案不是100分的對/(ㄒoㄒ)/~~)php
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即是一個封裝得很是好的類,好比,$("#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()
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有更好的支持
只要協議、域名、端口有任何一個不一樣,都被看成是不一樣的域。
要解決跨域的問題,咱們可使用如下幾種方法:
經過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)是一種通訊協議,它容許將超文本標記語言(HTML)文檔從Web服務器傳送到客戶端的瀏覽器。目前咱們使用的是HTTP/1.1 版本。
http協議是無狀態的,同一個客戶端的此次請求和上次請求是沒有對應關係,對http服務器來講,它並不知道這兩個請求來自同一個客戶端。 爲了解決這個問題, Web程序引入了Cookie機制來維護狀態.
HTTP協議的主要特色可歸納以下:
支持客戶/服務器模式。
簡單快速:客戶向服務器請求服務時,只需傳送請求方法和路徑。請求方法經常使用的有GET、HEAD、POST。每種方法規定了客戶與服務器聯繫的類型不一樣。因爲HTTP協議簡單,使得HTTP服務器的程序規模小,於是通訊速度很快。
靈活:HTTP容許傳輸任意類型的數據對象。正在傳輸的類型由Content-Type加以標記。
無鏈接:無鏈接的含義是限制每次鏈接只處理一個請求。服務器處理完客戶的請求,並收到客戶的應答後,即斷開鏈接。採用這種方式能夠節省傳輸時間。
無狀態: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 //服務器當前不能處理客戶端的請求,一段時間後可能恢復正常
Http協議定義了不少與服務器交互的方法,最基本的有4種,分別是GET,POST,PUT,DELETE. 一個URL地址用於描述一個網絡上的資源,而HTTP中的GET, POST, PUT, DELETE就對應着對這個資源的查,改,增,刪4個操做。 咱們最多見的就是GET和POST了。GET通常用於獲取/查詢資源信息,而POST通常用於更新資源信息.
GET提交的數據會放在URL以後,以?分割URL和傳輸數據,參數之間以&相連,如EditPosts.aspx?name=test1&id=123456. POST方法是把提交的數據放在HTTP包的Body中.
GET提交的數據大小有限制(由於瀏覽器對URL的長度有限制),而POST方法提交的數據沒有限制.
GET方式須要使用Request.QueryString來取得變量的值,而POST方式經過Request.Form來獲取變量的值。
GET方式提交數據,會帶來安全問題,好比一個登陸頁面,經過GET方式提交數據時,用戶名和密碼將出如今URL上,若是頁面能夠被緩存或者其餘人能夠訪問這臺機器,就能夠從歷史記錄得到該用戶的帳號和密碼.
在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
使用閉包的注意點:
因爲閉包會使得函數中的變量都被保存在內存中,內存消耗很大,因此不能濫用閉包,不然會形成網頁的性能問題,在IE中可能致使內存泄露。解決方法是,在退出函數以前,將不使用的局部變量所有刪除。
閉包會在父函數外部,改變父函數內部變量的值。因此,若是你把父函數看成對象(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是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
這兩函數的做用其實就是更改對象的內部指針,即改變對象的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原型(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:動畫;
css3在性能上能夠快速加載,可是缺點就是 IE8或如下不支持,並且複雜的動畫效果寫起來比較困難
js兼容性比較強,能實現比較複雜的代碼,缺點就是加載須要時間
用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);
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指向新建立的對象。