1.如何判別Object饱苟、Array對象
通過Object.prototype.toString可以檢測Object和Array(isArray對于檢測Array很靠譜)
letobj={};
letarr=[];
console.log(Object.prototype.toString.call(obj));//[object Object]
console.log(Object.prototype.toString.call(arr));//[object Array]
console.log(Object.prototype.toString.call(null));//[object Null]
參考:你有必要知道的一些JavaScript 面試題(上)、在JavaScript中,如何判斷數(shù)組是數(shù)組仅财?
2.從這里可以知道self=this操作的意義(this的綁定):
var myObject = {
foo: "bar",
func: function() {
var self = this;
console.log( this.foo);//bar
console.log( self.foo);//bar
(function() {
console.log( this.foo);//undefined
console.log(self.foo);//bar
}());
}
};
myObject.func();
this還可以優(yōu)雅的綁定:
varobj = {
func:function()?{},
say:function()?{
//?此時(shí)的this就是obj對象
setTimeout(function()?{
console.log(this)
this.func()
}.bind(this));
}
}
obj.say();//?obj
3.會輸出什么妖泄?
console.log(1+"2"+"2");
console.log(1++"2"+"2");
console.log(1+-"1"+"2");
console.log(+"1"+"1"+"2");
console.log("A"-"B"+"2");
console.log("A"-"B"+2);
4.
var a={},
b={key:'b'},
c={key:'c'};
a[b]=123;
a[c]=456;
console.log(a[b]);
reason:
The reason for this is as follows: When setting an object property, JavaScript will implicitly stringify the parameter value. In this case, since b and c are both objects, they will both be converted to “[object Object]”. As a result, a[b] anda[c] are both equivalent to a[“[object Object]”] and can be used interchangeably. Therefore, setting or referencing a[c] is precisely the same as setting or referencing a[b].
5.給你一個(gè) DOM 元素趟佃,創(chuàng)建一個(gè)能訪問該元素所有子元素的函數(shù),并且要將每個(gè)子元素傳遞給指定的回調(diào)函數(shù)锣尉。
function Traverse(p_element,p_callback) {
p_callback(p_element);
var list = p_element.children;
for (var i = 0; i < list.length; i++) {
Traverse(list[i],p_callback);? // recursive call
}
}
6.實(shí)現(xiàn)深度復(fù)制
https://juejin.cn/post/6904158317447217160
淺拷貝:
function shallowClone(o){
? ? ? let obj={}
? ? ? for(let key in o){
? ? ? ? ? obj[key]=o[key]
? ? ? }
? ? ? return obj
}
深拷貝:
function deepCopy(source){
? ? ? ? if (typeof source != "object") {
? ? ? ? ? return source;
? ? ? ? }
? ? ? ? if (source == null) {
? ? ? ? ? ? return source;
? ? ? ? }
? ? ? ? var newObj = source.constructor === Array ? [] : {};? //開辟一塊新的內(nèi)存空間
? ? ? ? for (var i in source) {
? ? ? ? ? ? newObj[i] = deepCopy(source[i]);? ? ? ? ? ? ? ? //通過遞歸實(shí)現(xiàn)深層的復(fù)制
? ? ? ? }
? ? ? ? return newObj;
}
source.constructor === Array 其實(shí)應(yīng)該是source.__proto__.constructor ===?Array,但source找不到constructor屬性决采,會往上原型鏈上找
7.setTimeout ?0
var fuc = [1,2,3];
for(var i in fuc){
setTimeout(function(){console.log(fuc[i])},0);
console.log(fuc[i]);
}
雖然setTimeout函數(shù)在每次循環(huán)的開始就調(diào)用了自沧,但是卻被放到循環(huán)結(jié)束才執(zhí)行,循環(huán)結(jié)束树瞭,i=3,接連打印了3次3拇厢。
這里涉及到j(luò)avascript單線程執(zhí)行的問題:javascript在瀏覽器中是單線程執(zhí)行的,必須在完成當(dāng)前任務(wù)后才執(zhí)行隊(duì)列中的下一個(gè)任務(wù)晒喷。
另外孝偎,對于javascript還維護(hù)著一個(gè)setTimeout隊(duì)列,未執(zhí)行的setTimeout任務(wù)就按出現(xiàn)的順序放到setTimeout隊(duì)列厨埋,等待普通的任務(wù)隊(duì)列中的任務(wù)執(zhí)行完才開始按順序執(zhí)行積累在setTimeout中的任務(wù)邪媳。
所以在這個(gè)問題里,會先打印1 2 3荡陷,而將setTimeout任務(wù)放到setTimeout任務(wù)隊(duì)列雨效,等循環(huán)中的打印任務(wù)執(zhí)行完了,才開始執(zhí)行setTimeout隊(duì)列中的函數(shù)废赞,所以在最后會接著打印3次3徽龟。
由此,可以知道雖然設(shè)置為0秒后執(zhí)行任務(wù)唉地,實(shí)際上是大于0秒才執(zhí)行的据悔〈福可是這有什么用呢?
用處就在于我們可以改變?nèi)蝿?wù)的執(zhí)行順序极颓!因?yàn)闉g覽器會在執(zhí)行完當(dāng)前任務(wù)隊(duì)列中的任務(wù)朱盐,再執(zhí)行setTimeout隊(duì)列中積累的的任務(wù)。
通過設(shè)置任務(wù)在延遲到0s后執(zhí)行菠隆,就能改變?nèi)蝿?wù)執(zhí)行的先后順序兵琳,延遲該任務(wù)發(fā)生,使之異步執(zhí)行骇径。
7.JSONP
8.JavaScript事件委托的技術(shù)原理
事件流:事件捕獲階段躯肌,處于目標(biāo)階段和事件冒泡階段。
事件捕獲是從外層元素到目標(biāo)元素的過程破衔,事件冒泡是從目標(biāo)元素到外層元素的過程清女。如圖:
事件委托的原理就是利用了事件冒泡,只需在DOM樹中盡量最高的層次上添加一個(gè)事件處理程序晰筛,從而管理某一類型的所有事件嫡丙。
添加到頁面上的事件處理程序的數(shù)量直接影響到頁面的整體性能,原因:
????1)每個(gè)函數(shù)都是對象传惠,都會占用內(nèi)存迄沫,內(nèi)存中對象越多,性能就越差
????2)事先綁定所有的事件處理程序而導(dǎo)致的DOM訪問次數(shù)卦方,也會延遲整個(gè)頁面的交互就緒時(shí)間
對“事件處理程序過多”問題的解決方案就是事件委托羊瘩,因?yàn)橹蝗〉昧艘粋€(gè)DOM,只添加了一個(gè)事件處理程序盼砍,與普通方法相比尘吗,結(jié)果一樣,但占用的內(nèi)存更少浇坐。
9.瀏覽器加載睬捶、解析、渲染的過程
10.HTTP POST GET 本質(zhì)區(qū)別詳解
(1)GET提交近刘,請求的數(shù)據(jù)會附在URL之后擒贸;POST提交:把提交的數(shù)據(jù)放置在是HTTP包的包體中。
(2)GET提交時(shí)觉渴,傳輸數(shù)據(jù)就會受到URL長度的 限制介劫。POST:由于不是通過URL傳值,理論上數(shù)據(jù)不受 限案淋。
(3)POST的安全性要比GET的安全性高座韵。
11.從輸入U(xiǎn)RL到頁面加載完成的過程中都發(fā)生了什么事情?
(1)輸入地址
(2)瀏覽器查找域名的IP地址
? ? ? ? ? ?這一步包括DNS具體的查找過程,包括:瀏覽器緩存->系統(tǒng)緩存->路由器緩存...
(3)瀏覽器向web服務(wù)器發(fā)送一個(gè)HTTP請求
(4)服務(wù)器的永久重定向響應(yīng)(從http://example.com到http://www.example.com)
(5)瀏覽器跟蹤重定向地址
(6)服務(wù)器處理請求
(7)服務(wù)器返回一個(gè)HTTP響應(yīng)
(8)瀏覽器顯示HTML
(9)瀏覽器發(fā)送請求獲取嵌入在HTML中的資源(如圖片誉碴、音頻宦棺、視頻、CSS黔帕、JS等等)
(10)瀏覽器發(fā)送異步請求
12.什么是語義化的html代咸?
(1)有利于SEO,有利于搜索引擎爬蟲更好的理解我們的網(wǎng)頁成黄,從而獲取更多的有效信息侣背,提升網(wǎng)頁的權(quán)重。
(2)在沒有CSS的時(shí)候能夠清晰的看出網(wǎng)頁的結(jié)構(gòu)慨默,增強(qiáng)可讀性,能夠便于開發(fā)者閱讀和寫出更優(yōu)雅的代碼弧腥。
13.href和src有什么區(qū)別厦取?
href 表示超文本引用(hypertext reference),在 link和a 等元素上使用管搪。src 表示來源地址虾攻,在 img、script更鲁、iframe 等元素上霎箍。
src和href之間存在區(qū)別,能混淆使用澡为。src用于替換當(dāng)前元素漂坏,href用于在當(dāng)前文檔和引用資源之間確立聯(lián)系。
當(dāng)瀏覽器解析到該元素時(shí)媒至,會暫停其他資源的下載和處理顶别,直到將該資源加載、編譯拒啰、執(zhí)行完畢驯绎,圖片和框架等元素也如此,類似于將所指向資源嵌入當(dāng)前標(biāo)簽內(nèi)谋旦。這也是為什么將js腳本放在底部而不是頭部剩失。
href是Hypertext Reference的縮寫,指向網(wǎng)絡(luò)資源所在位置册着,建立和當(dāng)前元素(錨點(diǎn))或當(dāng)前文檔(鏈接)之間的鏈接拴孤,如果我們在文檔中添加
那么瀏覽器會識別該文檔為css文件,就會并行下載資源并且不會停止對當(dāng)前文檔的處理指蚜。這也是為什么建議使用link方式來加載css乞巧,而不是使用@import方式。