(1)JavaScript包括哪些數據類型?
1.未定義(undefined) 2.空(null) 3.布爾(boolean) 4.字符串(string)
5.數字(number) 6.對象(object)
7.引用(reference) 8.列表(list) 9.完成(completion)
reference,list,completion這3種類型是作爲JavaScript運行時中間結果的數據類型 在代碼中不能使用。javascript
(2)border-color-left、marin-left、-moz-viewport改寫成JavaScript
borderColorLeft,marinLeft, MozViewport,
-moz-border-radius確實是寫成MozBorderRadius.css
(3)請簡述javascript延遲加載的方式?
(1)將js腳本放在</body>以前,這樣就能夠在頁面都顯示以後,在繼續加載.
(2)使用script標籤的defer和async屬性,defer屬性爲延遲加載,是在頁面渲染完成以後再進行加載的,html
而async屬性則是和文檔並行加載,這兩種解決方案都不完美,緣由在於不是全部瀏覽器都支持.async(異步).
(3)監聽onload事件,動態加載.前端
var script = document.createElement ("script"); script.type = "text/javascript"; //Firefox, Opera, Chrome, Safari 3+ script.onload = function(){ alert("Script loaded!");}; //Internet Explorer script.onreadystatechange = function(){ if (script.readyState == "loaded" || script.readyState == "complete") { script.onreadystatechange = null; alert("Script loaded."); } }; script.src = "script.js"; document.getElementsByTagName("head")[0].appendChild(script);
(4)經過ajax下載js腳本,動態添加script節點.
這種方式與第二種相似,區別就在與js腳本的自動下載仍是經過ajax下載,ajax的方式顯然可控制性更好一點,它能夠先下載js文件,但不當即執行:java
var xhr = window.XMLHttpRequest ? new XMLHttpRequest() : new ActiveXObject('Microsoft.XMLHTTP'); xhr.open("get", "script.js", true); xhr.onreadystatechange = function() { if (xhr.readyState == 4) { if (xhr.status >= 200 && xhr.status < 300 || xhr.status == 304) { var script = document.createElement ("script"); script.type = "text/javascript"; script.text = xhr.responseText; document.body.appendChild(script); } } }; xhr.send(null);
(5)使用js函數setTimeout()延遲執行node
<script language="JavaScript" src="" id="my"></script> <script> //延時3秒 setTimeout(function () { document.getElementById('my').src='script.css'; },3000); </script>
(5)看x, y, z的結果? //1 4 4jquery
<script type="text/javascript"> var x=1,y=z=0; function add(n) { alert(‘one’); return n=n+1; } y=add(x);
//y = 4,執行這段代碼的時候,函數已經被替換了 alert( " y = " + y);
//這個函數被重定義了.代替了以前的函數. function add(n) { alert(‘two); return n=n+3; }
z=add(x); alert(x + " " + y + " " + z ); //1 4 4
</script>
兩次執行的都是彈出two.證實執行的都是第二個聲明函數,
證實函數執行以前,就已經完成替換了. 因爲js是一個弱類型語言,不存在函數重載。重名函數就覆蓋替換。ajax
由於沒法判讀int 或者是多參數問題。因此函數只能用名字判斷。做爲惟一標識。express
變量的定義是在全部代碼執行的以前,在一個做用域內最早被預留在內存中的,這個變量佔用了內存的存儲位置,但尚未被定義(undefined),apache
只有在遇到定義變量的語句的時候,才被賦值(defined)。程序的執行在變量存儲以後按順序進行的,在執行第一句alert的時候,變量沒有被賦值,因此彈出undefined。
(6)試從域名解析原理的角度簡單分析,域名劫持是怎麼發生的?有什麼危害?
域名就是DNS,用戶IP記不住就記域名,www.baidu.com就是一個域名.電腦會把域名翻譯成IP地址..
域名的結構:是樹形,分割是點 . 好比 以網易的域名爲例:
3g.163.com 的上級域名是 .163.com
163.com 的上級域名是 .com
這裏的 .com 就被稱爲頂級域名(Top-Level Domain,簡稱 TLD)
解析原理:當你在瀏覽器的地址欄中輸入 www.163.com,而後敲回車,這時候電腦軟件會進行以下一系列事情。
1. 首先根據輸入的網址,提取出域名。
2. 若是你在系統中配置了 Hosts 文件,那麼電腦會先查詢 Hosts 文件,看這個www.163.com 否已經在 Hosts 裏面有了對應的記錄。若是有,直接就能夠拿到該記錄中的 IP地址,過程就結束了。
3. 若是 Hosts 裏面沒有這個別名,那麼電腦會看你有沒有設置域名服務器(DNS 服務器)。若是你的系統沒有設置域名服務器,那電腦就沒轍了,瀏覽器直接會報錯,說網站的域名沒法解析。過程就結束了。
4. 若是你設置過「域名服務器」,那麼電腦會向這個域名服務器發送一個域名查詢(DNS query)的請求,而後等候域名服務器的迴應。
5. 若是域名服務器始終沒有迴應(好比域名服務器掛了,或域名服務器的IP填錯了,或請求被攔截了),那麼電腦仍是沒轍(瀏覽器會報錯)。
6. 若是域名服務器迴應了,那麼你的電腦就能夠根據域名服務器的應答信息,獲得該域名的 IP地址。以後瀏覽器就會向這個 IP地址 對應的 Web 端口發送 HTTP 請求。
一般狀況下,電腦拿到的(DNS服務器)應答信息是正確的——也就是說,應答中的IP地址確實對應那個域名——這種狀況下,你的網絡軟件就能夠正常工做了。
域名服務器上都會保存一大堆的域名記錄(每條記錄包含「域名」和「IP地址」)。當收到域名查詢的時候,域名服務器會從這堆記錄中找到對方想要的,而後迴應給對方。若是域名服務器上的某條記錄被【人爲修改】了(改爲錯的),那麼一旦要查詢這條記錄,獲得的就是錯誤的結果。這種狀況稱之爲「域名劫持」。「域名劫持」的根源在於:域名服務器上的記錄被人給改了。最直接的辦法就是不要使用這種流氓 」一般是電信運營商(ISP)提供的域名服務器,改用國外那些比較靠譜的。目前口碑最好的,大概是 Google提供的兩個域名服務器,IP地址分別是 8.8.8.8 和 8.8.4.4 ——這倆不光是地址好記,更重要的是,不會耍流氓。
域名劫持的危害:好比,把維基百科的流量重定向到XX,篡改本身的域名服務器的記錄,把裏面跟維基百科相關的域名記錄的 IP地址修改成XX的 IP地址。如此一來,假設你用的是這個 ISP 的域名服務器,當你在瀏覽器輸入 http://zh.wikipedia.org/的時候,你的電腦查詢到的 IP地址 實際上是XX的 IP地址,因此瀏覽器打開的是「XX」的主頁。域名劫持實際上就是把網站重定向了。你想去A,結果成了B。
「域名污染」的原理,簡單說來是這樣滴:當你的電腦向域名服務器發送了「域名查詢」的請求,而後域名服務器把迴應發送給你的電腦,這之間是有一個時間差的。若是某個攻擊者可以在域名服務器的「DNS應答」尚未到達你的電腦以前,先僞造一個錯誤的「DNS應答」發給你電腦。那麼你的電腦收到的就是錯誤的信息,並獲得一個錯誤的 IP地址。「域名污染」也叫「域名緩存投毒」。
(7)列舉至少5種前端性能優化的具體方法,簡要說明理由。
A:儘可能減小HTTP請求。
前端優化的黃金準則指導着前端頁面的優化策略:只有10%-20%的最終用戶響應時間花在接受請求的HTML文檔上,剩下的80%-90%時間花在爲HTML文檔所引用的全部組件(圖片、腳本、樣式表等)進行的HTTP請求上。所以,改善響應時間的最簡單途徑就是減小組件的數量,並由此減小HTTP請求的數量。
① 圖片地圖:容許在一張圖片上關聯多個URL,而目標URL的選擇取決於用戶單擊了圖片上的哪一個位置。這樣多個圖片合併成一張圖片,這樣圖片的HTTP請求就減小了。(不過圖片地圖只支持矩形形狀,其餘形狀不支持。)
② CSS Sprites(圖像精靈):將多個圖片合併到一張單獨的圖片,這樣就大大減小了頁面中圖片的HTTP請求。(對於當前網絡流行的速度而言,不高於200KB的單張圖片的所需載入時間基本是差很少的。)
③ 內聯圖片和腳本使用data:URL(Base64編碼)模式直接將圖片包含在Web頁面中而無需進行HTTP請求。可是此種方法存在明顯缺陷:- 不受IE的歡迎;- 圖片太大不宜採用這種方式,由於Base64編碼以後會增長圖片大小,這樣頁面總體的下載量會變大;- 內聯圖片在頁面跳轉的時候不會被緩存。(大圖片可使用瀏覽器的本地緩存,在首次訪問的時候保存到瀏覽器緩存中,典型的是HTML5的manifest緩存機制以及LocalStorage等)。
④ 樣式表的合併:將頁面樣式定義、腳本、頁面自己代碼嚴格區分開,可是樣式表、腳本也不是分割越細越好,由於每多引用一個樣式表就增長一次HTPP請求,能合併的樣式表儘可能合併。一個網站有一個公用樣式表定義,每一個頁面只要有一個樣式表就OK啦。
B:使用內容發佈網絡(CDN的使用)
它是一組分佈在多個不一樣地理位置的Web服務器,用於更加有效地向用戶發佈內容。主要用於發佈頁面靜態資源:圖片、css文件、js文件等。如此,能輕易地提升響應速度。
C:添加Expires頭
瀏覽器使用緩存來減小HTTP請求的數據,並減少HTTP響應的大小,使頁面加載更快。其實就是一句話,把一些css、js、圖片在首次訪問的時候所有緩存到瀏覽器本地。(可使用HTML5提供的本地緩存機制)
D壓縮組件(使用Gzip方式)
使用各類壓縮工具進行對css和js的壓縮,甚至能夠壓縮html。文件壓縮變小,天然能夠提高。
E:將CSS樣式表放在頂部
若是將css樣式定義放在頁面中或者頁面底部,會出現短暫白屏或者某一區域短暫白板的狀況,這和瀏覽器的運營機制有關的,無論頁面如何加載,頁面都是逐步呈現的。因此在每作一個頁面的時候,用Link標籤把每個樣式表定義放在head中。
F:將javascript腳本放在底部
瀏覽器在加載css文件時,頁面逐步呈現會被阻止,直到全部css文件加載完畢,因此要把css文件的引用放到head中去,這樣在加載css文件時不會阻止頁面的呈現。可是對於js文件,在使用的時候,它下面全部的頁面內容的呈現都會被阻塞,將腳本放在頁面越靠下的地方,就意味着越多的內容可以逐步呈現。
G:避免使用CSS表達式
CSS表達式是動態玩CSS的一種很強大的方式,可是強大的同時也存在很高的危險性。由於css表達式的頻繁求值會致使css表達式性能低下。若是真想玩css表達式,能夠選用只求值一次的表達式或者使用事件處理來改變css的值。
H:使用外部javascript和CSS
內聯js和css其實比外部文件有更快的響應速度,那爲何還要用外部呢?由於使用外部的js和css可讓瀏覽器緩存他們,這樣不只HTML文檔大小減小,並且不會增長HTTP請求數量。另外,使用外部js和css能夠提升組件的可複用性。
I:減小DNS查詢
DNS查詢有時間開銷,一般一個瀏覽器查找一個給定主機名的IP地址須要20-120ms。緩存DNS:緩存DNS查詢能夠很好地提升網頁性能,一旦緩存了DNS查詢,以後對於相同主機名的請求就無需進行再次的DNS查找,至少短期內不須要。因此在使用頁面中URL、圖片、js文件、css文件等時,不要使用過多不一樣的主機名。
J:精簡javascript
其實W3Cfuns已經給你們準備好精簡JS所需的全部工具「前端神器」,這點W3Cfuns爲你們作的很不錯,在這個規則裏咱們就用到「JS壓縮/混淆/美化工具」最初始的精簡方式:就是移除沒必要要的字符減少js文件大小,改善加載時間。包括全部的註釋、沒必要要的空白字符。
高級一點的精簡方式就是:混淆。它不但會移除沒必要要的字符,還會改寫代碼,好比函數和變量的名字會被改爲很短的字符串,這樣使js代碼更簡練更難閱讀。一旦使用混淆,對於js代碼的維護和調試都很複雜,由於有時候混淆以後的js代碼徹底看不懂。其實實際開發過程當中,從文件大小和代碼可複用性來講,不只僅是js代碼須要精簡,css代碼同樣也很須要精簡。
K:避免重定向
重定向的英文是Redirect,用於將用戶從一個URL從新跳轉到另外一個URL。最多見的Redirect就是301和302兩種。關於重定向的性能影響這裏就不說了,自行查閱相關資料吧。在咱們實際開發中避免重定向最簡單也最容易被忽視的一個問題就是,設置URL的時候,最後的「/」,有些人有時候會忽略,其實你少了「/」,這時候的URL就被重定向了,因此在給頁面連接加URL的時候切記最後的「/」不可丟。
L:刪除重複腳本
重複的js代碼除了有沒必要要的HTTP請求以外,還會浪費執行js的時間。將你使用的js代碼模塊化,能夠很好地避免這個問題,至於js模塊化如何實現,如今有不少可使用的開源框架。
M:配置ETag
Etag(Entity Tag),實體標籤,是Web服務器和瀏覽器用戶確認緩存組件的有效性的一種機制。寫的很複雜,對我這種非專業的前端開發人員來講,有點過了,關於這個原則有興趣的本身看吧。
N:使Ajax可緩存
針對頁面中主動的Ajax請求返回的數據要緩存到本地,固然這個是針對短時間內不會變化的數據。若是不肯定數據變化週期的話,能夠增長一個修改標識的判斷,我正常處理過程當中會給一些Ajax請求返回的數據增長一個MD5值的判斷,每次請求會判斷當前MD5是否變化,若是變化了取最新的數據,若是不變化,則不變。
噼裏啪啦說了一堆,14個規則啊,那咱們開發過程當中要針對這每個規則對本身的前端代碼作check嗎?我反正不這麼幹,作前端頁面,尤爲是移動網站的頁面,我所記住的準則就是:儘可能減小頁面大小,儘可能下降頁面響應時間。在頁面性能和交互設計之中找平衡點。
(8)判斷字符串是不是這樣組成的,第一個必須是字母,後面能夠是字母、數字、下劃線,總長度爲5-20.
var pattern = /^[a-zA-Z][\w]{4,19}$/igm;
var str = 'a23_dfds_dfdfd';
alert(pattern.test(str));
(9)截取字符串abcdefg的efg
var pattern = /efg/igm; var str = 'abcdefgefgefg'; if (pattern.test(str)) { //檢測是否有efg alert(str.substr(str.indexOf('efg'), 3)); //取出長度爲3 }
(10) 將構造函數看成函數
function Box(name, age) { this.age = age; this.name = name; this.run = function () { return this.name + this.age + "runing...."; }; }; //建立一個對象,正常調用。 var box = new Box('hg', 123); alert(box.run()); //全局運行這個函數,屬性和方法添加給window,this是指向global的指針 Box('wj', 223); alert(this.run()); alert(window.run()); //在o對象中調用Box,因此o就具備了Box的屬性 var o = {}; Box.call(o, 'lz', 123); alert(o.run());
(11)判斷一個字符竄中出現最多的字符
var str = 'dffjkjdsfkldsfknnjfknkjfdsfdsfn'; var obj = {}; function hasMostStr(str) { var pattern = /^[\w]+/igm; if (!pattern.test(str)) return ; for (var i = 0; i != str.length; i++) { var charector = str.charAt(i); if (typeof charector!= 'string') break; if (!(charector in obj)) { obj[charector] = 1; } else { obj[charector]++; } } } function writeObj(obj) { if (typeof obj != 'object') { return; } var documents = ""; for (var pro in obj) { documents += pro + " = " + obj[pro] + "<br />"; } document.write(documents); } hasMostStr(str); writeObj(obj);
(12)規避javascript多人開發函數重名問題
(1) 能夠開發前規定命名規範,根據不一樣開發人員開發的功能在函數前加前綴。
(2) 將每一個開發人員的函數封裝到類中,調用的時候就調用類的函數,即便函數重名只要類名不重複就能夠。
(13)JavaScript繼承有哪兩種形式形式,進行描述
對象冒充:在子類構造方法內,經過apply/call將this做爲參數傳入。
優勢:
能夠向父類構造方法傳遞參數,即給apply第二個參數:arguments;
父類中的屬性都被複制到子類實例中,屬性之間無干擾,不管是引用類型仍是封裝類型。
缺點:
每個實例對象都擁有一份父類方法的拷貝,互不干擾,因此沒法統一修改;
沒法擁有父類原型中定義的方法;
子類的實例對象不能經過 instanceof 操做符判斷是不是父類的實例。
原型鏈:指定子類的prototype爲父類的一個實例對象。
優缺點和構造函數借用恰好相反。
這裏特別說明下屬性之間相互干擾(對應構造函數借用的優勢2)。
組合式繼承:
上面兩種方式互補一下,即用構造方法借用來繼承父類屬性,用原型鏈來繼承父類方法。
優勢:
封裝保護了內部數據的完整性;
封裝使對象的重構更輕鬆;
弱化模塊間的耦合,提升對象的可重用性;
有助於避免命名空間衝突。
缺點:
私用方法很難測試;
必須與複雜的做用域鏈打交道,使錯誤調度更困難;
容易造成過分封裝;
JavaScript並不原生支持封裝,因此在JavaScript中實現封裝存在複雜性的問題。
(14)編寫一個方法,求一個字符串的字節長度。
function GetBytes(str) {
var len = str.length;
var bytes = len;
for (var i = 0; i < len; i++)
{
if (str.charCodeAt(i) > 255) //中文都大於255
bytes++;
}
return bytes;
}
alert(GetBytes("你好,as")); //7
charCodeAt和charAt相似,前者返回uncode編碼,後者返回字符。
(15)編寫一個方法 去掉一個數組的重複元素
var arr = [1,2,3,4,5,1,3,2,3,4,2,2]; function haveUnqueArray(arr) { var o = []; for (var pro in arr) { var temp = arr[pro]; if (!o[temp]) { //判斷元素是否在數組中。 o.push(temp); //再也不就添加 } } return o; } alert(haveUnqueArray(arr));
(16)寫出this的典型應用
1---在html元素事件屬性中使用,如 <input type=」button」 onclick="showInfo(this);" value="點擊一下"/> 2---構造函數 function Animal(name, color) { this.name = name; this.color = color; } 3---內聯的script中 <input type="button" id="text" value="點擊一下" /> <script type="text/javascript"> var btn = document.getElementById("text"); btn.onclick = function() { alert(this.value); //此處的this是按鈕元素--彈出點擊一下 } </script>
4---CSS expression表達式中使用this關鍵字 <table width="100px" height="100px"> <tr> <td> <div style="width:expression(this.parentNode.width);">div element</div> </td> </tr> </table>
(17)JavaScript中如何檢測一個變量是一個String類型?請寫出函數實現。
String類型有兩種生成方式:
(1)Var str = 「hello world」; //string類型
(2)Var str2 = new String(「hello world」); //對象生成的
function IsString(str){
return (typeof str == "string" || str.constructor == String);
}
var str = "";
alert(IsString(1));
alert(IsString(str));
alert(IsString(new String(str)))
(18)JavaScript事件委託的技術原理
事件委託,就是事件,好比onclick,onmouseover,onmouseout.委託的意思就是讓別人來作,
原理就是利用冒泡的原理,把事件加載到父級標籤上,觸發執行效果。
好處1:提升性能。不須要for循環爲每個元素都加入事件。
好處2,新添加的元素還會有以前的事件。極可能此時js已經加載完成了,新加入的節點沒法在作出反應事件了,就還須要從新加載一次js。
其實要是對屬性作操做,事件委託,就能夠代替閉包和添加新的屬性,來解決對元素的循環操做。而且提高了性能。
<ul id="parent-list">
<li id="post-1">Item 1</li>
<li id="post-2">Item 2</li>
<li id="post-3">Item 3</li>
<li id="post-4">Item 4</li>
<li id="post-5">Item 5</li>
<li id="post-6">Item 6</li>
</ul>
<script>
// 找到父元素,添加監聽器...
//這裏只寫了W3C的,IE是attachEvent
document.getElementById("parent-list").addEventListener("click", function(ev) {
// e.target是被點擊的元素!
// 若是被點擊的是li元素
// var ev = ev || window.event;
// var target = ev.target || ev.srcElement;
if(ev.target && ev.target.nodeName == "LI") {
// 找到目標,輸出ID!
// console.log("List item ",ev.target.id.substr(ev.target.id.length - 1)," was clicked!");
alert("List item " + ev.target.id.substr(ev.target.id.length - 1));
}
}, false);
</script>
(19)JS添加事件
第一種: obj.onclick = method1;
obj.onclick = method2;
obj.onclick = method3; 最後只有medthod3保存了
第二種:用addEventListener(‘click’, function, false);
False 是由裏向外,true是由外向內。
IE還有一個attachEvent(‘click’, function);
第三種寫法 : obj['onclick']或者obj['click'] = function () {};
IE要加on W3C,就不加。
(20)冒泡事件是什麼?如何阻止事件冒泡和默認事件。
事件冒泡: 當一個元素上的事件被觸發的時候,好比說鼠標點擊了一個按鈕,一樣的事件將會在那個元素的全部祖先元素中被觸發。這一過程被稱爲事件冒泡;
這個事件從原始元素開始一直冒泡到DOM樹的最上層。
阻止冒泡事件: cancelBubble(IE)和stopPropagation(FF)
function doSomething (obj, evt) {
alert(obj.id);
var e = (evt) ? evt : window.event;
//判斷瀏覽器的類型,在基於ie內核的瀏覽器中的使用cancelBubble
if (window.event)
{
e.cancelBubble=true;
}
else
{
//e.preventDefault(); //在基於firefox內核的瀏覽器中支持作法stopPropagation
e.stopPropagation();
}
}
w3c的方法是e.stopPropagation(),IE則是使用e.cancelBubble = true
阻止默認行爲
w3c的方法是e.preventDefault(),IE則是使用e.returnValue = false;
(21)解釋jsonp的原理,以及爲何不是真正的ajax
動態建立script標籤,回調函數,Ajax是頁面無刷新請求數據操做。
JSONP(JSON with Padding)是JSON的一種「使用模式」,
可用於解決主流瀏覽器的跨域數據訪問的問題。
因爲同源策略,通常來講位於 server1.example.com 的網頁沒法與不是 server1.example.com的服務器溝通,而 HTML 的<script> 元素是一個例外。
利用 <script> 元素的這個開放策略,網頁能夠獲得從其餘來源動態產生的 JSON 資料,而這種使用模式就是所謂的 JSONP。
用 JSONP 抓到的資料並非 JSON,而是任意的JavaScript,用 JavaScript 直譯器執行而不是用 JSON 解析器解析。
(22)javascript的本地對象,內置對象和宿主對象
本地對象:
Object、Function、Array、String、Boolean、Number、Date、RegExp、Error、EvalError、RangeError、ReferenceError、SyntaxError、TypeError、URIError
由此能夠看出,簡單來講,本地對象就是 ECMA-262 定義的類(引用類型)
內置對象:
ECMA-262 只定義了兩個內置對象,即 Global 和 Math (它們也是本地對象,根據定義,每一個內置對象都是本地對象)。
本地對象,就是那些官方定義好了的對象。內置對象是本地對象的一種,其只包含Global對象和Math對象。而宿主對象則是那些官方未定義,你本身構建的對象加上DOM和BOM對象組成的。
(23)document load 和document ready的區別
Document.onload 是在結構和樣式加載完才執行js
Document.ready原生種沒有這個方法,jquery中有$().ready(function)DOM結構繪製完畢後就執行,沒必要等到加載完畢。
執行時間
window.onload 必須等到頁面內包括圖片的全部元素加載完畢後才能執行。
$(document).ready() 是DOM結構繪製完畢後就執行,沒必要等到加載完畢。
編寫個數不一樣
window.onload 不能同時編寫多個,若是有多個window.onload方法,只會執行一個
$(document).ready() 能夠同時編寫多個,而且均可以獲得執行
簡化寫法
window.onload 沒有簡化寫法
$(document).ready(function(){}) 能夠簡寫成$(function(){});
(24)簡述JavaScript封裝。
封裝能夠被定義爲對對象的內部數據表現形式和實現細節進行隱藏。經過封裝能夠強制實施信息隱藏。
在JavaScript中,並無顯示的聲明私有成員的關鍵字等。
因此要想實現封裝/信息隱藏就須要從另外的思路出發。咱們可使用閉包的概念來建立只容許從對象內部訪問的方法和屬性,來達到封裝的要求。
基本方式
通常來講,咱們學用的有三種方法來達到封裝的目的。
使用this.XXX來聲明一個變量,而後再聲明getXXX、setXXX等取值、賦值的方法。
使用this._XXX來聲明一個變量,而後再聲明getXXX、setXXX等取值、賦值的方法。
利用「函數做用域」這一個概念來作。 1. 門戶大開型 var Book = function(val){ this.setValue(val); }; Book.prototype = { setValue: function(val){ this.val = val; }, getValue: function(){ return this.val; }, }; var book = new Book(1); alert(book.val);
使用這種方法實現的封裝,雖然實現了取值器與賦值器以保護私有屬性。可是在實際使用中,私有屬性依然能夠從外部訪問,因此從根本上講,沒有實現封裝。
2. 用命名規範進行區別 var Book = function(val){ this.setValue(val); }; Book.prototype = { setValue: function(val){ this._val = val; }, getValue: function(){ return this._val; }, }; var book = new Book(1); alert(book._val); 使用這種方法與第一種相似,區別在於使用不一樣的命名來保護私有屬性的使用。可是,從實際應用來講其仍然沒有實現封裝。 3. 使用函數做用域 var Book = function() { var isbn; //這裏是局部變量。函數做用域。 this.setIsbn = function(newIsbn){ isbn = newIsbn; }; this.getIsbn = function(){ return isbn; }; } var book = new Book(); book.setIsbn(1); alert(book.getIsbn()); 因爲在JavaScript的函數中聲明的變量是有做用域的,因此使用這種方法能夠避免在外部直接訪問私有屬性。基本達到封裝所要求的內容。 這裏要注意的是,咱們在函數的內部,可使用this.XXX以及var來聲明變量。區別是使用this.XXX聲明的變量在外部是能夠訪問的。
使用var聲明的變量,因爲受到函數做用域的保護,在函數的外部是沒法直接訪問的。
(25)Js中this具體的用法總結以下
1. 全局變量和全局函數附屬於全局對象(window),所以使用」var」或」this」兩種方法定義全局變量是等效的。
2. 執行上下文和做用域不一樣。執行上下文在運行時肯定,隨時可能改變,而做用域則在定義時肯定,永遠不會變。這個跟MFC的一個性質很像,運行時動態識別。
//獲取對象構造函數名稱 function type(obj) { return obj && obj.constructor && obj.constructor.toString().match(/function\s*([^(]*)/)[1]; } function test() { alert(type(this)); } function A() { this.fun = test; } function B() { this.fun = test; } var a = new A(); var b = new B(); test(); // window a.fun(); // A b.fun(); // B
3. 若是當前執行的是一個對象的方法,則執行上下文就是這個方法所附屬的對象。
function test () { alert(this.name); } function AAA() { this.name = 'hg'; this.test1 = test; function BBB() { this.name = 'gh'; this.test2 = test; } this.bbb = new BBB(); } var aaa = new AAA(); aaa.test1(); //hg aaa.bbb.test2(); //gh
說明,函數test中的this指向臨近的這個對象。這個對象方法,執行的就是上下文所對應的對象。
4. 若是當前是一個建立對象的過程或者執行一個對象的方法,則執行上下文就是這個正在被建立的對象。
5. 若是一個方法在執行時沒有明確指定附屬對象,則這個方法的上下文爲全局對象。
6. 使用call和apply能夠改變對象的執行上下文。
(26)簡述下cookie的操做,還有cookie的屬性都知道哪些。
cookie是瀏覽器提供的一種機制,它將document 對象的cookie屬性提供給JavaScript。
能夠由JavaScript對其進行控制,而並非JavaScript自己的性質。cookie是存於用戶硬盤的一個文件,這個文件一般對應於一個域名,當瀏覽器再次訪問這個域名時,便使這個cookie可用。
所以,cookie能夠跨越一個域名下的多個網頁,但不能跨越多個域名使用。可用在保存用戶登陸狀態。跟蹤用戶行爲。定製頁面。建立購物車。
$.cookie(‘cookieName’,'cookieValue’,{expires:7,path:’/',domain: ‘chuhoo.com’,secure: false,raw:false});
注:expires:有效時間;path:設置可以讀取cookie的頂級目錄;domain: 建立cookie所在網頁所擁有的域名;secure:默認是false,若是爲true,cookie的傳輸協議需爲https;raw:默認爲 false,讀取和寫入時候自動進行編碼和解碼(使用encodeURIComponent編碼,使用decodeURIComponent解碼),關閉 這個功能,請設置爲true。
(27)前端優化知識都知道哪些?
答:a 減小http請求,合併css、js文件,apache的ant。
b 減小請求文件的大小,壓縮css、js文件,在線javascript compress。
c 採用sprite拼接圖片。
d 若是有廣告欄之類的模塊,用iframe。
e 將js文件放到末尾,這個頁面顯示就沒必要等js文件加載完之後再顯示,也就是頁面不會出現空白狀態。
(28)瀑布流佈局或者流式佈局是否有了解。
答:瀑布流佈局:採用絕對定位來給每張圖片或者模塊定位。
流式佈局:採用浮動式給模塊定位。能夠作出響應式佈局。
(29)JavaScript中如何對一個對象進行深度clone
克隆方法實在不少,這裏只是舉例一個。
function cloneObject(o) { if(!o || 'object' !== typeof o) { return o; } var c = 'function' === typeof o.pop ? [] : {}; var p, v; for(p in o) { if(o.hasOwnProperty(p)) { v = o[p]; if(v && 'object' === typeof v) { c[p] = Ext.ux.clone(v); } else { c[p] = v; } } } return c; };
(30)請實現,鼠標點擊頁面中的任意標籤,alert該標籤的名稱.(注意兼容性)
<script type="text/javascript"> document.onclick = function(evt){ var e = window.event || evt; var tag = e["target"] || e["srcElement"]; alert(tag.tagName); }; </script>
(31)做用域的問題
(1)var a = 6;
setTimeout(function () {
alert(a);
a = 666;
}, 1000);
a = 66;
Alert是打印66的,由於1s以後,a==66。三個a都是全局變量。
(2)
var a = 6;
SetTimeout(function () {
alert(a);
var a = 666;
}, 1000);
a = 66;
打印的是undefined,由於在function內部又定義了var的局部變量。
還有一點要記住:setTimeout(function,time);function是一個全局的函數。就是this。Function()這個this是全局不是某一個對象。
var a = 0; //定義全局變量 function A(){ this.a = 1; //對象變量a setTimeout(function(){ //函數和變量執行的是全局做用域 this.a = 2; //this 指向的是全局做用域 a=2 try{ this.b="b"; throw ''; //這裏拋出了一個異常 } catch(e){ this.b='bb'; //全局的b設置爲bb } },0); this.b = "bbb"; //定義對象內的b變量 } var aa = new A(); //定義了對象,運行了setTimeout setTimeout(function(){ console.log(aa.a); //1 console.log(window.a); //2 console.log(aa.b); //bbb console.log(window.b) //bb },0);
(32) 判斷輸出
var a = 10; function bb () { alert(a); var a=2; alert(a); } bb();
undefined
2