###基礎javascript
####Javascript是一種弱類型語言,它分別有什麼優勢和缺點 弱類型語言:簡單好用,更靈活多變。可是會犧牲性能,好比一些隱含的類型轉換 強類型語言:類型轉換的時候很是嚴格,,強類型語言是直接操縱內存,容易出內存越界和泄漏的問題。在類型的轉換方面是不少約束,甚至強制轉換也要很謹慎,一不當心就出大問題。php
####Javascript裏面的數據類型有哪些 5個簡單數據類型(基本數據類型)+ 1個複雜數據類型 undefiend, number string null boolean + objectcss
####有幾種方式能夠判斷數據類型 typeof和intanceof 其實typeof和instanceof的目的都是檢測變量的類型,兩個的區別在於typeof通常是檢測的是基本數據類型,instanceof主要檢測的是引用類型! html
####基本類型和引用類型有什麼區別 賦值的時候基本類型按值,引用類型按引用,就是基本類型會複製一份,引用類型就是一個新的指針 函數傳參的時候都是按值傳遞前端
####? [][]? nullundefined? () []==[]() null == undefined(對)vue
####寫個方法判斷一個變量的類型java
###函數node
####函數聲明和函數表達式有什麼區別 函數聲明會將那個函數提高到最前面,成爲全局函數。函數聲明要指定函數名,而函數表達式不用,能夠用做匿名函數。 建立函數的方式:函數聲明、函數表達式、還有一種不常見的方式就是Function構造器。 函數聲明:react
function add(a,b) { a = +a; b = +b; if (isNaN(a) || isNaN(b)) { return; } return a + b; }
函數表達式的幾種方式:jquery
// 函數表達式 var add = function(a, b) { // do sth } // 匿名函數定義的一個當即執行函數表達式 (function() { // do sth })(); // 做爲返回值的函數表達式 return function() { // do sth }; // 命名式函數表達式 var add = function foo (a, b) { // do sth }
函數聲明與函數表達式的主要區別就是:函數聲明會被前置 函數聲明前置:
// function add(a,b) 已經聲明前置了,能夠正常調用 var num = add(1, 2); console.log(num); // 3 function add(a,b) { a = +a; b = +b; if (isNaN(a) || isNaN(b)) { return; } return a + b; }
函數表達式前置:
// var add 變量聲明提早,此時變量的值是undefined var num = add(1, 2); console.log(num); // TypeError:undefined is not a function var add = function(a, b) { a = +a; b = +b; if (isNaN(a) || isNaN(b)) { return; } return a + b; }
Function構造器:
var func = new Function('a', 'b', 'console.log(a+b);'); fun(1, 2); // 3 // 和上面的方式沒有區別 var func = Function('a', 'b', 'console.log(a+b);'); func(1, 2); // 3
區別:
####函數有哪幾種調用方式
直接調用 做爲對象的方法調用 apply,call
####做用域 JS沒有塊做用域,只有函數做用域 做用域鏈的做用是保證執行環境裏有權訪問的變量和函數是有序的,做用域鏈的變量只能向上訪問,變量訪問到window對象即被終止,做用域鏈向下訪問變量是不被容許的。 ####做用域鏈是什麼 A://說的不是很清楚
###閉包 ####閉包是什麼
閉包是指有權訪問另外一個函數做用域中的變量的函數
建立閉包的方式: 在一個函數內部建立另外一個函數
閉包的做用: 1.讓這些函數的值始終保存在內存中
####濫用閉包有什麼反作用 因爲閉包會攜帶包含它的函數的做用域鏈,所以會比其餘函數佔用更多的內存。過分使用閉包可能會致使內存佔用過多,因此只在絕對必要時使用閉包。
####閉包實現塊級做用域
(function() { })();
####閉包的做用/應用 匿名自執行函數、緩存、實現封裝(主要做用)、實現面向對象中的對象 1 匿名自執行函數
咱們知道全部的變量,若是不加上var關鍵字,則默認的會添加到全局對象的屬性上去,這樣的臨時變量加入全局對象有不少壞處, 好比:別的函數可能誤用這些變量;形成全局對象過於龐大,影響訪問速度(由於變量的取值是須要從原型鏈上遍歷的)。 除了每次使用變量都是用var關鍵字外,咱們在實際狀況下常常遇到這樣一種狀況,即有的函數只須要執行一次,其內部變量無需維護, 好比UI的初始化,那麼咱們可使用閉包:
var datamodel = { table : [], tree : {} }; (function(dm){ for(var i = 0; i < dm.table.rows; i++){ var row = dm.table.rows[i]; for(var j = 0; j < row.cells; i++){ drawCell(i, j); } } //build dm.tree })(datamodel); ``` 咱們建立了一個匿名的函數,並當即執行它,因爲外部沒法引用它內部的變量, 所以在執行完後很快就會被釋放,關鍵是這種機制不會污染全局對象。 **2緩存** 再來看一個例子,設想咱們有一個處理過程很耗時的函數對象,每次調用都會花費很長時間, 那麼咱們就須要將計算出來的值存儲起來,當調用這個函數的時候,首先在緩存中查找,若是找不到,則進行計算, 而後更新緩存並返回值,若是找到了,直接返回查找到的值便可。閉包正是能夠作到這一點,由於它不會釋放外部的引用, 從而函數內部的值能夠得以保留。 ``` var CachedSearchBox = (function(){ var cache = {}, count = []; return { attachSearchBox : function(dsid){ if(dsid in cache){//若是結果在緩存中 return cache[dsid];//直接返回緩存中的對象 } var fsb = new uikit.webctrl.SearchBox(dsid);//新建 cache[dsid] = fsb;//更新緩存 if(count.length > 100){//保正緩存的大小<=100 delete cache[count.shift()]; } return fsb; }, clearSearchBox : function(dsid){ if(dsid in cache){ cache[dsid].clearSelection(); } } }; })(); CachedSearchBox.attachSearchBox("input1"); ``` 這樣,當咱們第二次調用CachedSearchBox.attachSerachBox(「input1」)的時候, 咱們就能夠從緩存中取道該對象,而不用再去建立一個新的searchbox對象。 **3 實現封裝** 能夠先來看一個關於封裝的例子,在person以外的地方沒法訪問其內部的變量,而經過提供閉包的形式來訪問: ``` var person = function(){ //變量做用域爲函數內部,外部沒法訪問 var name = "default"; return { getName : function(){ return name; }, setName : function(newName){ name = newName; } } }(); print(person.name);//直接訪問,結果爲undefined print(person.getName()); person.setName("abruzzi"); print(person.getName()); 獲得結果以下: undefined default abruzzi ``` 4 **實現面向對象中的對象** 傳統的對象語言都提供類的模板機制, 這樣不一樣的對象(類的實例)擁有獨立的成員及狀態,互不干涉。雖然JavaScript中沒有類這樣的機制,可是經過使用閉包, 咱們能夠模擬出這樣的機制。仍是以上邊的例子來說: ``` function Person(){ var name = "default"; return { getName : function(){ return name; }, setName : function(newName){ name = newName; } } }; var john = Person(); print(john.getName()); john.setName("john"); print(john.getName()); var jack = Person(); print(jack.getName()); jack.setName("jack"); print(jack.getName()); 運行結果以下: default john default jack ``` 由此代碼可知,john和jack均可以稱爲是Person這個類的實例,由於這兩個實例對name這個成員的訪問是獨立的,互不影響的。 ####實現一個暴露內部變量,並且外部能夠訪問修改的函數 (get和set,閉包實現) ``` var person = function(){ //變量做用域爲函數內部,外部沒法訪問 var name = "default"; return { getName : function(){ return name; }, setName : function(newName){ name = newName; } } }(); print(person.name);//直接訪問,結果爲undefined print(person.getName()); person.setName("abruzzi"); print(person.getName()); 獲得結果以下: undefined default abruzzi ``` ####從幾個li中取下標的閉包代碼 ``` <ul> <li>1</li> <li>2</li> <li>3</li> <li>4</li> </ul> var li=document.getElementsByTagName("li"); for(var i=0;i<li.length;i++) { (function(x) { li[x].onclick=function(){alert(x);} })(i); } ``` ####實現一個閉包的例子(實現了一個定時函數傳值的) ``` 閉包: for(var i = 0; i < 10; i++ ){ (function(x){ setTimeout(function(){ console.log(x) },x*1000) })(i) } 或者用全局變量實現 ``` ###面向對象 ------------------------------------------ ####原型與原型鏈 原型鏈是實現繼承的主要方法,其基本原理是利用原型讓一個引用繼承另外一個引用類型的屬性和方法。 簡單回顧一下構造函數,原型和實例的關係:每一個構造函數都有一個原型對象,原型對象都包含一個指向構造函數的指針,而實例都包含一個指向原型對象的內部指針。咱們讓一個原型對象等於另外一個類型的實例,此時原型對象將包含一個指向另外一個原型的指針,另外一個原型中也包含着指向另外一個構造函數的指針。假如另外一個原型又是另外一個類型的實例,那麼上述關係依然成立,如此層層遞進,就構成了實例與原型的鏈條。這就是所謂原型鏈的基本概念 ####js原型鏈的繼承 ####靜態屬性怎麼繼承 ####js原型鏈以及特色 由於每一個對象和原型都有原型,對象的原型指向原型對象, 而父的原型又指向父的父,這種原型層層鏈接起來的就構成了原型鏈。 ####面向對象有哪幾個特色 封裝,繼承,多態 ####對象的繼承 ####建立對象的幾種方式 ####繼承的兩種方法 原型鏈繼承和類繼承。而後類繼承只繼承了實例屬性,沒有原型屬性。 原型鏈繼承能夠繼承全部。而後用apply和call怎麼繼承原型鏈上的共享屬性?經過空函數傳值。新建一個空函數C。C實例化後C的實例屬性就是空,而後用B的apply/call去繼承C,至關於繼承了C的實例屬性 ####JS怎麼實現繼承 將父對象的一個實例賦值給子對象的原型 [js實現繼承的5種方式](http://javapolo.iteye.com/blog/1996871) ####new操做符時具體是幹了些什麼 New: 一、建立一個空對象,而且 this 變量引用該對象,同時還繼承了該函數的原型。 二、屬性和方法被加入到 this 引用的對象中。 三、新建立的對象由 this 所引用,而且最後隱式的返回 this 。 ####怎麼判斷屬性來自對象自身仍是原型鏈 hasOwnProperty ####一個對象的實例,如何統計被幾回調用過,分別具體被哪些函數調用過,能夠有哪些方法 ####寫個Animal類 有個Cat類繼承它,要求新建一個Cat的實例,能夠調用catch方法輸出本身的名字「大白的貓」; ####實現私有變量 (這裏當時還沒看到相關部分,只能想到用屬性的setter、getter來作。。。😂面試官各類啓發呀。。); ####手寫一個類的繼承,並解釋一下 ####手寫JS實現類繼承,講原型鏈原理 ####淺拷貝和深拷貝 ``` function extendCopy(p) { var c = {}; for (var i in p) { c[i] = p[i]; } c.uber = p; return c; } var Doctor = extendCopy(Chinese); Doctor.career = '醫生'; alert(Doctor.nation); // 中國 // 深拷貝: function deepCopy(p, c) { var c = c || {}; for (var i in p) { if (typeof p[i] === 'object') { c[i] = (p[i].constructor === Array) ? [] : {}; deepCopy(p[i], c[i]); } else { c[i] = p[i]; } } return c; } var Doctor = deepCopy(Chinese); ``` ###數組 ------------------------------------------ ####Array對象自帶的方法,一一列舉 var arr = [0,1,2]; 1.pop():刪除數組的最後一個元素,減小數組的長度,返回刪除的值。 這裏是2. 2.push(3):將參數加載到數組的最後,返回新數組的長度。 如今arr中是:0,1,2,3 3.shift():刪除數組的第一個元素,返回刪除的值,同時數組長度減一。 這裏是0 4.unshift(3,4):把參數加載數組的前面,返回新數組的長度。 如今arr:中是3,4,0,1,2 5.sort():按指定的參數對數組進行排序 ,返回的值是通過排序以後的數組 ``` var a = [0,1,5,10,15]; var b = a.sort(); // a:[1,2,3,4,5] b:[0,1,10,15,5] 正確的排序: function compare(val1, val2) { return val1 - val2; } arr = [3,7,6]; arr.sort(compare); // 3,6,7 ``` 6.reverse():反轉數組項的順序,返回的值是通過排序以後的數組 7.concat(3,4):把兩個數組拼接起來。 返回的值是一個副本 8.slice(start,end):返回從原數組中指定開始下標到結束下標之間的項組成的新數組 ``` var colors = ["red", "green", "blue", "yellow", "purple"]; // 一個參數:[ ,+∞) var color1 = colors.slice(1); alert(color1); // green,blue,yellow,purple // 兩個參數:[,) var color2 = colors.slice(1,4); alert(color2); // green,blue,yellow ``` 6splice(): 刪除: 2個參數,起始位置,刪除的項數 插入: 3個參數,起始位置,刪除的項數,插入的項 替換:任意參數,起始位置,刪除的項數,插入的任意數量的項 ``` var colors = ["red", "green", "blue"]; var removed = colors.splice(0,1); // 刪除第一項 alert(colors); // green,blue alert(removed); // red,返回數組中只包含一項 removed = colors.splice(1, 0, "yellow", "orange"); // 從位置1開始插入兩項 alert(colors); // green,yellow,orange,blue alert(removed); // 返回的數組是一個空數組 removed = colors.splice(1, 1, "red", "purple"); // 從位置I開始插入兩項 alert(colors); // green,red,yellow,orange,blue alert(removed); // yellow,返回的數組中只包含一項 ``` indexOf()和lastIndexOf():接受兩個參數,要查找的項(可選)和查找起點位置的索引 indexOf():從數組開頭向後查找 lastIndexOf():從數組末尾開始向前查找 every():對數組中的每一項運行給定函數,若是該函數對每一項都返回true,則返回true。 filter():對數組中的每一項運行給定函數,返回該函數會返回true的項組成數組。 forEach():對數組的每一項運行給定函數,這個方法沒有返回值。 map():對數組的每一項運行給定函數,返回每次函數調用的結果組成的數組。 some():對數組的每一項運行給定參數,若是該函數對任一項返回true,則返回true。以上方法都不會修改數組中的包含的值。 reduce()和reduceRight():縮小數組的方法,這兩個方法都會迭代數組的全部項,而後構建一個最終返回的值。 join(separator):將數組的元素組起一個字符串,以separator爲分隔符,省略的話則用默認用逗號爲分隔符 ``` var a = [1,2,3,4,5]; var b = a.join("|"); //a:[1,2,3,4,5] b:"1|2|3|4|5" ``` ####Array對象自帶的排序函數底層是怎麼實現的 ####數組去重 ``` 思路: 1.建立一個新的數組存放結果 2.建立一個空對象 3.for循環時,每次取出一個元素與對象進行對比,若是這個元素不重複,則把它存放到結果數組中,同時把這個元素的內容做爲對象的一個屬性,並賦值爲1,存入到第2步創建的對象中。 說明:至於如何對比,就是每次從原數組中取出一個元素,而後到對象中去訪問這個屬性,若是能訪問到值,則說明重複。 Array.prototype.unique3 = function(){ var res = []; // 建立一個新的數組存放結果 var json = {}; // 建立一個空對象 for(var i = 0; i < this.length; i++){ if(!json[this[i]]){ // json不爲空的時候 res.push(this[i]); // 把元素依次放入到res中 json[this[i]] = 1; //? } } return res; // 返回res } var arr = [112,112,34,'你好',112,112,34,'你好','str','str1']; alert(arr.unique3()); // 調用unique3函數 ``` ####數組去除一個函數。 用arr.splice。又問splice返回了什麼?應該返回的是去除的元素。 ####你知道僞數組嗎 這裏把符合如下條件的對象稱爲僞數組: 1,具備length屬性 2,按索引方式存儲數據 3,不具備數組的push,pop等方法 如 1,function內的**arguments** 。 2,經過**document.forms,Form.elements,Select.options,document.getElementsByName()** **,document.getElementsByTagName()** ,[**childNodes/children** ](http://snandy.iteye.com/blog/547369)等方式獲取的集合(HTMLCollection,NodeList)等。 3,特殊寫法的對象 ,如 ``` var obj={}; obj[0] = "一"; obj[1] = "二"; obj[2] = "三"; obj.length = 3; ``` ####那你從新設計一下這個函數,讓它直接擁有數組的方法吧 ``` // 方法1、 聲明一個空數組,經過遍歷僞數組把它們從新添加到新的數組中,你們都會,這不是面試官要的 var aLi = document.querySelectorAll('li'); var arr = []; for (var i = 0; i < aLi.length; i++) { arr[arr.length] = aLi[i] } // 方法2、使用數組的slice()方法 它返回的是數組,使用call或者apply指向僞數組 var arr = Array.prototype.slice.call(aLi); ``` ####實現sum(2,3);sum(2,3,4);sum(2,3,4,5); (我用了比較原始的方法,if來判斷) ####那若是sum裏面的參數不肯定呢 (提取arguments的長度,用for循環) ####手寫一個遞歸函數(考察arguments.callee,以及arguments的解釋) ``` // arguments.callee 是一個指向正在執行函數的指針 function factorial(num) { if (num <= 1) { return 1; } else { return num * arguments.callee(num - 1); } } ``` ####若干個數字,怎麼選出最大的五個 ###AJAX -------------------------------------------- #### ajax原理 Ajax的原理:經過XmlHttpRequest對象來向服務器發異步請求,從服務器得到數據,而後用javascript來操做DOM而更新頁面。 ####原生ajax的四個過程/手寫原生ajax a:new一個XHR對象 b:調用open方法 c:send一些數據 d:對過程進行監聽,來知道服務器是否是正確地作出了響應,接着能夠作一些事情 ``` // 兼容性寫法 var request; if (window.XMLHttpRequest) { request = new XMLHttpRequest(); //IE7+,Firefox,Chrome,Opera,Safari } else{ request = new ActiveXObject("Microsoft.XMLHTTP"); //IE6,IE5 } ``` ``` // GET請求: document.getElementById("search").onclick = function() { var request = new XMLHttpRequest(); request.open("GET", "server.php?number=" + document.getElementById("keyword").value); request.send(); request.onreadystatechange = function() { if (request.readyState===4) { if (request.status===200) { document.getElementById("searchResult").innerHTML = request.responseText; } else { alert("發生錯誤:" + request.status); } } } } // POST請求 document.getElementById("save").onclick = function() { var request = new XMLHttpRequest(); request.open("POST", "server.php"); var data = "name=" + document.getElementById("staffName").value + "&number=" + document.getElementById("staffNumber").value + "&sex=" + document.getElementById("staffSex").value + "&job=" + document.getElementById("staffJob").value; request.setRequestHeader("Content-type","application/x-www-form-urlencoded"); request.send(data); request.onreadystatechange = function() { if (request.readyState===4) { if (request.status===200) { document.getElementById("createResult").innerHTML = request.responseText; } else { alert("發生錯誤:" + request.status); } } } } ``` ####經過哪一個屬性獲得data? jquery裏是success回調裏面的形參。 responseText和responseXML。後者是XML解析了的。 #### readyState幾個狀態的含義 readyState屬性的變化表明服務器響應的變化 0:請求未初始化,open尚未調用 1:服務器鏈接已創建,open已經調用了 2:請求已接收,也就是接收到頭信息了 3:請求處理中,也就是接收到了響應主體 4:請求已完成,且響應已就緒,也就是響應完成了 ####支持哪些數據格式? 經常使用的有三種數據格式:HTML、XML、JSON。 ####XML和JSON有過了解吧?能說一下分別介紹一下他們嗎?JSON有什麼優點 >**XML**:擴展標記語言 (ExtensibleMarkup Language, XML) ,能夠用來標記數據、定義數據類型,是一種容許用戶對本身的標記語言進行定義的源語言。 優勢: - A.格式統一,符合標準; - B.容易與其餘系統進行遠程交互,數據共享比較方便。 缺點: - A.XML文件龐大,文件格式複雜,傳輸佔帶寬; - B.服務器端和客戶端都須要花費大量代碼來解析XML,致使服務器端和客戶端代碼變得異常複雜且不易維護; - C.客戶端不一樣瀏覽器之間解析XML的方式不一致,須要重複編寫不少代碼; - D.服務器端和客戶端解析XML花費較多的資源和時間。 >**JSON**:(JavaScript ObjectNotation) 是一種輕量級的數據交換格式。易於人閱讀和編寫。同時也易於機器解析和生成。 JSON採用徹底獨立於語言的文本格式。 優勢: - A.數據格式比較簡單,易於讀寫,格式都是壓縮的,佔用帶寬小; - B.易於解析,客戶端JavaScript能夠簡單的經過eval()進行JSON數據的讀取; - C.支持多種語言。包括ActionScript, C, C#, ColdFusion, Java, JavaScript, Perl, PHP, Python, Ruby等服務器端語言,便於服務器端的解析; - D.在PHP世界,已經有PHP-JSON和JSON-PHP出現了,偏於PHP序列化後的程序直接調用,PHP服務器端的對象、數組等能直接生成JSON格式,便於客戶端的訪問提取; - E.由於JSON格式能直接爲服務器端代碼使用,大大簡化了服務器端和客戶端的代碼開發量,且完成任務不變,而且易於維護。 缺點: - A.沒有XML格式這麼推廣的深刻人心和喜用普遍,沒有XML那麼通用性; - B.JSON格式目前在Web Service中推廣還屬於初級階段。 ####在不支持json格式的瀏覽器中,寫方法可以將json字符串與對象互相轉換; 現代瀏覽器中提供了JSON.stringify()方法 將數組,對象轉成json。 JSON.stringify 把一個對象轉換成json字符串, JSON.parse 把一個json字符串解析成對象。 ####ajax在jquery的底層是怎麼實現的 ####手寫一個promise版的ajax ####js的異步加載,promise的三種狀態,ES7中的async用過麼 ####若是頁面初始載入的時候把ajax請求返回的數據存在localStorage裏面,而後每次調用的時候去localStorage裏面取數,是否可行。 (直接說了不能保證數據的實時性,請求和實時性必然會有一方有所犧牲) ####js異步的方法 方案一:`<script>`標籤的`async="async"`屬性(詳細參見:script標籤的async屬性) 點評:HTML5中新增的屬性,Chrome、FF、IE9&IE9+均支持(IE6~8不支持)。此外,這種方法不能保證腳本按順序執行。 方案二:`<script>`標籤的`defer="defer"`屬性 點評:兼容全部瀏覽器。此外,這種方法能夠確保全部設置defer屬性的腳本按順序執行。 方案三:動態建立`<script>`標籤 ``` <!DOCTYPE html> <html> <head> <script type="text/javascript"> (function() { var s = document.createElement_x('script'); s.type = 'text/javascript'; s.src = "http://code.jquery.com/jquery-1.7.2.min.js"; var tmp = document.getElementsByTagName_r('script')[0]; tmp.parentNode.insertBefore(s, tmp); })(); </script> </head> <body> <img src="http://xybtv.com/uploads/allimg/100601/48-100601162913.jpg" /> </body> </html> ``` 點評:兼容全部瀏覽器。 方案四:AJAX eval(使用AJAX獲得腳本內容,而後經過eval_r(xmlhttp.responseText)來運行腳本) 點評:兼容全部瀏覽器。 方案五:iframe方式(這裏能夠參照:iframe異步加載技術及性能 中關於Meboo的部分) 點評:兼容全部瀏覽器。 ###跨域 --------------------------------------------------- ####jsonp是什麼 JSON是一種數據格式,JSONP是一種數據調用方式。 工做原理: 咱們和服務端約定好一個函數名,當請求文件的時候,服務端返回一段 JS。這段JS調用了咱們約定好的函數,而且將數據當作參數傳入。,JSON 的數據格式和 JavaScript 語言裏對象的格式正好相同。因此在咱們約定的函數裏面能夠直接使用這個對象。 利用`<script>`標籤沒有跨域限制的來達到與第三方通信的目的。 當須要通信時,本站腳本建立一個`<script>`元素,地址指向第三方的API網址,形如: `<script src="http://www.example.net/api?param1=1¶m2=2"></script>` 並提供一個回調函數來接收數據(函數名可約定,或經過地址參數傳遞)。 第三方產生的響應爲json數據的包裝(故稱之爲jsonp,即json padding),形如: `callback({"name":"hax","gender":"Male"})`這樣瀏覽器會調用callback函數,並傳遞解析後json對象做爲參數。本站腳本可在callback函數裏處理所傳入的數據。 ``` <meta content="text/html; charset=utf-8" http-equiv="Content-Type" /> <script type="text/javascript"> function jsonpCallback(result) { //alert(result); for(var i in result) { alert(i+":"+result[i]);//循環輸出a:1,b:2,etc. } } var JSONP=document.createElement("script"); JSONP.type="text/javascript"; JSONP.src="http://crossdomain.com/services.php?callback=jsonpCallback"; document.getElementsByTagName("head")[0].appendChild(JSONP); </script> // 或者: <meta content="text/html; charset=utf-8" http-equiv="Content-Type" /> <script type="text/javascript"> function jsonpCallback(result) { alert(result.a); alert(result.b); alert(result.c); for(var i in result) { alert(i+":"+result[i]);//循環輸出a:1,b:2,etc. } } </script> <script type="text/javascript" src="http://crossdomain.com/services.php?callback=jsonpCallback"></script> ``` ####手寫jsonp ####jsonp怎麼用 動態加載`<script>`標籤 ####!發送jsonp時候的那個消息頭長什麼樣子 ####跨域是啥 跨域是指 不一樣域名之間相互訪問 協議、子域名、主域名、端口號任意一個不相同時,都算跨域。 ####跨域瞭解多少 講了CORS、JSONP、postMessage啥的 ####跨域的方法 1. JSONP - 原理: 動態`<script>`標籤 `<script>` 標籤是不受同源策略的限制的,它能夠載入任意地方的 JavaScript 文件,而並不要求同源。 - 例子: ``` <script>function getWeather(data) { console.log(data); }</script> <script src="http://x.y.com/xx.js"> // http://x.y.com/xx.js 文件內容: getWeather({ "城市": "北京", "天氣": "大霧" }); ``` 2. document.domain - 使用條件: 1.有其餘頁面 window對象的引用。 2.二級域名相同。 3.協議相同。 4.端口相同。 3. window.name 4. [HTML5] postMessage ####前端跨域方法以及說下怎樣實現 JSONP XHR2 後端代理 window.name window.postmessage 異步:客戶端的操做和服務器端的操做互相之間不會形成堵塞 XMLHttpRequest對象:後臺和服務器交換數據 一、利用html+css來實現頁面,表達信息; 二、用XMLHttpRequest和web服務器進行數據的異步交換 三、運營js操做DOM,實現動態局部刷新; ####!爲何要跨域 ####描述一下跨域安全問題 ####Cookie跨域請求能不能帶上 ###this ---------------------------------------- ####js中this的做用 ####this的理解 this對象是在運行時基於函數的執行環境綁定的:在全局函數中,this等於window,而當函數做爲某個對象的方法調用時,this等於那個對象 (不過匿名函數的執行具備全局性,所以,this對象一般指向window.) ####怎麼傳入this call apply ####apply和call的區別 foo.call(this, arg1,arg2,arg3) == foo.apply(this, arguments) `call方法`: 語法:call([thisObj[,arg1[, arg2[, [,.argN]]]]]) 定義:調用一個對象的一個方法,以另外一個對象替換當前對象。 說明: call 方法能夠用來代替另外一個對象調用一個方法。call 方法可將一個函數的對象上下文從初始的上下文改變爲由 thisObj 指定的新對象。 若是沒有提供 thisObj 參數,那麼 Global 對象被用做 thisObj。 `apply方法`: **• 在js裏call()與apply()有什麼相同和不一樣? ** >apply()方法: 接受兩個參數,一個是在其中運行函數的做用域,另外一個是參數數組(能夠是Array的實例,也能夠是arguments對象)。 語法:apply(thisObj,[argArray]) 定義:應用某一對象的一個方法,用另外一個對象替換當前對象。 ``` function sum(num1,num2){ return num1 + num2; } function callsum1(num1,num2){ return sum.apply(this,[num1,num2]);//傳入數組 } function callsum2(num1,num2){ return sum.apply(this,arguments);//傳入arguments對象 } alert(callsum1(10,10)); alert(callsum2(10,10)); ``` >call()方法: 他與apply()方法的區別僅在與接收參數的方式不一樣。對於call()方法而言,第一個參數是this值沒有變化變化的是其他參數都直接傳遞個函數。換句話說就是在使用call()方法時,傳遞給函數的參數必須逐個例舉出來。 語法:call(thisObj,Object) 定義:調用一個對象的一個方法,以另外一個對象替換當前對象。 ``` function sum(num1,num2){ return num1 + num2; } function callsum(num1,num2){ return sum.call(this, num1, num2); } alert(callsum(10,10)); ``` ####實現bind函數 ####js中上下文是什麼 ####js有哪些函數能改變上下文 call apply ###事件 ----------------------------------------------- ####實現事件代理 事件委託就是利用事件冒泡,只指定一個事件處理程序,就能夠管理某一類型的全部事件。 例1:點擊li,彈出123 ``` <ul id="ul1"> <li>111</li> <li>222</li> <li>333</li> <li>444</li> </ul> // 實現功能是點擊li,彈出123: window.onload = function(){ var oUl = document.getElementById("ul1"); var aLi = oUl.getElementsByTagName('li'); for(var i = 0; i < aLi.length; i++){ aLi[i].onclick = function(){ alert(123); } } } // 事件委託:利用冒泡 window.onload = function(){ var oUl = document.getElementById("ul1"); oUl.onclick = function(){ alert(123); } } // 事件委託:點擊具體的Li纔會發生 window.onload = function(){ var oUl = document.getElementById("ul1"); oUl.onclick = function(ev){ var ev = ev || window.event; var target = ev.target || ev.srcElement; if(target.nodeName.toLowerCase() == 'li'){ alert(123); alert(target.innerHTML); } } } ``` 例2:每一個li點擊的效果都不同 ``` <div id="box"> <input type="button" id="add" value="添加" /> <input type="button" id="remove" value="刪除" /> <input type="button" id="move" value="移動" /> <input type="button" id="select" value="選擇" /> </div> // 普通方法: window.onload = function(){ var Add = document.getElementById("add"); var Remove = document.getElementById("remove"); var Move = document.getElementById("move"); var Select = document.getElementById("select"); Add.onclick = function(){ alert('添加'); }; Remove.onclick = function(){ alert('刪除'); }; Move.onclick = function(){ alert('移動'); }; Select.onclick = function(){ alert('選擇'); } } // 事件委託: window.onload = function(){ var oBox = document.getElementById("box"); oBox.onclick = function (ev) { var ev = ev || window.event; var target = ev.target || ev.srcElement; if(target.nodeName.toLocaleLowerCase() == 'input') { switch(target.id){ case 'add' : alert('添加'); break; case 'remove' : alert('刪除'); break; case 'move' : alert('移動'); break; case 'select' : alert('選擇'); break; } } } } ``` 總結: 那什麼樣的事件能夠用事件委託,什麼樣的事件不能夠用呢? 適合用事件委託的事件:click,mousedown,mouseup,keydown,keyup,keypress。 值得注意的是,mouseover和mouseout雖然也有事件冒泡,可是處理它們的時候須要特別的注意,由於須要常常計算它們的位置,處理起來不太容易。 ####事件代理中怎麼定位實際事件產生的目標 A:捕獲->處於目標->冒泡,IE應該是隻有冒泡沒有捕獲。 事件代理就是在父元素上綁定事件來處理,經過event對象的target來定位。 ####jquery的委託原理 ####冒泡和捕獲,事件流哪三個階段? 除了冒泡和捕獲,還有目標階段。他們的前後順序,先捕獲,到了目標,再冒泡。(不要只記概念,要了解是幹麼用的) ``` DOM事件流包括三個階段: 事件捕獲階段 處於目標階段 事件冒泡階段 ``` ####事件機制,如何綁定事件處理函數 [淺談JavaScript的事件機制](http://blog.csdn.net/wusuopubupt/article/details/21738523) [JavaScript綁定事件的方法[3種]](http://www.itxueyuan.org/view/6338.html) ####事件類型、綁定方式 ``` 一、表單事件: submit事件、reset事件、click事件、change事件、 focus事件(不冒泡) (IE和ES5支持冒泡的focusin) blur事件(不冒泡) (IE和ES5支持冒泡的focusout) input事件(ES5 textinput提供更方便的獲取輸入文字的方案) 二、Window事件 load事件、DOMContentLoaded事件、readyStatechage事件 unload事件、beforeunload事件、resize事件、scroll事件 三、鼠標事件 click事件、dbclick事件、mouseover事件(冒泡)、 mouseout事件(冒泡)、mousedown事件、mouseup事件 contextmenu事件、mouseenter事件(不冒泡)、mouseleave事件(不冒泡) mousewheel事件(FF DOMMouseScroll事件、DOM3 wheel事件) 四、鍵盤事件 keydown事件、keyup事件、keypress事件 ``` ####w3c事件與IE事件的區別 (當時回答的只想到冒泡跟捕獲) ####IE與W3C怎麼阻止事件的冒泡 當咱們須要阻止瀏覽器某DOM元素的默認行爲: W3C用e.preventDefault() IE下用window.event.returnValue=false 阻止事件冒泡: W3C用e.stopPropagation() IE下用window.event.cancelBubble=true來實現。 >在瀏覽器解析事件的時候,有兩種觸發方式,一種叫作Bubbling(冒泡),另一種叫作Capturing(捕獲)。由上圖能夠看出來,冒泡的方式效果就是當一個DOM元素的某事件例如click事件被fire時,依次它的父元素的click事件也被fire(觸發),一直傳遞到最頂層的body元素爲止。而捕獲的觸發方式正好相反,當某個元素的click事件被觸發時,先從最頂層的body元素click事件被觸發開始,一直傳遞到真正被觸發的元素爲止。 >此次我將討論W3C的標準DOM事件模型和IE獨立門戶的DOM事件模型到底有多少區別,首先咱們能夠回想一下目前大多數Js程序員習慣如何綁定事件到DOM元素上,最多見的就是obj.onclick=handler這種方式(更惡劣的是在Html代碼的元素標籤中直接加上onclick屬性,徹底沒達到視圖和動做分開的原則)。咱們暫時稱這種方式的事件添加爲Traditional(傳統方式)吧,IE有本身的IE Event Module,而火狐等瀏覽器則遵循的W3C方式的Event Module,下面看看這三者各自的優缺點在哪裏—— >一、 Traditional Module >傳統方式的事件模型即直接在DOM元素上綁定事件處理器,例如— >window.onload=function(){…} >obj.onmouseover=function(e){…} >obj.onclick=function(){…} >首先這種方式是不管在IE仍是Firefox等其餘瀏覽器上均可以成功運行的通用方式。這即是它最大的優點了,並且在Event處理函數內部的this變量無一例外的都只想被綁定的DOM元素,這使得Js程序員能夠大大利用this關鍵字作不少事情。 >至於它的缺點也很明顯,就是傳統方式只支持Bubbling,而不支持Capturing,而且一次只能綁定一個事件處理器在DOM元素上,沒法實現多Handler綁定。最後就是function參數中的event參數只對非IE瀏覽器有效果(由於IE瀏覽器有特製的window.event)。 >二、 W3C (Firefox.e.g) Event Module >Firefox等瀏覽器很堅定的遵循W3C標準來制定瀏覽器事件模型,使用addEventListener和removeEventListener兩個函數,看幾個例子— >window.addEventListener(‘load’,function(){…},false); >document.body.addEventListener(‘keypress’,function{…},false); >obj.addEventListener(‘mouseover’,MV,true); >function MV(){…} >addEventListener帶有三個參數,第一個參數是事件類型,就是咱們熟知的那些事件名字去掉前面的’on’,第二個參數是處理函數,能夠直接給函數字面量或者函數名,第三個參數是boolean值,表示事件是否支持Capturing。 >W3C的事件模型優勢是Bubbling和Capturing都支持,而且能夠在一個DOM元素上綁定多個事件處理器,各自並不會衝突。而且在處理函數內部,this關鍵字仍然可使用只想被綁定的DOM元素。另外function參數列表的第一個位置(無論是否顯示調用),都永遠是event對象的引用。 >至於它的缺點,很不幸的就只有在市場份額最大的IE瀏覽器下不可以使用這一點。 >三、 IE Event Module >IE本身的事件模型跟W3C的相似,但主要是經過attachEvent和detachEvent兩個函數來實現的。依舊看幾個例子吧— >window.attachEvent(‘onload’,function(){…}); >document.body.attachEvent(‘onkeypress’,myKeyHandler); >能夠發現它跟W3C的區別是沒有第三個參數,並且第一個表示事件類型的參數也必須把’on’給加上。這種方式的優勢就是能綁定多個事件處理函數在同一個DOM元素上。 >至於它的缺點,爲何現在在實際開發中不多見呢?首先IE瀏覽器自己只支持Bubbling不支持Capturing;並且在事件處理的function內部this關鍵字也沒法使用,由於this永遠都只想window object這個全局對象。要想獲得event對象必須經過window.event方式,最後一點,在別的瀏覽器中,它顯然是沒法工做的。 >最後我在推薦兩個必須知道的IE和W3C標準的區別用法吧— >一、 當咱們須要阻止瀏覽器某DOM元素的默認行爲的時候在W3C下調用e.preventDefault(),而在IE下則經過window.event.returnValue=false來實現。 >二、當咱們要阻止事件冒泡的時候,在W3C標準裏調用e.stopPropagation(),而在IE下經過設置window.event.cancelBubble=true來實現。 ####描述一下事件模型 ####IE的事件模型是怎樣的 ####event對象/事件包括哪些東西 ####js異步模式如何實現 [Javascript異步編程的4種方法](http://www.ruanyifeng.com/blog/2012/12/asynchronous%EF%BC%BFjavascript.html) ####手寫一個盒子模型中,獲取盒子內子節點的class樣式,盒子內節點的類型不可知 我用了事件監聽,但沒考慮瀏覽器兼容性,也沒能寫出來怎麼斷定節點的類型(枚舉不可) 面試官問我本身給這個代碼打幾分,我說60分 面試官說這種代碼兼容性有問題,根本不能在線上運行,因此60分也沒QwQ 使用事件代理機制,當事件被拋到更上層的父節點的時候,咱們經過檢查事件的目標對象(target)來判斷並獲取事件源。 // 獲取父節點,併爲它添加一個click事件 document.getElementById("parent-list").addEventListener("click",function(e) { // 檢查事件源e.targe是否爲Li if(e.target && e.target.nodeName.toUpperCase() == "LI") { // 真正的處理過程在這裏 //alert(123); console.log("List item ",e.target.id," was clicked!"); } }); • 事件捕獲:當某個元素觸發某個事件(如onclick),頂層對象document就會發出一個事件流,隨着DOM樹的節點向目標元素節點流去,直到到達事件真正發生的目標元素。在這個過程當中,事件相應的監聽函數是不會被觸發的。 • 事件目標:當到達目標元素以後,執行目標元素該事件相應的處理函數。若是沒有綁定監聽函數,那就不執行。 • 事件起泡:從目標元素開始,往頂層元素傳播。途中若是有節點綁定了相應的事件處理函數,這些函數都會被一次觸發。若是想阻止事件起泡,可使用e.stopPropagation()(Firefox)或者e.cancelBubble=true(IE)來組織事件的冒泡傳播。 ###JQ ----------------------------------------------- ####jQuery仍是原生js ####爲何選擇原生 我認爲要把原生吃透再去理解其餘類庫的話會更好一點,她說也是 #### jQuery源碼有看過嗎?請說出jQuery內部判斷數據類型的巧妙方式 ####jQuery源碼有看過嗎?請說出你印象最深入部分的原理。 ####手寫一個jQuery插件 ####在jquery方法和原型上面添加方法的區別和實現($.extend,$.fn.extend),以及jquery對象的實現(return new jQuery.fn.init) ####手寫實現jquery裏面的insertAfter (結合nextSibling和insertBefore來實現) ####jquery和zepto有什麼區別 ###es6 ----------------------------------------- ####es6與es7瞭解多少 ####談談對ES6的理解 ####es6的新特性 ####promise let關鍵字,class , ####promise `http://www.jianshu.com/p/063f7e490e9a` ####Promise編程 ####手寫實現一個promise(不會) ####如何避免多重回調—promise,promise簡單描述一下,如何在外部進行resolve() ####promise解決了你什麼問題 ####ES5中,除了函數,什麼可以產生做用域 A:對象? //而後被回問對象有做用域嗎?而後我說對象裏面this會變。。。徹底把做用域和執行環境弄混了 ####es6中字符串模版怎麼用 ####ES6裏頭的箭頭函數的this對象與其餘的有啥區別 ###瀏覽器 ------------------------------------------- ####瀏覽器端的JS包含哪幾個部分 ECMAScript+DOM ####瀏覽器渲染的方式 ####瀏覽器的渲染過程 (如js代碼何時運行啊,css代碼上面時候渲染啊,js代碼運行阻塞頁面渲染之類的) ####瀏覽器加載一個頁面的過程、渲染機制 瀏覽器的解析方式,瀏覽器解析html頁面首先瀏覽器先下載html,而後在內存中把html代碼轉化成Dom Tree,而後瀏覽器根據Dom Tree上的Node分析css和Images,當文檔下載遇到js時,js獨立下載。 ###DOM -------------------------------------------------------------- ####DOM包含哪些對象? Node對象,而後繼承下來的有Document,Element,Text,還有想不起來了 https://zhidao.baidu.com/question/562272490.html ####如何獲取某個DOM節點,節點遍歷方式 ####setTimeout和setInterval區別,如何互相實現? setInterval在執行完一次代碼以後,通過了那個固定的時間間隔,它還會自動重複執行代碼,而setTimeout只執行一次那段代碼。 區別: ``` window.setTimeout("function",time);//設置一個超時對象,只執行一次,無週期 window.setInterval("function",time);//設置一個超時對象,週期='交互時間' ``` ####瞭解navigator對象嗎 Navigator 對象: Navigator 對象包含有關瀏覽器的信息。 註釋:沒有應用於 navigator 對象的公開標準,不過全部瀏覽器都支持該對象。 ###緩存 ------------------------------------------------ ####Cookie 是否會被覆蓋,localStorage是否會被覆蓋。 同名cookie會被覆蓋 ####cookie和session有什麼區別 cookie在客戶端,session在服務端 Session過時與否取決於服務期的設定,cookie過時與否能夠在cookie生成的時候設置進去。 cookie不是很安全,別人能夠分析存放在本地的COOKIE並進行COOKIE欺騙 考慮到安全應當使用session。 ####瀏覽器在發送cookie時會發送哪幾個部分? A:不太清楚 ####那你知道cookie有哪幾個組成部分嗎? A:不太清楚 Cookie由變量名和值組成,相似[JavaScript](http://lib.csdn.net/base/javascript)變量。其屬性裏既有標準的Cookie變量,也有用戶本身建立的變量,屬性中變量是用「變量=值」形式來保存。 ####你有用開發者工具看過cookie嗎 A:有 ####瀏覽器緩存的區別 ###前端安全 -------------------------------------- ####前端安全 [聊一聊WEB前端安全那些事兒](https://segmentfault.com/a/1190000006672214) ####前端安全:xss攻擊和csrf **XSS跨站腳本(Crosssite scripting)** 緣由:XSS其實就是Html的注入問題,攻擊者的輸入沒有通過嚴格的控制進入了數據庫,最終顯示給來訪的用戶,致使能夠在來訪用戶的瀏覽器裏以瀏覽用戶的身份執行Html代碼。 攻擊手段和目的: 攻擊者使被攻擊者在瀏覽器中執行腳本後,若是須要收集來自被攻擊者的數據(如cookie或其餘敏感信息),能夠自行架設一個網站,讓被攻擊者經過JavaScript等方式把收集好的數據做爲參數提交,隨後以數據庫等形式記錄在攻擊者本身的服務器上。 a. 盜用 cookie ,獲取敏感信息。 b.利用植入 Flash ,經過 crossdomain 權限設置進一步獲取更高權限;或者利用Java等獲得 相似的操做。 c.利用 iframe、frame、XMLHttpRequest或上述Flash等方式,以(被攻擊)用戶的身份執行一 些管理動做,或執行一些通常的如發微博、加好友、發私信等操做。 d.利用可被攻擊的域受到其餘域信任的特色,以受信任來源的身份請求一些平時不容許的操 做,如進行不當的投票活動。 e.在訪問量極大的一些頁面上的XSS能夠攻擊一些小型網站,實現DDoS攻擊的效果。 避免XSS的方法: 1.主要是將用戶所提供的內容進行濾; 移除用戶上傳的dom結點,好比onerror; 移除用戶上傳的style結點,script結點,iframe結點等。 2.使用HTTP頭指定類型: 不少時候可使用HTTP頭指定內容的類型,使得輸出的內容避免被做爲HTML解析。如在PHP語言中使用如下代碼: ``` header ('Content-Type: text/javascript; charset=utf-8'); ``` 便可強行指定輸出內容爲文本/JavaScript腳本(順便指定了內容編碼),而非能夠引起攻擊的HTML。 **CSRF(僞造請求):冒充用戶之手** CSRF 顧名思義,是僞造請求,冒充用戶在站內的正常操做。咱們知道,絕大多數網站是經過 cookie 等方式辨識用戶身份(包括使用服務器端 Session 的網站,由於 Session ID 也是大多保存在 cookie 裏面的),再予以受權的。因此要僞造用戶的正常操做,最好的方法是經過XSS 或連接欺騙等途徑,讓用戶在本機(即擁有身份 cookie 的瀏覽器端)發起用戶所不知道的請求。 防護方法: 請求令牌(一種簡單有效的防護方法): 首先服務器端要以某種策略生成隨機字符串,做爲令牌(token),保存在 Session 裏。而後在發出請求的頁面,把該令牌以隱藏域一類的形式,與其餘信息一併發出。在接收請求的頁面,把接收到的信息中的令牌與 Session 中的令牌比較,只有一致的時候才處理請求,處理完成後清理session中的值,不然返回 HTTP 403 拒絕請求或者要求用戶從新登錄驗證身份。 ###功能實現 --------------------------------------- ####1.一個文本框,須要兩個控件對裏面的值進行控制,一個是+1一個是-1,要求每點擊一次就有個提示框冒出來。 並且文本框是可修改的,每次修改也會冒出提示框。( 事件監聽) ####2.使用js畫一個拋物線,拋物線上有個小球隨着拋物線運動,有兩個按鈕能使小球繼續運動中止運動 ####3.js輪播實現思路 ####4.實現一個querySelectorAll的功能 函數長這樣querySelect(el, className) ``` function querySelect(el,className){ var children = el.children; var result = []; if(el.classList.contains(className)){ result.push(el); } for(var i; i<children.length; i++){ var child = children[i]; var arr = querySelect(child,className); result.push.apply(result, arr); } return result; } ``` ####5.實現一個快排 ``` #include <iostream> using namespace std; void Qsort(int a[], int low, int high) { if(low >= high) { return; } int first = low; int last = high; int key = a[first];/*用字表的第一個記錄做爲樞軸*/ while(first < last) { while(first < last && a[last] >= key) { --last; } a[first] = a[last];/*將比第一個小的移到低端*/ while(first < last && a[first] <= key) { ++first; } a[last] = a[first]; /*將比第一個大的移到高端*/ } a[first] = key;/*樞軸記錄到位*/ Qsort(a, low, first-1); Qsort(a, first+1, high); } int main() { int a[] = {57, 68, 59, 52, 72, 28, 96, 33, 24}; Qsort(a, 0, sizeof(a) / sizeof(a[0]) - 1);/*這裏原文第三個參數要減1不然內存越界*/ for(int i = 0; i < sizeof(a) / sizeof(a[0]); i++) { cout << a[i] << ""; } return 0; }/*參考數據結構p274(清華大學出版社,嚴蔚敏)*/ ``` ####lazyload如何實現 [圖片懶加載](圖片延遲加載(lazyload)的實現原理) ###移動端 --------------------------------------------- ####移動端是指手機瀏覽器,仍是native,仍是hybrid(問這個問題真的是無語) ####你用了移動端的什麼庫類和框架? ####移動端要注意哪些 ####移動端是指手機瀏覽器,仍是native,仍是hybrid(問這個問題真的是無語) ####你用了移動端的什麼庫類和框架? ####移動端要注意哪些 ####適配有去考慮麼,retina屏幕啊? ####rem是什麼?em是什麼?若是上一層就是根root了,em和rem等價麼? #### 你對目前流行的前端框架都有什麼瞭解,有沒有應用經驗? (一面時面試官推薦我多瞭解一下 Vue.js ,我回去也惡補了,二面時便說了一些對Vue.js的理解,二面面試官也說Vue.js是他們經常使用的,這個信息很重要) ###算法 ####雙向鏈表怎麼找中點? 頭尾指針都往中間走,兩個指針相等或交替的時候爲中點 ####上面的問題 單向鏈表呢 A:先走到尾記下有幾個元素,而後再走到一半的地方 //面完查了下能夠用快慢指針,一個指針每次走一步,另外個走兩步,快指針到尾部時慢指針在中點 ###問答 ####1 obj怎麼變? ``` var obj = { a : 1 }; (function (obj) { obj = {a : 2}; })(obj); ``` A:外面的obj不變,由於裏面等於讓局部的obj指向了一個新的對象 ``` var obj = { a: 1, func: function() { (function() { a = 2; }(); } }; obj.func(); ``` ####2 問a怎麼變匿名函數裏的this是什麼?怎麼改變裏面的this?匿名函數不能傳參怎麼改變obj.a的值? A: obj.a不變,匿名函數裏的this指向全局對象(window),至關於給window加了一個名爲a的屬性。 ``` (function () { this.a = 2; }).call(this); //或者apply //或者 func: function () { var self = this; (function () { self.a = 2; })(); } ``` ###其餘 ####4. 字符串「1」加上數字1的結果是? (也許是看我前一題答不上來,沉默半天忽然問了這個……這是在動態調整難度?) ####JS動畫有哪些實現方法 ####那你知道還有什麼實現動畫的方法 A:CSS3的animation,還有用canvas作的算嗎? ####作一些js題(考察this,做用域,變量聲明,引用類型); ####實現一個列表中每一個li裏有一個input和button,點擊button刪除對應的li節點 #### 給了段代碼,問輸出什麼。主要是考做用域鏈和this ####要實現函數內每隔5秒調用本身這個函數,100次之後中止,怎麼辦 ###框架 ####介紹一下react ####組件化是啥 ####你覺的react的優勢 ####爲何沒有選擇學習AngularJS ####主流框架Node Angular Vue React對比 javascript實現的底層原理 ** ####bootstrap的實現原理 ####vue與angularjs區別 ####對nodejs瞭解多少 ####nodejs中的文件怎麼讀寫 ####解釋一下vue和react,以及異同點 ####解釋一下react和vue,以及區別 ####requireJS的原理是什麼 ####require的讀取順序 ####手寫實現requireJS模塊實現(想了半天才想到createElement("script"),配合異步來加載,閉包導出) ####react和vue的介紹以及異同 ####AMD和CMD,commonJS的區別 ####requirejs如何避免循環依賴 ####vue的特色?雙向數據綁定是如何實現的 ####學習angularjs之類的庫的方法 ####5requirejs實現原理 ####5.vuejs與angularjs的區別 ####requirejs怎麼防止重複加載 ####vue如何實現父子組件通訊,以及非父子組件通訊 ####vuex是用來作什麼的 /說下你所瞭解的vuex ###打包工具 ####爲何要打包 (我說了http請求那點事) ####介紹一下webpack和gulp,以及項目中具體的使用 ####gulp的插件用過啥/gulp用過啥 ####gulp底層實現原理 ####gulp你是怎麼用的 ####webpack底層實現原理 ####gulp與webpack區別 ####webpack是用來幹嗎的 ####webpack與gulp的區別 ####vue源碼結構 ####vue與angularjs中雙向數據綁定是怎樣實現的 ####webpack怎樣配置 ####angular的雙向綁定原理 ####angular和react的認識(挖財用這個兩個框架,後來問了) ####MVVM是什麼 ####說說你瞭解的框架 我說了react和vue ####react你以爲怎樣 (我說了一些組件化和虛擬dom樹的東西) ####AngularJS呢 (我說沒有學過,但瞭解過一點,我把我瞭解的都說了給她聽) ####爲何你會以爲AngularJS笨重? (也是本身的見解,mvc框架嘛,一整套什麼都有) ####響應式佈局是啥 一個網站可以兼容多個終端 ####響應式佈局是根據什麼進行響應 經過定義容器大小,平分12份(也有平分紅24份或32份,但12份是最多見的),再調整內外邊距,最後結合媒體查詢,就製做出了響應式網格系統。 判斷出終端設備的容器寬度,而後選擇性的加載吻合大小的網頁,也就是媒體查詢。媒體查詢寫在CSS樣式代碼的最後,CSS是層疊樣式表,在同一特殊性下,靠後的的樣式會重疊前面的樣式。 html頭部也要寫兼容性, 例如:`<meta name="viewport content="width=device-width,initial-scale=1,maximum-scale=1,user-scalable=no"/>`。 註釋: `width=device-width`:寬度等於當前設備的寬度 `initial-scale=1`:初始的縮放比例(默認爲1) `maximum-scale=1`:容許用戶縮放到得最大比例(默認爲1) `user-scalable=no`:用戶不能手動縮放 ####響應式佈局的方式 如何實現響應式佈局? 一、百分比 經過將每一個盒子的寬度設定百分比來實現。 優勢:簡單方便要 缺點:在額外設置margin、padding時,或者使用不一樣瀏覽器時,會使得佈局混亂 二、meta標籤 代碼段爲: `<meta name="viewport" content="width=device-width, initial-scale=1" /> ` 這主要是爲了讓代碼適應移動端的屏幕,其中,viewport 是指須要加載meta 標籤時讀取的名字爲「視口」,其中的 width 須要等於 device-width(設備寬度),主要是告訴瀏覽器,將佈局視口的寬度設置爲設備最理想的寬,initial-scale(縮放比例) 爲1,這樣就保證了加載的時候,要獲取設備的寬度,同時要保持原始大小,便於媒體查詢 三、@media 媒體查詢 css代碼段爲: `@media screen and (min-width: 10rem) and (max-width: 20rem) { ... } ` 這裏面的 第一個 screen 意思爲屏幕,這裏面還有許多 參數,包括all(用於全部設備)、print(用於打印機和打印預覽)、speech(應用於屏幕閱讀器等發聲設備)。 使用and來並列顯示多種狀況,min-width 和max-width 來定義在那種尺寸的屏幕上顯示,這就是響應式的靈魂。 上面的例子,就是 媒體查詢屏幕,最小寬度爲10rem 最大寬度我20rem 的設備寬度上來實現大括號內的樣式或者其餘功能,這裏面的rem也能夠換成px或者em之類的單位等。 優勢:如今大部分的響應式佈局都是使用@media 來實現的,能夠書寫大量的公共樣式,在須要適應屏幕的時候,在大括號內加入相應的功能便可實現響應式佈局。 缺點:可能須要對同一個類書寫不一樣的樣式,代碼比較繁複,難度也稍微難點。 ###沒有 ####手寫一個js的深克隆 ####for函數裏面setTimeout異步問題 ####原生js模板引擎 ####用原生js實現複選框選擇以及全選非全選功能 ####看過哪些框架的源碼 ####要求寫js自定義事件 ####做用域的題 #####js寫一個遞歸。就是每隔5秒調用一個自身,一共100次。 ####如何保持登陸狀態 ####原生js添加class怎麼添加,若是自己已經有class了,會不會覆蓋,怎麼保留? ####Get和post的區別 ####1.怎麼獲得一個頁面的a標籤 (就說了getElementByTagName和選擇器) ####2.怎麼在頁面裏放置一個很簡單的圖標,不能用img和background-img (說了canvas,或者一些庫有icon庫,data-icon). ####3.正則表達式判斷url(只寫了判斷是不是http或者https開頭) [正則表達式匹配URL](http://blog.csdn.net/weasleyqi/article/details/7912647) ``` String check = @"((http|ftp|https)://)(([a-zA-Z0-9\._-]+\.[a-zA-Z]{2,6})|([0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}))(:[0-9]{1,4})*(/[a-zA-Z0-9\&%_\./-~-]*)?"; ``` ####4.怎麼去除字符串先後的空格 ``` (正則匹配^\s和\s$而且替代,Jquery的$.trim,string.trim()) tring.prototype.Trim = function(){return this.replace(/(^\s*)|(\s*$)/g, "");} g 爲全局標誌 ``` 正則表達式,JS裏一組特殊的東東,上例是替換文本前與後的空格,就等於trim。 ####實現頁面的局部刷新 ####websocket知道嗎? ####知道最近流行哪些前端技術嗎?我回答的nodejs ####用js使低版本瀏覽器支持HTML5標籤 底層是怎麼實現 ####實現一個可拖動的div **1.用原生JS實現一個接口,可以用Ajax上傳文件並顯示上傳進度,上傳完成後接收一個來自服務器的json數據** ####介紹一下主流的框架吧,angular 和react,原理,實現。 我把angular的watch digest這些講了個遍,也問了關於react的虛擬dom,爲何要這麼作,優點在哪裏? 使用這些前端的框架的優點是什麼,劣勢又是什麼 。 (看我把原理講的差很少,問我是否是在網上看了不少的這方面的文章,臥槽居然別發現了,這些東西都是我面試前一天看的,我立馬意識到不對),其實呢,框架對於我來講並非要熟悉多少它的api,而是要研究它的設計思想,這樣對本身之後的編碼也是有幫助的哈(成功避開話題) #### 由於項目中用過不少redis,不免要去解釋一下redis的底層實現, 首先說了說底層6大的數據結構,鏈表,字符串,字典,跳錶,壓縮列表等,redis是一個基於epoll的單線程模型,redis的應用舉例,在你的項目中如何使用,說到設置expire時間的時候,我給本身挖了個坑,面試官問我如何實現定時器,redis中有沒有定時器這個概念(實際上是沒有的)我入坑了, ,後來發現不對勁,趕忙說本身很久沒有研究這個底層了,有些概念可能有些模糊了。後來面試官提醒我是用epoll註冊事件的方法來實現expire的。自認爲redis應該是本身的加分項,沒有想到是減分項。 ####node.js有用過嗎? A:有,主要用一些工具,好比gulp ####你有用過什麼代碼管理工具 A://而後面試官看到簡歷上有GitHub就不問了 ####介紹MVVM模式; ####若是要你設計一個組件,你會如何設計 ####grunt用過哪些功能; ####瀏覽器如何匹配某個選擇器; ####websocket相關,輪詢,polling; ####ws和wss的區別; ###設計模式 ####要是讓你本身寫一個js框架你會用到哪些設計模式 ####日常在項目中用到過哪些設計模式,說說看 ####瞭解哪些設計模式說說看 ####說下你所瞭解的設計模式的優勢 ###其餘 ####頁面優化 ####移動端和pc差異 ####模塊化 ####說下你所理解的mvc與mvvc ####有沒有上傳過些什麼npm模塊