var str = "what fuck is 1235 going on ?"; var newArr = str.split(" "); for(var i=0,myArr=[];i<newArr.length;i++){ myArr.push(newArr[i].replace(newArr[i].charAt(0),newArr[i].charAt(0).toUpperCase())); } console.log(myArr); var myStr=myArr.join(" "); console.log(myStr);
<body> <div id="box"> </div> <button id="button">獲取顏色</button> </body>
$(function() { var search=location.search;//得到路徑 var params={};//定義一個空對象 if(params!=''){ var ps=search.slice(1).split('&');//截取?以後的路徑,並以&切割 for(var i=0;i<ps.length;i++){//遍歷參數數組 var arr=ps[i].split('=');//將數組每一個元素以=切割 params[arr[0]]=arr[1];// } } var userId=params.userId; });
方法一:
<script> //設置index保存 var oLi=document.getElementsByTagName('li'); for(var i=0;i<oLi.length;i++){ oLi[i].index=i; oLi[i].onclick=function(){ alert(this.index); } } </script>
方法二: <script> var oLi=document.getElementsByTagName('li'); for(var i=0; i<oLi.length; i++){ (function(j){ oLi[j].onclick = function(){ alert(j); }; })(i); }
</script>
<script> //方法一:indexof查找 var arr=new Array(1,2,2,2,3,3,5,6,8,8,9); Array.prototype.unique1=function(){ var n=[]; for(var i=0;i<arr.length;i++){ if(n.indexOf(arr[i])==-1){ n.push(arr[i]); } } return n; } alert(arr.unique1()); </script> <script> //方法二:hash var arr=new Array(1,2,2,2,3,3,5,6,8,8,9); Array.prototype.unique2=function(){ var hash={},//hash表 n=[];//臨時數組 for(var i=0;i<this.length;i++){ if(!hash[this[i]]){ //若是hash表中沒有當前項 hash[this[i]]=true;//存入hash表 n.push(this[i]);//當前元素push到臨時數組中 } } return n; } alert(arr.unique1()); </script>
var str="we are friends"; var maxLen=0; var index=""; var hash={}; for(var i=0;i<str.length;i++){ if(!hash[str.charAt(i)]){ hash[str.charAt(i)]=1; }else{ hash[str.charAt(i)]++; } } for(var i in hash){ if(hash[i]>maxLen){ maxLen=hash[i]; index=i; } } alert("出現次數最多的元素是:"+index+" 出現次數:"+maxLen);
function Trim(str){ return str.replace(/(^\s*)|(\s*$)/g, ""); }
function getLen(str){ var len=0; for(var i=0;i<str.length;i++){ if(str.charCodeAt(i)>255){//charCodeAt() 方法可返回指定位置的字符的 Unicode 編碼 len+=2; }else{ len++; } } return len; }
d(); e(); function d(){//用聲明的方式聲明的函數 alert('hello');//hello } var e = function(){//函數表達式 alert('world');//e is not a function }
function arrSort(arr){ var len=arr.length; var nu = ''; for(var i=0;i<=len-1;i++){ for(var j=0;j<=len-1-i;j++){ if(arr[j]>arr[j+1]){ nu=arr[j]; arr[j]=arr[j+1]; arr[j+1]=nu; } } } return arr; }
function getDay(){ var start = new Date(); var end = new Date(start.getFullYear()+1,'0'); var leftTime = (end.getTime()-start.getTime())/1000;//轉成秒 var second = Math.floor(leftTime%60);//取餘 var minute = Math.floor((leftTime/60))%60; var hour = Math.floor((leftTime/(60*60)))%24; var day = Math.floor((leftTime/(60*60*24)))%30; var month = Math.floor((leftTime/(60*60*24*30)))%12; return '距離明年還剩'+month+'月,'+day+'天,'+hour+'小時,'+minute+'分鐘,'+second+'秒'; } setInterval(function(){ var text=getDay(); document.getElementById('time').innerHTML=text; },1000);
jQuery中沒有提供這個功能,因此你須要先編寫兩個jQuery的擴展:
$.fn.stringifyArray = function(array) {
return JSON.stringify(array)
}
$.fn.parseArray = function(array) {
return JSON.parse(array)
} javascript
而後調用:
$("").stringifyArray(array)css
(1) [ ]==[ ]
答案:false.
數組,在 Javascript 中是對象,對象使用 == 比較都是比較的引用。
簡單的說,就是,若是是同一個對象,就相等,若是不是同一個對象,就不等。
每次使用 [] 都是新建一個數組對象,因此 [] == [] 這個語句裏建了兩個數據對象,它們不等。html
(2)Array.isArray(Array.prototype)前端
答案:true
Array.prototype爲[],Array.isArray(a)是一個判斷a是否爲數組的方法。vue
(3)聲明提早html5
var word="hello word";
(function(){
alert(word); //undefined
var word="hello test";
})();java
談話面試:jquery
解:1.全局上下文:不管是否在嚴格模式下,在全局執行上下文中(在任何函數體外部)this
都指代全局對象。【在全局執行上下文中 this
都是全局對象 window
】(瀏覽器環境)web
2.函數上下文:在函數內部,this
的值取決於函數被調用的方式。【取決於被調用的方式】面試
3.bind方法:ECMAScript 5
引入了 Function.prototype.bind
。調用 f.bind(someObject)
會 建立一個與 f
具備相同函數體和做用域的函數,可是在這個新函數中,this
將永久地被綁定到了 bind
的第一個參數,不管這個函數是如何被調用的。
4.箭頭函數:在箭頭函數中,this
與封閉詞法上下文的 this
保持一致。在全局代碼中,它將被設置爲全局對象
5.做爲對象的方法:當函數做爲對象裏的方法被調用時,它們的 this
是調用該函數的對象
6.原型鏈中的this:對於在對象原型鏈上某處定義的方法,一樣的概念也適用。若是該方法存在於一個對象的原型鏈上,那麼 this
指向的是調用這個方法的對象,就像該方法在對象上同樣。
7.做爲構造函數:當一個函數用做構造函數時(適用 new
關鍵字),它的 this
被綁定到正在構造的新對象。雖然構造器返回的默認值是 this
所指的那個對象,但它仍能夠手動返回其餘的對象(若是返回值不是一個對象,則返回 this
對象)
8.做爲DOM事件的處理函數:當函數被用做事件處理函數時,它的 this
指向觸發事件的元素(一些瀏覽器在使用非 addEventListener
的函數動態添加監聽函數時不遵照這個約定)
9.做爲一個內斂事件處理函數:當代碼被內聯 on-event
處理函數 調用時,它的 this
指向監聽器所在的 DOM
元素
解:須要先理解基本類型和引用類型:
ECMAScript 變量可能包含兩種不一樣數據類型的值:基本類型值和引用類型值。基本類型值指的是那些保存在棧內存中的簡單數據段,即這種值徹底保存在內存中的一個位置。而引用類型值是指那些保存堆內存中的對象,意思是變量中保存的實際只是這個對象的引用,這個引用指向堆內存中的對象。
目前基本類型有:Boolean、Null、Undefined、Number、String、Symbol。
引用類型有:Object、Array、Function。
深拷貝與淺拷貝的概念只存在於引用類型。
淺拷貝:
var obj1 = {x:1, y:2},obj2 = obj1; console.log(obj1) // {x:1, y:2} console.log(obj2) // {x:1, y:2} obj2.x = 2; // 修改obj2.x console.log(obj1) // {x:2, y:2} console.log(obj2) // {x:2, y:2}
深拷貝:
數組:slice()只能實現一維數組的深拷貝,Object.assign()也只能實現一維對象的深拷貝。 var arr1 = [1, 2], arr2 = arr1.slice(); console.log(arr1); //[1, 2] console.log(arr2); //[1, 2] arr2[0] = 3; //修改arr2 console.log(arr1); //[1, 2] console.log(arr2); //[3, 2]
解:可維護性:由於是單向數據流,全部狀態是有跡可循的,數據的傳遞也能夠及時分發響應
易用性:它使得咱們組件間的通信變得更強大,而不用藉助中間件這類來實現不一樣組件間的通信
並且代碼量很少,如果你要用 localStorage
或者 sessionStorage
,你必須手動去跟蹤維護你的狀態表,雖然說可行,可是代碼量會多不少,並且可讀性不好
localStorage
,sessionStorage
)?解:由於 vuex
的 store 幹不過刷新啊
保存在瀏覽器的緩存內,若用戶刷新的話,值再取一遍唄。
解:瀏覽器在請求不一樣域的資源時,會由於同源策略的影響請求不成功,這就是一般被提到的「跨域問題」。
同源策略",即同域名(domain或ip)、同端口、同協議的才能互相獲取資源,而不能訪問其餘域的資源。在同源策略影響下,一個域名A的網頁能夠獲取域名B下的腳本,css,圖片等,可是不能發送Ajax請求,也不能操做Cookie、LocalStorage等數據。同源策略的存在,一方面提升了網站的安全性,但同時在面對先後端分離、模擬測試等場景時,也帶來了一些麻煩,從而不得不尋求一些方法來突破限制,獲取資源。
解:父組件傳數據給子組件,經過props屬性來實現
<parent> <child :child-msg="msg"></child>//這裏必需要用 - 代替駝峯 </parent> data(){ return { msg: [1,2,3] }; }
方法一:
props: ['childMsg']
方法二:
props: {
childMsg: Array //這樣能夠指定傳入的類型,若是類型不對,會警告
}
方法三:
props: { childMsg: { type: Array, default: [0,0,0] //這樣能夠指定默認的值 } }
若是子組件想要改變數據呢?這在vue中是不容許的,由於vue只容許單向數據傳遞,這時候咱們能夠經過觸發事件來通知父組件改變數據,從而達到改變子組件數據的目的.emit
子組件: <template> <div @click="up"></div> </template> methods: { up() { this.$emit('upup','hehe'); //主動觸發upup方法,'hehe'爲向父組件傳遞的數據 } }
父組件: <div> <child @upup="change" :msg="msg"></child> //監聽子組件觸發的upup事件,而後調用change方法 </div> methods: { change(msg) { this.msg = msg; } }
vue的生命週期鉤子
每一個 Vue 實例在被建立以前都要通過一系列的初始化過程。例如須要設置數據監聽、編譯模板、掛載實例到 DOM、在數據變化時更新 DOM 等。同時在這個過程當中也會運行一些叫作生命週期鉤子的函數,給予用戶機會在一些特定的場景下添加他們本身的代碼。
beforeCreate: //建立以前:vue實例的掛載元素$el和數據對象data都爲undefined,還未初始化。
created: //建立完畢:vue實例的數據對象data有了,$el尚未
beforeMount: //掛載前,vue實例的$el和data都初始化了,但仍是掛載以前爲虛擬的DOM節點,data.message還未替換。
mounted: // 掛載完畢,data.message成功渲染。
beforeUpdate: // 修改vue實例的data時,vue會自動更新渲染視圖
beforeDestroy: // 銷燬以前
destroyed: // 銷燬成功
深刻響應式原理
當你把一個普通的javascript對象傳給vue實例的data選項,vue將遍歷此對象全部的屬性,並使用Object.defineProperty把這些屬性所有轉爲getter/setter
這些getter/setter對用戶來講是不可見的,可是在內部他們讓vue追蹤依賴,在屬性被訪問和修改時通知變化。這裏須要注意的問題是瀏覽器控制檯在打印數據對象時getter/setter的格式化並不一樣,因此須要安裝vue-devtools來獲取更加友好的檢查接口。
每一個組件實例都有相應的watcher實例對象,他會在組件渲染的過程當中把屬性記錄爲依賴,以後當依賴的setter被調用時,會通知watcher從新計算,從而導致它關聯的組件得以更新。
⦁ Vue中實現了數據的雙向綁定,爲了支持雙向綁定,就必須時刻追蹤數據變化並及時響應到ui上。
⦁ Vue經過Object.defineProperty()設置對象的存儲器屬性,並對對象中的每一個值,重寫了其中的get、set,data中的每一個key,都有一個獨立的依賴收集器。
⦁ 在get中,向依賴收集器添加了監聽
⦁ 在mount時,實例了一個Watcher,將收集器的目標指向了當前Watcher
⦁ 在data值發生變動時,觸發set,觸發了依賴收集器中的全部監聽的更新,來觸發Watcher.update
Vue中的MVVM模式
vue是以數據驅動的,vue自己將Dom和數據進行綁定,一旦建立綁定,DOM和數據將保持同步,每當數據發生變化,DOM會跟着變化。ViewModel是vue的核心,它是vue的一個實例。
Vue中的狀態管理
Vuex 是一個專爲 Vue.js 應用程序開發的狀態管理模式。它採用集中式存儲管理應用的全部組件的狀態,並以相應的規則保證狀態以一種可預測的方式發生變化。
computed和watch的區別
計算屬性的結果會被緩存,除非依賴的響應式屬性變化纔會從新計算
監聽某一個值,當被監聽的值發生變化時,執行對應的操做
與computed的區別是,watch更加適用於監聽某一個值的變化並作對應的操做,好比請求後臺接口等,而computed適用於計算已有的值並返回結果
解:javaScript的事件代理也叫事件委託。
好比咱們有100個li,每一個li都有相同的click點擊事件,可能咱們會用for循環的方法,來遍歷全部的li,而後給它們添加事件,
通俗的講,事件就是onclick,onmouseover,onmouseout,等就是事件,
代理呢,就是讓別人來作,這個事件原本是加在某些元素上的,然而你卻加到別人身上來作,完成這個事件。
就是利用事件冒泡的原理,把事件加到父級元素上,觸發執行效果。從而能夠很大程度上來提升執行的效率、並且就算新添加了元素仍是會有代理的事件
解:相同,call和apply,專門用於借用一個函數,並替換函數中的this爲指定對象。
不一樣,call要求傳入函數的參數必須獨立傳入。
apply要求傳入函數的參數必須放入一個數組或集合中,總體傳入。
解:web存儲,在開發web應用時,開發人員有時須要在本地存儲數據,當前瀏覽器支持cookie存儲,但其大小有4KB限制。
html5中的web存儲對象有兩種類型:
sessionStorage對象,負責存儲一個會話的數據。若是用戶關閉了頁面或瀏覽器,則會銷燬數據,一次會話結束,存儲的信息會自動刪除,
存儲的數據沒法垮頁面存在,只在當前頁面。
localStorage對象,負責存儲沒有到期的數據,當web頁面或瀏覽器關閉時,仍會保持數據的存儲,固然這還取決於爲此用戶的瀏覽器設置
的存儲量,若是不是人爲刪除,存儲的信息會一直保留,存儲的數據內容是能夠跨頁的。
解:設置width=device-width,而後用百分比來分配屏幕寬度,高度自適應變化,字體也使用相對大小em,rem等等
移動瀏覽器提供一個特殊的功能:雙擊(double tap)放大
300ms的延遲就來自這裏,用戶碰觸頁面以後,須要等待一段時間來判斷是否是雙擊(double tap)動做,而不是當即響應單擊(click),等待的這段時間大約是300ms。
a、不要混用touch和click
既然touch以後300ms會觸發click,只用touch或者只用click就天然不會存在問題了
在javaScript中一切皆對象,可是對象又分爲函數對象和普通對象,經過new出來的都是函數對象,function是默認的函數對象,函數對象有一個默認的屬性prototype,指向原型對象。原型對象上的方法和屬性,能夠被這個函數建立的實例引用。
this.name = 'John'; } Person.prototype = { say: function() { console.log('Hello,' + this.name); } }; var person = new Person(); person.say();//person.say is not a function
//函數B想要使用函數A的變量
functionSuper(){
this
.val = 1;
this
.arr = [1];
}
function
Sub(){
// ...
}
Sub.prototype =
new
Super();
// 核心
var
sub1 =
new
Sub();
var
sub2 =
new
Sub();
sub1.val = 2;
sub1.arr.push(2);
alert(sub1.val);
// 2
alert(sub2.val);
// 1
alert(sub1.arr);
// 1, 2
alert(sub2.arr);
// 1, 2
上傳前用js對圖片壓縮,把利用canvas生成的base64字符串,傳入後臺, * (無所謂ajax或者form,同時也能夠解決圖片無刷新上傳), * 在Java後臺將獲取到的base64字符串輸出爲圖片,便可。
解:實際上是拿手機拍照的方向問題,iphone正確的手機拍照方式是橫屏的,用戶每每是豎屏拍照等於照相機反轉了90度,出來的照片固然是反轉90度,當你橫屏拍照上傳,圖片就是正確的,一張生成的圖片是沒法辨別選擇方向的,只有在上傳前反轉角度才行。
//獲取圖片方向 function getPhotoOrientation(img) { var orient; EXIF.getData(img, function () { orient = EXIF.getTag(this, 'Orientation'); }); return orient; }
//圖片壓縮 function compress(img, width, height, ratio) { var canvas, ctx, img64, orient; //獲取圖片方向 orient = getPhotoOrientation(img); canvas = document.createElement('canvas'); canvas.width = width; canvas.height = height; ctx = canvas.getContext("2d"); //若是圖片方向等於6 ,則旋轉矯正,反之則不作處理 if (orient == 6) { ctx.save(); ctx.translate(width / 2, height / 2); ctx.rotate(90 * Math.PI / 180); ctx.drawImage(img, 0 - height / 2, 0 - width / 2, height, width); ctx.restore(); } else { ctx.drawImage(img, 0, 0, width, height); } img64 = canvas.toDataURL("image/jpeg", ratio); return img64; }
解:路由是根據不一樣的 url 地址展現不一樣的內容或頁面
前端路由更多用在單頁應用上, 也就是SPA, 由於單頁應用, 基本上都是先後端分離的, 後端天然也就不會給前端提供路由。
優勢:
1.從性能和用戶體驗的層面來比較的話,後端路由每次訪問一個新頁面的時候都要向服務器發送請求,而後服務器再響應請求,這個過程確定會有延遲。而前端路由在訪問一個新頁面的時候僅僅是變換了一下路徑而已,沒有了網絡延遲,對於用戶體驗來講會有至關大的提高。
2.在某些場合中,用ajax請求,可讓頁面無刷新,頁面變了但Url沒有變化,用戶就不能複製到想要的地址,用前端路由作單頁面網頁就很好的解決了這個問題
缺點:
使用瀏覽器的前進,後退鍵的時候會從新發送請求,沒有合理地利用緩存。
16.請講解一下閉包?
解:包就是可以讀取其餘函數內部變量的函數。因爲在Javascript語言中,只有函數內部的子函數才能讀取局部變量,所以能夠把閉包簡單理解成「定義在一個函數內部的函數」。
因此,在本質上,閉包就是將函數內部和函數外部鏈接起來的一座橋樑。閉包能夠用在許多地方。它的最大用處有兩個,一個是前面提到的能夠讀取函數內部的變量,另外一個就是讓這些變量的值始終保持在內存中。
使用閉包的注意點:
因爲閉包會使得函數中的變量都被保存在內存中,內存消耗很大,因此不能濫用閉包,不然會形成網頁的性能問題,在IE中可能致使內存泄露。解決方法是,在退出函數以前,將不使用的局部變量所有刪除。
閉包會在父函數外部,改變父函數內部變量的值。因此,若是你把父函數看成對象(object)使用,把閉包看成它的公用方法(Public Method),把內部變量看成它的私有屬性(private value),這時必定要當心,不要隨便改變父函數內部變量的值。
17.js中的做用域和做用域鏈
做用域指變量和函數的可以使用範圍,在JavaScript中變量的做用域分爲局部做用域和全局做用域。1.全局做用域
(1)最外層函數和在最外層函數外面定義的變量擁有全局做用域
(2)全部末定義直接賦值的變量自動聲明爲擁有全局做用域。
(3)全部window對象的屬性擁有全局做用域
2.局部做用域
函數內部聲明的變量。
3.做用域鏈
程序執行的時候會建立一個執行環境棧,首先將window的執行環境壓入到執行環境棧中,window是全局的,裏面存放全局的變量和函數。
當調用一個函數的時候,會將這個函數的執行環境壓入到執行環境棧中,而且還會建立這個函數的活動對象,指向活動對象。活動對象中保存
函數內部的變量也就是局部變量,活動對象指向window。
函數調用完以後,它的執行環境會被釋放,它指向的活動對象也會被釋放。活動對象中保存的局部變量也被釋放。當查找一個變量時,首先去
活動對象中查找,找不到就沿着做用域鏈向下查找,若是window中都找不到,就會報錯。格局做用於逐級引用造成做用域鏈。
18.同步和異步
同步就是指一個進程在執行某個請求的時候,若該請求須要隔一段時間才能返回信息,那麼這個進程會一直等待下去,直到收到返回消息纔會繼續執行下去
異步請求是指進程不須要一直等待下去,而是繼續執行下面的操做,無論其餘進程的狀態。當有消息返回時,系統會通知進程進行處理,這樣能夠提升執行效率。
setTimeout(function cbFn(){ console.log('learnInPro'); }, 1000); console.log('sync things');
setTimeout就是一個異步任務
,當JS引擎順序執行到setTimeout的時候發現他是個異步任務,則會把這個任務掛起,繼續執行後面的代碼。直到1000ms後,回調函數cbFn纔會執行,這就是異步,在執行到setTimeout的時候,JS並不會傻呵呵的等着1000ms執行cbFn回調函數,而是繼續執行了後面的代碼
爲何要在js中寫異步?
因爲javascript是單線程的,只能在JS引擎的主線程上運行的,因此js代碼只能一行一行的執行,不能在同一時間執行多個js代碼任務,這就致使若是有一段耗時較長的計算,或者是一個ajax請求等IO操做,若是沒有異步的存在,就會出現用戶長時間等待,而且因爲當前任務還未完成,因此這時候全部的其餘操做都會無響應。
11.http://blog.csdn.net/gaoshanwudi/article/details/7355794閉包
19.重載
argument。length判斷參數的個數。
20.熱加載
21.vue的缺點
22.不固定高寬div垂直居中的方法
<div class="block" style="height: 300px;"> <div class="centered"> <h1>haorooms案例題目</h1> <p>haorooms案例內容,haorooms案例內容haorooms案例內容haorooms案例內容haorooms案例內容haorooms案例內容haorooms案例內容haorooms案例內容haorooms案例內容</p> </div> </div>
/* This parent can be any width and height */ .block { text-align: center; } /* The ghost, nudged to maintain perfect centering */ .block:before { content: ''; display: inline-block; height: 100%; vertical-align: middle; margin-right: -0.25em; /* Adjusts for spacing */ } /* The element to be centered, can also be of any width and height */ .centered { display: inline-block; vertical-align: middle; width: 50%; }
普通函數能夠在聲明以前調用,
匿名函數會被當作普通表達式,存在聲明提早。
a();
//a函數能夠在它定義的前面調用
b();
//b函數這樣調用就會出「未定義」錯誤
function
a()
{
alert(
"aaaaaa"
);
}
var
b =
function
()
{
alert(
"bbbbbb"
);
}
大體能夠分爲以下7步:
輸入網址;
發送到DNS服務器,並獲取域名對應的web服務器對應的ip地址;
與web服務器創建TCP鏈接;
瀏覽器向web服務器發送http請求;
web服務器響應請求,並返回指定url的數據(或錯誤信息,或重定向的新的url地址);
瀏覽器下載web服務器返回的數據及解析html源文件;
生成DOM樹,解析css和js,渲染頁面,直至顯示完成;
23.jquey如何擴展自定義方法
(jQuery.fn.myMethod=function(){ alert('myMethod'); }) // 或者: (function($){ $.fn.extend({ myMethod: function(){ alert('myMethod') } }) })(jQuery)
// 使用
$("#div").myMethod();