1..sort 排序原理
冒泡排序法解析:冒泡排序法的原理:
比較相鄰的元素魔吐。如果第一個比第二個大,就交換他們兩個莱找。
對每一對相鄰元素做同樣的工作酬姆,從開始第一對到結(jié)尾的最后一對奥溺。在這一點(diǎn),最后的元素應(yīng)該會是最大的數(shù)相满。
針對所有的元素重復(fù)以上的步驟层亿,除了最后一個。
持續(xù)每次對越來越少的元素重復(fù)上面的步驟立美,直到?jīng)]有任何一對數(shù)字需要比較。
示例:
var arr = [1, 5, 4, 2];
// sort()方法的比較邏輯為:
// 第一輪:1和5比碌更,1和4比,1和2比
// 第二輪:5和4比洞慎,5和2比
// 第三輪:4和2比// 一.sort排序規(guī)則 return大于0則交換數(shù)組相鄰2個元素的位置
// 二.arr.sort(function (a,b) {})中
// a --?代表每一次執(zhí)行匿名函時候痛单,找到的數(shù)組中的當(dāng)前項;
// b --?代表當(dāng)前項的后一項桦他;
// 1.升序
var apple = [45, 42, 10, 147, 7, 65, -74];
// ①默認(rèn)法,缺點(diǎn):只根據(jù)首位排序
console.log(apple.sort());
// ②指定排序規(guī)則法,return可返回任何值
console.log(
apple.sort(function(a, b) {
return a - b; //若return返回值大于0(即a>b),則a,b交換位置
})
);
//2.降序
var arr = [45, 42, 10, 111, 7, 65, -74];
console.log(
apple.sort(function(a, b) {
return b - a; //若return返回值大于零(即b>a),則a,b交換位置
})
);參考 1谆棱、參考 2
2.JavaScript 的數(shù)據(jù)類型
JS 數(shù)據(jù)類型共有六種垃瞧,分別是 String、Number个从、Boolean、Null嫌松、Undefined 和 Object 等奕污, 另外,ES6 新增了 Symbol 類型贾陷。其中嘱根,Object 是引用類型,其他的都是基本類型(Primitive Type)慌洪。
3.call() 和 apply() 的含義和區(qū)別?
首先說明兩個方法的含義:
call:調(diào)用一個對象的一個方法割岛,用另一個對象替換當(dāng)前對象。例如:B.call(A, args1,args2);即 A 對象調(diào)用 B 對象的方法犯助。
apply:調(diào)用一個對象的一個方法,用另一個對象替換當(dāng)前對象惠爽。例如:B.apply(A, arguments);即 A 對象應(yīng)用 B 對象的方法瞬哼。
call 與 apply 的相同點(diǎn):
方法的含義是一樣的,即方法功能是一樣的较性;
第一個參數(shù)的作用是一樣的结胀;
call 與 apply 的不同點(diǎn):兩者傳入的列表形式不一樣
call 可以傳入多個參數(shù);
apply 只能傳入兩個參數(shù)攀操,所以其第二個參數(shù)往往是作為數(shù)組形式傳入
4.Zepto 的點(diǎn)透問題如何解決秸抚?
方案一:來得很直接 github 上有個 fastclick 可以完美解決https://github.com/ftlabs/fastclick引入 fastclick.js剥汤,因?yàn)?fastclick 源碼不依賴其他庫所以你可以在原生的 js 前直接加上
window.addEventListener(
"load",
function() {
FastClick.attach(document.body);
},
false
);
或者有 zepto 或者 jqm 的 js 里面加上
$(function() {
FastClick.attach(document.body);
});
當(dāng)然 require 的話就這樣:
var FastClick = require("fastclick");
FastClick.attach(document.body, options);
方案二:用 touchend 代替 tap 事件并阻止掉 touchend 的默認(rèn)行為 preventDefault()$("#cbFinish").on("touchend", function(event) {
//很多處理比如隱藏什么的
event.preventDefault();
});
方案三:延遲一定的時間(300ms+)來處理事件
$("#cbFinish").on("tap", function(event) {
setTimeout(function() {
//很多處理比如隱藏什么的
}, 320);
});
這種方法其實(shí)很好,可以和 fadeInIn/fadeOut 等動畫結(jié)合使用
5..如何判斷當(dāng)前腳本運(yùn)行在瀏覽器還是 node 環(huán)境中慈迈?
通過判斷 Global 對象是否為 window省有,如果不為 window蠢沿,當(dāng)前腳本沒有運(yùn)行在瀏覽器中
6.移動端最小觸控區(qū)域是多大匾效?
蘋果推薦是 44pt x 44pt解析:參考
7.解釋 JavaScript 中的作用域與變量聲明提升?
對作用域的理解是只會對某個范圍產(chǎn)生作用野宜,而不會對外產(chǎn)生影響的封閉空間。在這樣的一些空間里河胎,外部不能訪問內(nèi)部變量虎敦,但內(nèi)部可以訪問外部變量。
所有申明都會被提升到作用域的最頂上
同一個變量申明只進(jìn)行一次胚迫,并且因此其他申明都會被忽略
函數(shù)聲明的優(yōu)先級優(yōu)于變量申明唾那,且函數(shù)聲明會連帶定義一起被提升
8.Node.js 的適用場景?
比如:RESTFUL API期犬、實(shí)時聊天昌罩、客戶端邏輯強(qiáng)大的單頁 APP,具體的例子比如說:本地化的在線音樂應(yīng)用遣总,本地化的在線搜索應(yīng)用轨功,本地化的在線 APP 等古涧。解析:參考
9.如何判斷一個對象是否屬于某個類?
instanceof解析:if (a instanceof Person) {
alert("yes");
}
10.bind菇爪、call柒昏、apply 的區(qū)別
call 和 apply 其實(shí)是一樣的,區(qū)別就在于傳參時參數(shù)是一個一個傳或者是以一個數(shù)組的方式來傳氏涩。
call 和 apply 都是在調(diào)用時生效,改變調(diào)用者的 this 指向意系。
let name = 'Jack'
const obj = {name: 'Tom'}
function sayHi() {console.log('Hi! ' + this.name)}
sayHi() // Hi! Jack
sayHi.call(obj) // Hi! Tom
bind 也是改變 this 指向饺汹,不過不是在調(diào)用時生效,而是返回一個新函數(shù)作郭。
const newFunc = sayHi.bind(obj)
newFunc() // Hi! Tom
11.移動端的點(diǎn)擊事件的有延遲弦疮,時間是多久胁塞,為什么會有? 怎么解決這個延時编检?
300 毫秒
因?yàn)闉g覽器捕獲第一次單擊后扰才,會先等待一段時間,如果在這段時間區(qū)間里用戶未進(jìn)行下一次點(diǎn)擊蕾总,則瀏覽器會做單擊事件的處理琅捏。如果這段時間里用戶進(jìn)行了第二次單擊操作,則瀏覽器會做雙擊事件處理蚀浆。
推薦 fastclick.js
12.如何實(shí)現(xiàn)文件斷點(diǎn)續(xù)傳
斷點(diǎn)續(xù)傳最核心的內(nèi)容就是把文件“切片”然后再一片一片的傳給服務(wù)器搜吧,但是這看似簡單的上傳過程卻有著無數(shù)的坑滤奈。首先是文件的識別,一個文件被分成了若干份之后如何告訴服務(wù)器你切了多少塊据忘,以及最終服務(wù)器應(yīng)該如何把你上傳上去的文件進(jìn)行合并搞糕,這都是要考慮的。因此在文件開始上傳之前汉规,我們和服務(wù)器要有一個“握手”的過程驹吮,告訴服務(wù)器文件信息,然后和服務(wù)器約定切片的大小啄枕,當(dāng)和服務(wù)器達(dá)成共識之后就可以開始后續(xù)的文件傳輸了族沃。前臺要把每一塊的文件傳給后臺脆淹,成功之后前端和后端都要標(biāo)識一下,以便后續(xù)的斷點(diǎn)漓糙。當(dāng)文件傳輸中斷之后用戶再次選擇文件就可以通過標(biāo)識來判斷文件是否已經(jīng)上傳了一部分烘嘱,如果是的話,那么我們可以接著上次的進(jìn)度繼續(xù)傳文件为狸,以達(dá)到續(xù)傳的功能遗契。
有了 HTML5 的 File api 之后切割文件比想想的要簡單的多的多牍蜂。只要用 slice 方法就可以了var packet = file.slice(start, end);
參數(shù) start 是開始切片的位置,end 是切片結(jié)束的位置 單位都是字節(jié)辐怕。通過控制 start 和 end 就可以是實(shí)現(xiàn)文件的分塊如file.slice(0,1000);
file.slice(1000,2000);
file.slice(2000,3000);
// ......
在把文件切成片之后从绘,接下來要做的事情就是把這些碎片傳到服務(wù)器上是牢。
如果中間掉線了驳棱,下次再傳的時候就得先從服務(wù)器獲取上一次上傳文件的位置农曲,然后以這個位置開始上傳接下來的文件內(nèi)容。
13.使用構(gòu)造函數(shù)的注意點(diǎn)
一般情況下構(gòu)造函數(shù)的首字母需要大寫形葬,因?yàn)槲覀冊诳吹揭粋€函數(shù)首字母大寫的情況暮的,就認(rèn)定這是一個構(gòu)造函數(shù)青扔,需要跟new關(guān)鍵字進(jìn)行搭配使用,創(chuàng)建一個新的實(shí)例(對象)
構(gòu)造函數(shù)在被調(diào)用的時候需要跟new關(guān)鍵字搭配使用谈息。
在構(gòu)造函數(shù)內(nèi)部通過this+屬性名的形式為實(shí)例添加一些屬性和方法凛剥。
構(gòu)造函數(shù)一般不需要返回值,如果有返回值
13.1 如果返回值是一個基本數(shù)據(jù)類型逻炊,那么調(diào)用構(gòu)造函數(shù)余素,返回值仍舊是那么創(chuàng)建出來的對象炊昆。
13.2 如果返回值是一個復(fù)雜數(shù)據(jù)類型,那么調(diào)用構(gòu)造函數(shù)的時候视乐,返回值就是這個return之后的那個復(fù)雜數(shù)據(jù)類型敢茁。
14.數(shù)組的常用方法
Array.map()
此方法是將數(shù)組中的每個元素調(diào)用一個提供的函數(shù)彰檬,結(jié)果作為一個新的數(shù)組返回谎砾,并沒有改變原來的數(shù)組
let arr = [1, 2, 3, 4, 5];
let newArr = arr.map(x =? x * 2);
//arr= [1, 2, 3, 4, 5] 原數(shù)組保持不變
//newArr = [2, 4, 6, 8, 10] 返回新數(shù)組
Array.forEach()
此方法是將數(shù)組中的每個元素執(zhí)行傳進(jìn)提供的函數(shù)棺榔,沒有返回值隘道,直接改變原數(shù)組郎笆,注意和 map 方法區(qū)分
let arr = [1, 2, 3, 4, 5];
num.forEach(x =? x * 2);
// arr = [2, 4, 6, 8, 10] 數(shù)組改變,注意和map區(qū)分
Array.filter()
此方法是將所有元素進(jìn)行判斷宛蚓,將滿足條件的元素作為一個新的數(shù)組返回
let arr = [1, 2, 3, 4, 5]
const isBigEnough =? value =? value ?= 3
let newArr = arr.filter(isBigEnough )
//newNum = [3, 4, 5] 滿足條件的元素返回為一個新的數(shù)組
Array.every()
此方法是將所有元素進(jìn)行判斷返回一個布爾值,如果所有元素都滿足判斷條件远舅,則返回 true痕钢,否則為 false:
let arr = [1, 2, 3, 4, 5]
const isLessThan4 =? value =? value ? 4
const isLessThan6 =? value =? value ? 6
arr.every(isLessThan4 ) //false
arr.every(isLessThan6 ) //true
Array.some()
此方法是將所有元素進(jìn)行判斷返回一個布爾值任连,如果存在元素都滿足判斷條件,則返回 true裁着,若所有元素都不滿足判斷條件拱她,則返回 false:
let arr= [1, 2, 3, 4, 5]
const isLessThan4 =? value =? value ? 4
const isLessThan6 =? value =? value ? 6
arr.some(isLessThan4 ) //true
arr.some(isLessThan6 ) //false
Array.reduce()
此方法是所有元素調(diào)用返回函數(shù),返回值為最后結(jié)果,傳入的值必須是函數(shù)類型:
let arr = [1, 2, 3, 4, 5];
const add = (a, b) =? a + b;
let sum = arr.reduce(add);
//sum = 15
相當(dāng)于累加的效果與之相對應(yīng)的還有一個 Array.reduceRight() 方法桶雀,區(qū)別是這個是從右向左操作的
Array.push()
此方法是在數(shù)組的后面添加新加元素背犯,此方法改變了數(shù)組的長度:
Array.pop()
此方法在數(shù)組后面刪除最后一個元素盅抚,并返回數(shù)組,此方法改變了數(shù)組的長度:
let arr = [1, 2, 3, 4, 5];
arr.pop();
console.log(arr); //[1, 2, 3, 4]
console.log(arr.length); //4
Array.shift()
此方法在數(shù)組后面刪除第一個元素柱锹,并返回數(shù)組,此方法改變了數(shù)組的長度:
let arr = [1, 2, 3, 4, 5];
arr.shift();
console.log(arr); //[2, 3, 4, 5]
console.log(arr.length); //4
Array.unshift()
此方法是將一個或多個元素添加到數(shù)組的開頭壤巷,并返回新數(shù)組的長度:
let arr = [1, 2, 3, 4, 5];
arr.unshift(6, 7);
console.log(arr); //[6, 7, 2, 3, 4, 5]
console.log(arr.length); //7
Array.isArray()
判斷一個對象是不是數(shù)組胧华,返回的是布爾值
Array.concat()
此方法是一個可以將多個數(shù)組拼接成一個數(shù)組:
let arr1 = [1, 2, 3]
arr2 = [4, 5]
let arr = arr1.concat(arr2)
console.log(arr)//[1, 2, 3, 4, 5]
. Array.toString()
此方法將數(shù)組轉(zhuǎn)化為字符串:
```js
let arr = [1, 2, 3, 4, 5];
let str = arr.toString()
console.log(str)// 1,2,3,4,5
Array.join()
此方法也是將數(shù)組轉(zhuǎn)化為字符串
```js
let arr = [1, 2, 3, 4, 5];
let str1 = arr.toString()
let str2 = arr.toString(',')
let str3 = arr.toString('##')
console.log(str1)// 12345
console.log(str2)// 1,2,3,4,5
console.log(str3)// 1##2##3##4##5
通過例子可以看出和 toString 的區(qū)別矩动,可以設(shè)置元素之間的間隔
Array.splice(開始位置释漆, 刪除的個數(shù),元素)
萬能方法示姿,可以實(shí)現(xiàn)增刪改:
let arr = [1, 2, 3, 4, 5];
let arr1 = arr.splice(2, 0 'haha')
let arr2 = arr.splice(2, 3)
let arr1 = arr.splice(2, 1 'haha')
console.log(arr1) //[1, 2, 'haha', 3, 4, 5]新增一個元素
console.log(arr2) //[1, 2] 刪除三個元素
console.log(arr3) //[1, 2, 'haha', 4, 5] 替換一個元素
15..如何獲取瀏覽器版本信息
window.navigator.userAgent
16..字符串常用操作
charAt(index):返回指定索引處的字符串
charCodeAt(index):返回指定索引處的字符的 Unicode 的值
concat(str1,str2,...):連接多個字符串栈戳,返回連接后的字符串的副本
fromCharCode():將 Unicode 值轉(zhuǎn)換成實(shí)際的字符串
indexOf(str):返回 str 在父串中第一次出現(xiàn)的位置览露,若沒有則返回-1
lastIndexOf(str):返回 str 在父串中最后一次出現(xiàn)的位置,若沒有則返回-1
match(regex):搜索字符串命锄,并返回正則表達(dá)式的所有匹配
replace(str1,str2):str1 也可以為正則表達(dá)式脐恩,用 str2 替換 str1
search(regex):基于正則表達(dá)式搜索字符串侦讨,并返回第一個匹配的位置
slice(start,end):返回字符索引在 start 和 end(不含)之間的子串
split(sep,limit):將字符串分割為字符數(shù)組骗污,limit 為從頭開始執(zhí)行分割的最大數(shù)量
substr(start沈条,length):從字符索引 start 的位置開始,返回長度為 length 的子串
substring(from,to):返回字符索引在 from 和 to(不含)之間的子串
toLowerCase():將字符串轉(zhuǎn)換為小寫
toUpperCase():將字符串轉(zhuǎn)換為大寫
valueOf():返回原始字符串值
17.作用域的概念及作用
作用域 : 起作用的一塊區(qū)域
作用域的概念: 對變量起保護(hù)作用的一塊區(qū)域
作用: 作用域外部無法獲取到作用域內(nèi)部聲明的變量涕烧,作用域內(nèi)部能夠獲取到作用域外界聲明的變量汗洒。
18.call 與 apply 區(qū)別
第二個參數(shù)的類型不同解析:call 和 apply 的作用,完全一樣瞻凤,唯一的區(qū)別就是在參數(shù)上面世杀。call 接收的參數(shù)不固定玫坛,第一個參數(shù)是函數(shù)體內(nèi) this 的指向包晰,第二個參數(shù)以下是依次傳入的參數(shù)。apply 接收兩個參數(shù)勉痴,第一個參數(shù)也是函數(shù)體內(nèi) this 的指向蒸矛。第二個參數(shù)是一個集合對象(數(shù)組或者類數(shù)組)
19.正則表達(dá)式構(gòu)造函數(shù) var reg = new RegExp('xxx')與正則表達(dá)字面量 var reg = // 有什么不同胸嘴?
使用正則表達(dá)字面量的效率更高解析:下面的示例代碼演示了兩種可用于創(chuàng)建正則表達(dá)式以匹配反斜杠的方法:
//正則表達(dá)字面量
var re = /\\/gm;
//正則構(gòu)造函數(shù)
var reg = new RegExp("\\\\", "gm");
var foo = "abc\\123"; // foo的值為"abc\123"
console.log(re.test(foo)); //true
console.log(reg.test(foo)); //true如上面的代碼中可以看到,使用正則表達(dá)式字面量表示法時式子顯得更加簡短乡话,而且不用按照類似類(class-like)的構(gòu)造函數(shù)方式思考绑青。其次屋群,在當(dāng)使用構(gòu)造函數(shù)的時候,在這里要使用四個反斜杠才能匹配單個反斜杠邪乍。這使得正則表達(dá)式模式顯得更長,更加難以閱讀和修改喊熟。正確來說姐刁,當(dāng)使用 RegExp()構(gòu)造函數(shù)的時候聂使,不僅需要轉(zhuǎn)義引號(即"表示"),并且通常還需要雙反斜杠(即\表示一個\)弃理。使用 new RegExp()的原因之一在于屎蜓,某些場景中無法事先確定模式炬转,而只能在運(yùn)行時以字符串方式創(chuàng)建。參考
20.js 中 callee 與 caller 的作用
caller 返回一個調(diào)用當(dāng)前函數(shù)的引用 如果是由頂層調(diào)用的話 則返回 null
(舉個栗子哈 caller 給你打電話的人 誰給你打電話了 誰調(diào)用了你 很顯然是下面 a 函數(shù)的執(zhí)行 只有在打電話的時候你才能知道打電話的人是誰 所以對于函數(shù)來說 只有 caller 在函數(shù)執(zhí)行的時候才存在)
var callerTest = function() {
console.log(callerTest.caller);
};
function a() {
callerTest();
}
a(); //輸出function a() {callerTest();}
callerTest(); //輸出null
callee 返回一個正在被執(zhí)行函數(shù)的引用 (這里常用來遞歸匿名函數(shù)本身 但是在嚴(yán)格模式下不可行)
callee 是 arguments 對象的一個成員 表示對函數(shù)對象本身的引用 它有個 length 屬性(代表形參的長度)
var c = function(x, y) {
console.log(arguments.length, arguments.callee.length, arguments.callee);
};
c (1, 2, 3); //輸出3 2 function(x,y) {console.log(arguments.length,arguments.callee.length,arguments.callee)}