1.以下代碼的輸出是:
(function() {
var x=foo();
var foo=function foo() {
return "foobar"
};
return x;
})();
A. foo()
B. 類型錯誤
C. undefined
D. foobar
答案:B
JS中變量聲明珊拼、函數(shù)聲明會提升羹幸,而函數(shù)表達(dá)式不會提升钙皮。上面的代碼執(zhí)行順序是:var x; var foo; x=foo(); 執(zhí)行到這里會因?yàn)閒oo為undefined而報(bào)錯(foo is not a function)。如果是下面的代碼就不會報(bào)錯:
(function() {
var x=foo();
function foo() {
return "foobar"
};
return x;
})();
2.下面哪些語句可以 在JS里判斷一個對象oStringObject是否為String:
A. oStringObject instanceof String
B. typeof oStringObject == ‘string’
C. oStringObject is String
D. 以上答案都不正確
答案:A
var str1 = new String('js');
var str2 = 'js';
typeof str1; //object
typeof str2; //string
str1 instanceof String; //true
str2 instanceof String; //false
判斷一個變量是否是字符串的周全的辦法:
function isString(str){
return (typeof str == 'string')||(str instanceof String)
}
因?yàn)楸绢}中說的是一個對象oStringObject曼追,那它一定是用String構(gòu)造函數(shù)創(chuàng)建的對象窍仰,只能用instanceof。
需要注意的是用到instanceof時礼殊,關(guān)鍵字的左邊一定是對象驹吮,如果是基本類型的話那么返回一定是false,因?yàn)榛绢愋偷淖兞坎豢赡軐儆谌魏晤惛嘌啵缟厦娲a中的str2钥屈。關(guān)鍵字的右邊一定是類名,例如Object坝辫、String篷就、Array、Date等等或是用戶通過構(gòu)造函數(shù)自定義的類近忙,例如:
function Person(name){
this.name = name;
}
var p = new Person();
p instanceof Person; //true
typeof運(yùn)算符判斷的是變量的數(shù)據(jù)類型竭业。Js中的的數(shù)據(jù)類型有:undefined、null及舍、string未辆、number、boolean锯玛、object咐柜、(function)。使用typeof運(yùn)算符返回的結(jié)果只有以上7中攘残。function被作為一種特殊的object拙友,會返回function。通過對象字面量歼郭、內(nèi)建對象的構(gòu)造函數(shù)遗契、用戶自定義的構(gòu)造函數(shù)創(chuàng)建的對象都會返回object。
關(guān)于typeof和instanceof還有一個需要注意的是null病曾,這是Javascript的歷史遺留問題
typeof null; //object
null instanceof Object; //false
3.假設(shè) output 是一個函數(shù)牍蜂,輸出一行文本漾根。下面的語句輸出結(jié)果是什么?
output(typeof (function() {
output('Hello World!')
})()
);
答案:Hello World undefined
typeof 立即執(zhí)行函數(shù) 返回undefined喲
4.以下代碼的運(yùn)行結(jié)果:
var obj ={a:1,b:function () {alert(this.a)}};
var fun =obj.b;
fun();
答案:undefined
以上代碼這樣看比較清晰:
var foo = function(){
alert(this.a);
}
var obj ={a:1,b:foo};
var fun =obj.b;
fun();
foo是一個獨(dú)立的函數(shù)鲫竞,fun和obj.b都是對foo的引用辐怕。在函數(shù)中調(diào)用this時要根據(jù)具體的上下文來輸出,下面討論幾種上下文情況:
- 全局調(diào)用贡茅,默認(rèn)情況下執(zhí)行foo()秘蛇,此時的上下文是window。也就是代碼中通過fun()調(diào)用顶考。
- 對象的屬性方法調(diào)用,上下文是對象本身妖泄。也就是代碼中通過obj.b()調(diào)用的情況驹沿。
- call、apply調(diào)用蹈胡,上下文是指定的對象渊季。
- 構(gòu)造函數(shù)中調(diào)用,上下文是被創(chuàng)建的對象罚渐。
5.關(guān)于javascript的原始類型(primitive type)却汉,錯誤的是
A. 有5種primitive type,分別是Undefined荷并、Null合砂、Boolean、Number 和 String
B. var sTemp = “test string”; alert (typeof sTemp);結(jié)果為string
C. var oTemp;alert(oTemp == undefined)為true
D. alert(null == undefined);結(jié)果為false
答案:D
null == undefined; //true
null === undefined; //false
==和===的區(qū)別簡單的總結(jié)以下:
-
基本類型之間的比較
- 不同類型之間的比較:==會轉(zhuǎn)化為相同類型后比較值是否相等源织,===因類型不同直接返回false
- 相同類型的比較:直接比較值是否相等翩伪,兩者結(jié)果相同
-
引用類型之間的比較
- 兩者都比較地址是否相等
-
基本類型與引用類型的比較
- ==將引用類型轉(zhuǎn)化為基本類型后比較值是否相等,===因類型不同直接返回false
6.以下程序的運(yùn)行結(jié)果:
function Foo(){
var i=0;
return function(){
document.write(i++);
}
}
var f1=Foo(),
f2=Foo();
f1();
f1();
f2();
答案:010
關(guān)于閉包的概念和作用就不解釋了,這里想分析以下這兩段代碼(來自阮一峰博客):
代碼1:
var name = "The Window";
var object = {
name : "My Object",
getNameFunc : function(){
return function(){
return this.name;
};
}
};
alert(object.getNameFunc()());
代碼2:
var name = "The Window";
var object = {
name : "My Object",
getNameFunc : function(){
var that = this;
return function(){
return that.name;
};
}
};
alert(object.getNameFunc()());
代碼中object.getNameFunc()()取到的是getNameFunc的閉包谈息。有一點(diǎn)需要明確:閉包中this的上下文是全局作用域缘屹,而不是object;object.getNameFunc()中的this的上下文才是object侠仇。
第一段代碼中this.name取到的是window下的name轻姿,”This Window”。第二段代碼中由于在getNameFunc中將this存儲在that中逻炊,在閉包中就能訪問到this.name互亮。
7.下列描述中,關(guān)于 js 函數(shù)定義方式嗅骄,正確的是:
A. function add(a,b){return a+b;} 函數(shù)表達(dá)式
B. var add = new Function('a','b','return a+b') 函數(shù)表達(dá)式
C. function add(a,b){return a+b;} 函數(shù)聲明
D. var add = function(a,b){return a+b;} 函數(shù)聲明
E. var add = new Function('a','b','return a+b') 函數(shù)聲明
答案:C
//函數(shù)聲明
function add(a,b){return a+b;}
//函數(shù)表達(dá)式或函數(shù)字面量(函數(shù)本身為匿名函數(shù)胳挎,即使這里給了函數(shù)名的話也只能在函數(shù)內(nèi)部通過函數(shù)名調(diào)用)
var add = function(a,b){return a+b;}
//構(gòu)造函數(shù)或函數(shù)對象(可以接受任意數(shù)量的參數(shù),但最后一個始終被作為函數(shù)體)
var add = new Function('a','b','return a+b');
8.以下代碼的輸出結(jié)果是:
var f = function g() {
return 23;
};
typeof g();
A. number
B. undefined
C. function
D. 報(bào)錯
答案:D
函數(shù)表達(dá)式中的函數(shù)名是可選的溺森。如果具有函數(shù)名的話慕爬,那它相當(dāng)于函數(shù)內(nèi)部的一個變量窑眯,在函數(shù)外部是無法調(diào)用的,所以報(bào)錯會提示ReferenceError:g is not a function
医窿。
在函數(shù)表達(dá)式中使用命名函數(shù)的一個情況是函數(shù)遞歸磅甩,這樣也可以避免使用非標(biāo)準(zhǔn)的arguments.callee
屬性。
被函數(shù)表達(dá)式賦值的變量一定會有name屬性姥卢。name屬性可以看作函數(shù)的名字卷要,如果賦值的是匿名函數(shù)表達(dá)式時,name就是變量名独榴;如果賦值的是命名函數(shù)表達(dá)式時僧叉,name就是函數(shù)名。
9.下列描述錯誤的是:
A. 在原型上擴(kuò)展的可枚舉方法棺榔,會被for in循環(huán)出來
B. 使用object.defineProperty可向?qū)ο筇砑踊蛘咝薷膶傩?br>
C. 每個對象都有prototype屬性瓶堕,返回對象類型原型的引用
D. 通過hasOwnProperty可判斷一個對象以及其原型鏈上是否具有指定名稱的屬性
E. 原型鏈?zhǔn)荍S實(shí)現(xiàn)繼承的一種模型
F. For循環(huán)是按順序的,for in循環(huán)是不一定按順序的
答案:
關(guān)于for in和for of:
我們知道for in和for of最大的區(qū)別是:for in遍歷的到的是key症歇,for of遍歷的到的是value郎笆,因此更合理的做法是使用for in遍歷對象,使用for of遍歷數(shù)組忘晤。ES6中的for of功能很強(qiáng)大宛蚓,能夠遍歷數(shù)組、字符串设塔、Set凄吏、Map、NodeList和生成器壹置。
除此之外竞思,用for in遍歷數(shù)字還有很多弊端:
- for in能夠遍歷包括原型上的所有可遍歷的屬性。
- 遍歷不一定按照數(shù)組的內(nèi)部順序
ES6中提供了一種新的方法钞护,可以輕松的獲取對象的自有鍵:
var obj = {a:'a',b:'b'};
Object.keys(obj); //['a','b']
hasOwnProperty
用于判斷對象自身是否具有某屬性
definePeoperty
用于為對象添加或修改屬性盖喷,這里可以對屬性進(jìn)行更多的配置。在大部分的mvvm框架中會使用這個方法來實(shí)現(xiàn)數(shù)據(jù)綁定难咕。
10.如何判斷一個js對象是否是Array课梳。arr為要判斷的對象,其中最準(zhǔn)確的方法是余佃?
A.typeof(arr)
B. arr instanceof Array
C. arr.toString==='[object Array]'
D. Object.prototype.toString.call(arr) === '[object Array]'
答案:D
arr instanceof Array
返回true暮刃,但在跨frame對象構(gòu)建的場景下會失效背蟆。
arr.toString
是一個函數(shù)厦幅,調(diào)用toString將數(shù)組轉(zhuǎn)換為字符串:
var arr = [1,2,3];
arr.toString() //"1,2,3"
Object.prototype.toString.call()
可用于精確判斷對象的類型,它會返回object和對象類型的組合:
Object.prototype.toString.call(123); //[object Number]
Object.prototype.toString.call('123'); //[object String]
Object.prototype.toString.call([1,2,3]); //[object Array]
Object.prototype.toString.call({}); //[object Object]
Object.prototype.toString.call(new Date()); //[object Date]
Object.prototype.toString.call(new Function()); //[object Function]
但無法判斷用戶自定義的對象類型踪宠,會統(tǒng)一判斷為Object:
function Person(){}
Object.prototype.toString.call(new Person()); //[object Object]