- 1. JavaScript中如何檢測(cè)一個(gè)變量是一個(gè)String類型宋渔?請(qǐng)寫(xiě)出函數(shù)實(shí)現(xiàn)
- 2. 請(qǐng)用js去除字符串空格?
- 3. 獲取URL字符串中的參數(shù)
- 4. 怎樣添加、移除裳食、移動(dòng)、復(fù)制芙沥、創(chuàng)建和查找節(jié)點(diǎn)
- 5. 談?wù)劺厥諜C(jī)制方式及內(nèi)存管理
- 6. 寫(xiě)出3個(gè)使用this的典型應(yīng)用
- 7. 比較typeof與instanceof诲祸?
- 8.如何理解閉包?
- 9. 什么是跨域而昨?跨域請(qǐng)求資源的方法有哪些救氯?
- 10. javascript面向?qū)ο笾欣^承實(shí)現(xiàn)?
- 11. 判斷一個(gè)字符串中出現(xiàn)次數(shù)最多的字符歌憨,統(tǒng)計(jì)這個(gè)次數(shù)
- 12. 編寫(xiě)一個(gè)方法 去掉一個(gè)數(shù)組的重復(fù)元素
1. JavaScript中如何檢測(cè)一個(gè)變量是一個(gè)String類型着憨?請(qǐng)寫(xiě)出函數(shù)實(shí)現(xiàn)
1. typeof(obj) === "string"
2. typeof obj === "string"
3. obj.constructor === String
2. 請(qǐng)用js去除字符串空格?
- 使用replace正則匹配的方法
- 去除所有空格:str = str.replace(/\s*/g,"");
- 去除兩頭空格:str = str.replace(/^\s|\s$/g,"");
- 去除 左 空 格:str = str.replace( /^\s*/g, “”);
- 去除 右 空 格:str = str.replace(/(\s*$)/g, "");
- 實(shí)例如下:
var str = " 23 23 "; var str2 = str.replace(/\s*/g,""); console.log(str2); // 2323
3. 獲取URL字符串中的參數(shù)
測(cè)試地址為:http://www.runoob.com/jquery/misc-trim.html?channelid=12333&name=xiaoming&age=23
function showWindowHref(){
var sHref = window.location.href;
var args = sHref.split('?');
if(args[0] == sHref){
return "";
}
var arr = args[1].split('&');
var obj = {};
for(var i = 0;i< arr.length;i++){
var arg = arr[i].split('=');
obj[arg[0]] = arg[1];
}
return obj;
}
var href = showWindowHref(); // obj
console.log(href['name']); // xiaoming
4. 怎樣添加务嫡、移除甲抖、移動(dòng)、復(fù)制心铃、創(chuàng)建和查找節(jié)點(diǎn)
- 創(chuàng)建新節(jié)點(diǎn)
createDocumentFragment()
//創(chuàng)建一個(gè)DOM片段
createElement()
創(chuàng)建具體的元素
createTextNode()
//創(chuàng)建一個(gè)文本節(jié)點(diǎn) - 添加
appendChild()
//添加 - 移除
removeChild()
//移除 - 替換
replaceChild()
//替換 - 插入
insertBefore()
//插入 - 查找
getElementsByTagName()
//通過(guò)標(biāo)簽名稱
getElementsByName()
//通過(guò)元素的Name屬性的值
getElementById()
//通過(guò)元素Id准谚,唯一性
5. 談?wù)劺厥諜C(jī)制方式及內(nèi)存管理
-
回收機(jī)制方式
定義和用法:垃圾回收機(jī)制(GC:Garbage Collection),執(zhí)行環(huán)境負(fù)責(zé)管理代碼執(zhí)行過(guò)程中使用的內(nèi)存。
原理:垃圾收集器會(huì)定期(周期性)找出那些不在繼續(xù)使用的變量去扣,然后釋放其內(nèi)存柱衔。但是這個(gè)過(guò)程不是實(shí)時(shí)的,因?yàn)槠溟_(kāi)銷比較大厅篓,所以垃圾回收器會(huì)按照固定的時(shí)間間隔周期性的執(zhí)行秀存。
-
實(shí)例如下:
function fn1() { var obj = {name: 'hanzichi', age: 10}; } function fn2() { var obj = {name:'hanzichi', age: 10}; return obj; } var a = fn1(); var b = fn2();
fn1中定義的obj為局部變量,而當(dāng)調(diào)用結(jié)束后羽氮,出了fn1的環(huán)境或链,那么該塊內(nèi)存會(huì)被js引擎中的垃圾回收器自動(dòng)釋放;在fn2被調(diào)用的過(guò)程中档押,返回的對(duì)象被全局變量b所指向澳盐,所以該塊內(nèi)存并不會(huì)被釋放祈纯。
垃圾回收策略:標(biāo)記清除(較為常用)和引用計(jì)數(shù)。
-
標(biāo)記清除:
定義和用法:當(dāng)變量進(jìn)入環(huán)境時(shí)叼耙,將變量標(biāo)記"進(jìn)入環(huán)境"腕窥,當(dāng)變量離開(kāi)環(huán)境時(shí),標(biāo)記為:"離開(kāi)環(huán)境"筛婉。某一個(gè)時(shí)刻簇爆,垃圾回收器會(huì)過(guò)濾掉環(huán)境中的變量,以及被環(huán)境變量引用的變量爽撒,剩下的就是被視為準(zhǔn)備回收的變量入蛆。
到目前為止,IE硕勿、Firefox哨毁、Opera、Chrome源武、Safari的js實(shí)現(xiàn)使用的都是標(biāo)記清除的垃圾回收策略或類似的策略扼褪,只不過(guò)垃圾收集的時(shí)間間隔互不相同。
-
引用計(jì)數(shù):
定義和用法:引用計(jì)數(shù)是跟蹤記錄每個(gè)值被引用的次數(shù)粱栖。基本原理:就是變量的引用次數(shù)话浇,被引用一次則加1,當(dāng)這個(gè)引用計(jì)數(shù)為0時(shí)闹究,被視為準(zhǔn)備回收的對(duì)象凳枝。
-
內(nèi)存管理
-
什么時(shí)候觸發(fā)垃圾回收?
垃圾回收器周期性運(yùn)行跋核,如果分配的內(nèi)存非常多岖瑰,那么回收工作也會(huì)很艱巨,確定垃圾回收時(shí)間間隔就變成了一個(gè)值得思考的問(wèn)題砂代。
IE6的垃圾回收是根據(jù)內(nèi)存分配量運(yùn)行的蹋订,當(dāng)環(huán)境中的變量,對(duì)象刻伊,字符串達(dá)到一定數(shù)量時(shí)觸發(fā)垃圾回收露戒。垃圾回收器一直處于工作狀態(tài),嚴(yán)重影響瀏覽器性能捶箱。
IE7中智什,垃圾回收器會(huì)根據(jù)內(nèi)存分配量與程序占用內(nèi)存的比例進(jìn)行動(dòng)態(tài)調(diào)整,開(kāi)始回收工作丁屎。
合理的GC方案:(1)荠锭、遍歷所有可訪問(wèn)的對(duì)象; (2)、回收已不可訪問(wèn)的對(duì)象晨川。
GC缺陷:(1)证九、停止響應(yīng)其他操作删豺;
優(yōu)化策略:(1)、分代回收(Generation GC);(2)愧怜、增量GC
開(kāi)發(fā)過(guò)程中遇到的內(nèi)存泄露情況呀页,如何解決的?
-
-
內(nèi)存泄漏
- 定義和用法:內(nèi)存泄露是指一塊被分配的內(nèi)存既不能使用拥坛,又不能回收蓬蝶,直到瀏覽器進(jìn)程結(jié)束。C#和Java等語(yǔ)言采用了自動(dòng)垃圾回收方法管理內(nèi)存猜惋,幾乎不會(huì)發(fā)生內(nèi)存泄露疾党。我們知道,瀏覽器中也是采用自動(dòng)垃圾回收方法管理內(nèi)存惨奕,但由于瀏覽器垃圾回收方法有bug,會(huì)產(chǎn)生內(nèi)存泄露竭钝。
- 內(nèi)存泄露的幾種情況:
-
當(dāng)頁(yè)面中元素被移除或替換時(shí)梨撞,若元素綁定的事件仍沒(méi)被移除,在IE中不會(huì)作出恰當(dāng)處理香罐,此時(shí)要先手工移除事件卧波,不然會(huì)存在內(nèi)存泄露。
- 實(shí)例如下:
<div id="myDiv"> <input type="button" value="Click me" id="myBtn"> </div>
var btn = document.getElementById("myBtn"); btn.onclick = function(){ document.getElementById("myDiv").innerHTML = "Processing...";
- 解決方法如下:
<div id="myDiv"> <input type="button" value="Click me" id="myBtn"> </div>
var btn = document.getElementById("myBtn"); btn.onclick = function(){ btn.onclick = null; document.getElementById("myDiv").innerHTML = "Processing..."; }
- 實(shí)例如下:
-
由于是函數(shù)內(nèi)定義函數(shù)庇茫,并且內(nèi)部函數(shù)--事件回調(diào)的引用外暴了港粱,形成了閉包。閉包可以維持函數(shù)內(nèi)局部變量旦签,使其得不到釋放查坪。
- 實(shí)例如下:
function bindEvent(){ var obj=document.createElement("XXX"); obj.onclick=function(){ //Even if it's a empty function } }
- 解決方法如下:
function bindEvent(){ var obj=document.createElement("XXX"); obj.onclick=function(){ //Even if it's a empty function } obj=null; }
- 實(shí)例如下:
-
6. 寫(xiě)出3個(gè)使用this的典型應(yīng)用
-
在html元素事件屬性中使用,如:
<input type=”button” onclick=”showInfo(this);” value=”點(diǎn)擊一下”/>
-
構(gòu)造函數(shù)
function Animal(name, color) { this.name = name; this.color = color; }
-
input點(diǎn)擊宁炫,獲取值
<input type="button" id="text" value="點(diǎn)擊一下" />
var btn = document.getElementById("text"); btn.onclick = function() { alert(this.value); //此處的this是按鈕元素 }
-
apply()/call()求數(shù)組最值
var numbers = [5, 458 , 120 , -215 ]; var maxInNumbers = Math.max.apply(this, numbers); console.log(maxInNumbers); // 458 var maxInNumbers = Math.max.call(this,5, 458 , 120 , -215); console.log(maxInNumbers); // 458
7. 比較typeof與instanceof偿曙?
相同點(diǎn):JavaScript 中 typeof 和 instanceof 常用來(lái)判斷一個(gè)變量是否為空,或者是什么類型的羔巢。
typeof的定義和用法:返回值是一個(gè)字符串望忆,用來(lái)說(shuō)明變量的數(shù)據(jù)類型。
-
細(xì)節(jié):
typeof 一般只能返回如下幾個(gè)結(jié)果:number,boolean,string,function,object,undefined竿秆。
typeof 來(lái)獲取一個(gè)變量是否存在启摄,如 if(typeof a!="undefined"){alert("ok")},而不要去使用 if(a) 因?yàn)槿绻?a 不存在(未聲明)則會(huì)出錯(cuò)幽钢。
對(duì)于 Array,Null 等特殊對(duì)象使用 typeof 一律返回 object歉备,這正是 typeof 的局限性。
Instanceof定義和用法:instanceof 用于判斷一個(gè)變量是否屬于某個(gè)對(duì)象的實(shí)例匪燕。
-
實(shí)例演示:
a instanceof b?alert("true"):alert("false"); //a是b的實(shí)例威创?真:假 var a = new Array(); alert(a instanceof Array); // true alert(a instanceof Object) // true
如上落午,會(huì)返回 true,同時(shí) alert(a instanceof Object) 也會(huì)返回 true;這是因?yàn)?Array 是 object 的子類肚豺。
js function test(){}; var a = new test(); alert(a instanceof test) // true
-
細(xì)節(jié):
如下溃斋,得到的結(jié)果為‘N’,這里的 instanceof 測(cè)試的 object 是指 js 語(yǔ)法中的 object,不是指 dom 模型對(duì)象吸申。
if (window instanceof Object){ alert('Y')} else { alert('N');} // 'N'
8.如何理解閉包梗劫?
定義和用法:當(dāng)一個(gè)函數(shù)的返回值是另外一個(gè)函數(shù),而返回的那個(gè)函數(shù)如果調(diào)用了其父函數(shù)內(nèi)部的其它變量截碴,如果返回的這個(gè)函數(shù)在外部被執(zhí)行梳侨,就產(chǎn)生了閉包。
表現(xiàn)形式:使函數(shù)外部能夠調(diào)用函數(shù)內(nèi)部定義的變量日丹。
-
實(shí)例如下:
根據(jù)作用域鏈的規(guī)則走哺,底層作用域沒(méi)有聲明的變量,會(huì)向上一級(jí)找哲虾,找到就返回丙躏,沒(méi)找到就一直找,直到window的變量束凑,沒(méi)有就返回undefined晒旅。這里明顯count 是函數(shù)內(nèi)部的flag2 的那個(gè)count 。
var count=10; //全局作用域 標(biāo)記為flag1 function add(){ var count=0; //函數(shù)全局作用域 標(biāo)記為flag2 return function(){ count+=1; //函數(shù)的內(nèi)部作用域 alert(count); } } var s = add() s();//輸出1 s();//輸出2
-
變量的作用域
要理解閉包汪诉,首先必須理解Javascript特殊的變量作用域废恋。
變量的作用域分類:全局變量和局部變量。
-
特點(diǎn):
函數(shù)內(nèi)部可以讀取函數(shù)外部的全局變量扒寄;在函數(shù)外部無(wú)法讀取函數(shù)內(nèi)的局部變量鱼鼓。
函數(shù)內(nèi)部聲明變量的時(shí)候,一定要使用var命令该编。如果不用的話蚓哩,你實(shí)際上聲明了一個(gè)全局變量!
-
使用閉包的注意點(diǎn)
濫用閉包上渴,會(huì)造成內(nèi)存泄漏:由于閉包會(huì)使得函數(shù)中的變量都被保存在內(nèi)存中岸梨,內(nèi)存消耗很大,所以不能濫用閉包稠氮,否則會(huì)造成網(wǎng)頁(yè)的性能問(wèn)題曹阔,在IE中可能導(dǎo)致內(nèi)存泄露。解決方法是隔披,在退出函數(shù)之前赃份,將不使用的局部變量全部刪除。
會(huì)改變父函數(shù)內(nèi)部變量的值。所以抓韩,如果你把父函數(shù)當(dāng)作對(duì)象(object)使用纠永,把閉包當(dāng)作它的公用方法(Public Method),把內(nèi)部變量當(dāng)作它的私有屬性(private value)谒拴,這時(shí)一定要小心尝江,不要隨便改變父函數(shù)內(nèi)部變量的值。
9. 什么是跨域英上?跨域請(qǐng)求資源的方法有哪些炭序?
-
什么是跨域?
由于瀏覽器同源策略苍日,凡是發(fā)送請(qǐng)求url的協(xié)議惭聂、域名、端口三者之間任意一與當(dāng)前頁(yè)面地址不同即為跨域相恃。存在跨域的情況:
網(wǎng)絡(luò)協(xié)議不同辜纲,如http協(xié)議訪問(wèn)https協(xié)議。
端口不同拦耐,如80端口訪問(wèn)8080端口耕腾。
域名不同,如qianduanblog.com訪問(wèn)baidu.com揩魂。
子域名不同,如abc.qianduanblog.com訪問(wèn)def.qianduanblog.com炮温。
域名和域名對(duì)應(yīng)ip,如www.a.com訪問(wèn)20.205.28.90.
-
跨域請(qǐng)求資源的方法:
-
porxy代理
定義和用法:proxy代理用于將請(qǐng)求發(fā)送給后臺(tái)服務(wù)器火脉,通過(guò)服務(wù)器來(lái)發(fā)送請(qǐng)求,然后將請(qǐng)求的結(jié)果傳遞給前端柒啤。
實(shí)現(xiàn)方法:通過(guò)nginx代理倦挂;
注意點(diǎn):1、如果你代理的是https協(xié)議的請(qǐng)求担巩,那么你的proxy首先需要信任該證書(shū)(尤其是自定義證書(shū))或者忽略證書(shū)檢查方援,否則你的請(qǐng)求無(wú)法成功。
-
CORS 【Cross-Origin Resource Sharing】
定義和用法:是現(xiàn)代瀏覽器支持跨域資源請(qǐng)求的一種最常用的方式涛癌。
-
使用方法:一般需要后端人員在處理請(qǐng)求數(shù)據(jù)的時(shí)候犯戏,添加允許跨域的相關(guān)操作。如下:
res.writeHead(200, { "Content-Type": "text/html; charset=UTF-8", "Access-Control-Allow-Origin":'http://localhost', 'Access-Control-Allow-Methods': 'GET, POST, OPTIONS', 'Access-Control-Allow-Headers': 'X-Requested-With, Content-Type' });
-
jsonp
定義和用法:通過(guò)動(dòng)態(tài)插入一個(gè)script標(biāo)簽拳话。瀏覽器對(duì)script的資源引用沒(méi)有同源限制先匪,同時(shí)資源加載到頁(yè)面后會(huì)立即執(zhí)行(沒(méi)有阻塞的情況下)。
特點(diǎn):通過(guò)情況下弃衍,通過(guò)動(dòng)態(tài)創(chuàng)建script來(lái)讀取他域的動(dòng)態(tài)資源呀非,獲取的數(shù)據(jù)一般為json格式。
-
實(shí)例如下:
function testjsonp(data) { console.log(data.name); // 獲取返回的結(jié)果 }
var _script = document.createElement('script'); _script.type = "text/javascript"; _script.src = "http://localhost:8888/jsonp?callback=testjsonp"; document.head.appendChild(_script);
-
缺點(diǎn):
- 這種方式無(wú)法發(fā)送post請(qǐng)求(這里)
- 另外要確定jsonp的請(qǐng)求是否失敗并不容易,大多數(shù)框架的實(shí)現(xiàn)都是結(jié)合超時(shí)時(shí)間來(lái)判定岸裙。
-
10. javascript面向?qū)ο笾欣^承實(shí)現(xiàn)猖败?
面向?qū)ο蟮幕咎卣饔校悍忾]、繼承降允、多態(tài)恩闻。
-
在JavaScript中實(shí)現(xiàn)繼承的方法:
原型鏈(prototype chaining)
call()/apply()
混合方式(prototype和call()/apply()結(jié)合)
對(duì)象冒充
-
繼承的方法如下:
- prototype原型鏈方式:
function teacher(name){ this.name = name; } teacher.prototype.sayName = function(){ console.log("name is "+this.name); } var teacher1 = new teacher("xiaoming"); teacher1.sayName(); function student(name){ this.name = name; } student.prototype = new teacher() var student1 = new student("xiaolan"); student1.sayName(); // name is xiaoming // name is xiaolan
- call()/apply()方法
function teacher(name,age){ this.name = name; this.age = age; this.sayhi = function(){ alert('name:'+name+", age:"+age); } } function student(){ var args = arguments; teacher.call(this,args[0],args[1]); // teacher.apply(this,arguments); } var teacher1 = new teacher('xiaoming',23); teacher1.sayhi(); var student1 = new student('xiaolan',12); student1.sayhi(); // alert: name:xiaoming, age:23 // alert: name:xiaolan, age:12
- 混合方法【prototype,call/apply】
function teacher(name,age){ this.name = name; this.age = age; } teacher.prototype.sayName = function(){ console.log('name:'+this.name); } teacher.prototype.sayAge = function(){ console.log('age:'+this.age); } function student(){ var args = arguments; teacher.call(this,args[0],args[1]); } student.prototype = new teacher(); var student1 = new student('xiaolin',23); student1.sayName(); student1.sayAge(); // name:xiaolin // age:23
- 對(duì)象冒充
function Person(name,age){ this.name = name; this.age = age; this.show = function(){ console.log(this.name+", "+this.age); } } function Student(name,age){ this.student = Person; //將Person類的構(gòu)造函數(shù)賦值給this.student this.student(name,age); //js中實(shí)際上是通過(guò)對(duì)象冒充來(lái)實(shí)現(xiàn)繼承的 delete this.student; //移除對(duì)Person的引用 } var s = new Student("小明",17); s.show(); var p = new Person("小花",18); p.show(); // 小明, 17 // 小花, 18
- prototype原型鏈方式:
11. 判斷一個(gè)字符串中出現(xiàn)次數(shù)最多的字符,統(tǒng)計(jì)這個(gè)次數(shù)
var str = 'asdfssaaasasasasaa';
var json = {};
for (var i = 0; i < str.length; i++) {
if(!json[str.charAt(i)]){
json[str.charAt(i)] = 1;
}else{
json[str.charAt(i)]++;
}
};
var iMax = 0;
var iIndex = '';
for(var i in json){
if(json[i]>iMax){
iMax = json[i];
iIndex = i;
}
}
console.log('出現(xiàn)次數(shù)最多的是:'+iIndex+'出現(xiàn)'+iMax+'次');
12. 編寫(xiě)一個(gè)方法 去掉一個(gè)數(shù)組的重復(fù)元素
- 方法一:
var arr = [0,2,3,4,4,0,2]; var obj = {}; var tmp = []; for(var i = 0 ;i< arr.length;i++){ if( !obj[arr[i]] ){ obj[arr[i]] = 1; tmp.push(arr[i]); } } console.log(tmp); //結(jié)果如下: [0, 2, 3, 4]
- 方法二:
var arr = [2,3,4,4,5,2,3,6], arr2 = []; for(var i = 0;i< arr.length;i++){ if(arr2.indexOf(arr[i]) < 0){ arr2.push(arr[i]); } } console.log(arr2); 結(jié)果為:[2, 3, 4, 5, 6]
- 方法三:
var arr = [2,3,4,4,5,2,3,6]; var arr2 = arr.filter(function(element,index,self){ return self.indexOf(element) === index; }); console.log(arr2); //結(jié)果為:[2, 3, 4, 5, 6]