內(nèi)置類型
JavaScript 有七種內(nèi)置類型:
? 空值(null) ? 未定義(undefined) ? 布爾值( boolean) ? 數(shù)字(number) ? 字符串(string) ? 對(duì)象(object) ? 符號(hào)(symbol书劝,ES6 中新增)
- 除對(duì)象之外住册,其他統(tǒng)稱為“基本類型”。
- 我們可以用typeof 運(yùn)算符來查看值的類型弄捕,它返回的是類型的字符串值摔笤。
- 有意思的是会油,這七種類型和它們的字符串值并不一一對(duì)應(yīng):
typeof undefined === "undefined"; // true
typeof true === "boolean"; // true
typeof 42 === "number"; // true
typeof "42" === "string"; // true
typeof { life: 42 } === "object"; // true
typeof Symbol() === "symbol"; // true ES6中新加入的類型
而在對(duì)變量執(zhí)行typeof 操作時(shí),得到的結(jié)果并不是該變量的類型贾费,而是該變量持有的值的類型钦购,因?yàn)镴avaScript 中的變量沒有類型。
你可能注意到null 類型不在此列褂萧。它比較特殊押桃,typeof 對(duì)它的處理有問題:
typeof null === "object"; // true
正確的返回結(jié)果應(yīng)該是"null",但這個(gè)bug 由來已久箱玷,在JavaScript 中已經(jīng)存在了將近二十年怨规,也許永遠(yuǎn)也不會(huì)修復(fù)陌宿,因?yàn)檫@牽涉到太多的Web 系統(tǒng),“修復(fù)”它會(huì)產(chǎn)生更多的bug波丰,令許多系統(tǒng)無法正常工作壳坪。
我們需要使用復(fù)合條件來檢測(cè)null 值的類型:
var a = null;
(!a && typeof a === "object"); // true
null 是基本類型中唯一的一個(gè) “假值”(falsy 或者false-like)類型,typeof 對(duì)它的返回值為"object"掰烟。實(shí)際上爽蝴,null 本身是基本類型。
- 數(shù)組也是對(duì)象纫骑。確切地說蝎亚,它也是object 的一個(gè)“子類型”
- 除了undefined和null其他三個(gè)都有相應(yīng)的構(gòu)造器函數(shù),分別是Number()先馆、String()发框、Boolean()。通過這些可以創(chuàng)建出相應(yīng)的對(duì)象煤墙,通過將這些基本類型封裝成對(duì)象梅惯,就可以在其中繼承一些有用的工作方法。
其調(diào)用分為兩種形式:
1)使用new操作符調(diào)用--用于新建對(duì)象仿野。
2)不使用new操作符調(diào)用铣减,用于將任意符轉(zhuǎn)換為基本數(shù)據(jù)類型。
操作符
操作符 | 相關(guān)操作 | 代碼實(shí)例 |
---|---|---|
++ | 自增1操作 | 當(dāng)操作符后置脚作,先返回該值葫哗,然后再遞增1var a=123; var b=a++; b //123; a //124 當(dāng)操作符前置,先將值遞增1球涛,再返回 var a=123; var b=++a; b //124; a //124
|
-- | 自減1操作 | 操作符后置var a=123; var b=a--; b //123; a //122 操作符前置 var a=123; var b=--a; b //122; a //12
|
- 操作符優(yōu)先級(jí):劣针!> && > || (最佳操作是使用括號(hào))
- == 相等運(yùn)算符,在該比較操作之前亿扁,兩邊的操作數(shù)會(huì)會(huì)被自動(dòng)轉(zhuǎn)換為相同的類型如:1==“1”;將返回true
而===等價(jià)運(yùn)算符其幕后不存在任何形式的類型轉(zhuǎn)換酿秸。此外!=存在類型轉(zhuǎn)換,!==不允許類型轉(zhuǎn)換 - 如果在同一個(gè)值上執(zhí)行兩次邏輯非運(yùn)輸魏烫,其結(jié)果就等于原值;
var b=!!true; b; 將返回true
- 如果在一個(gè)非布爾值上執(zhí)行邏輯運(yùn)算肝箱,該值會(huì)在運(yùn)算期間轉(zhuǎn)換為布爾值:
var b="one"; !b; 將返回false;!!b;將會(huì)返回true;
- 檢驗(yàn)一個(gè)字符串中是否包含另一個(gè)字符串哄褒,可以用-1來做indexOf()結(jié)果比照(是區(qū)分大小寫的)
if (s.indexOf('Couch') !== -1){.....}
注意if (s.indexOf('Couch')){.....}
是不對(duì)的,因?yàn)樗饕悼赡苁?煌张,會(huì)被轉(zhuǎn)換為falsh
變量
- 變量沒有類型呐赡,但它們持有的值有類型。類型定義了值的行為特征骏融,通過typeof 的安全防范機(jī)制(阻止報(bào)錯(cuò))來檢查undeclared 變量链嘀,有時(shí)是個(gè)不錯(cuò)的辦法萌狂。
- 注意當(dāng)?shù)诙卧O(shè)置變量時(shí),就不需要再使用var語句了怀泊。
var n=1; n=1234;
- 檢查變量是否存在:
if(typeof somevar !==‘undefined’){result=‘yes’;}
變量的作用域
這是一個(gè)至關(guān)重要的問題茫藏,js語言不能為變量定義特定的塊作用域,但可以定義其所屬的函數(shù)域霹琼,函數(shù)外不可見务傲。而如果該變量定義在if或for代碼塊中,它在代碼塊以外是可見的枣申。
- 還有一點(diǎn)很重要售葡,聲明一個(gè)變量時(shí)沒有用var語句,該變量會(huì)被默認(rèn)為全局變量忠藤,在函數(shù)中的這種變量也一樣挟伙,不過要訪問到需要函數(shù)首先被調(diào)用過,也可以說在該函數(shù)被調(diào)用之前模孩,這個(gè)沒有var的變量是不存在的
function f(){local=2;} //local為全局變量
local尖阔; //ReferenceError: local is not defined
f(); //注意這里函數(shù)執(zhí)行后,函數(shù)內(nèi)的全局變量才能訪問到
local瓜贾; //2
注意:函數(shù)域始終優(yōu)先于全局域
var a=123;
function f(){
alert(a); //undefined; a的聲明會(huì)提升到函數(shù)體頂端诺祸,而賦值留在書寫的位置
var a=1; //1
alert (a);
}
f() //1
函數(shù)
- function(函數(shù))也是JavaScript 的一個(gè)內(nèi)置類型,然而查閱規(guī)范就會(huì)知道祭芦,它實(shí)際上是object 的一個(gè)“子類型”筷笨。具體來說,函數(shù)是“可調(diào)用對(duì)象”龟劲,它有一個(gè)內(nèi)部屬性[[Call]]胃夏,該屬性使其可以被調(diào)用。
函數(shù)對(duì)象中最重要的還是prototype屬性昌跌;每個(gè)函數(shù)的prototype屬性中都包含了一個(gè)對(duì)象(內(nèi)建對(duì)象)仰禀;它只有在該函數(shù)是構(gòu)造器時(shí)才會(huì)發(fā)揮作用;
每次某個(gè)函數(shù)被調(diào)用蚕愤,就會(huì)有個(gè)新的執(zhí)行上下文為其創(chuàng)建答恶,即使是調(diào)用的自身函數(shù),也是如此
var some_obj={
name:'Ninjia',
say: function(){
return 'I am a ' + this.name;
}
}
function F(){}
typeof F.prototype; //"object"
F.prototype = some_obj;
var obj=new F(); //----------------------------- 作為構(gòu)造器
obj.say() //"I am a Ninjia"
Function 對(duì)象的方法:
函數(shù)對(duì)象中有兩個(gè)非常有用的方法:call() 和 applay()萍诱,通過這兩個(gè)方法我們就能讓對(duì)象去借用其他對(duì)象中的方法悬嗓,為己所用。這也是一種重用代碼的方式裕坊,非常簡(jiǎn)單實(shí)用
call()方法:
var some_obj={
name:'Ninjia',
say: function(who){
return 'Haya ' + who + ', I am a ' + this.name;
}
}
some_obj.say('qing') //"Haya qing, I am a Ninjia"
再創(chuàng)建一個(gè)無方法的my_obj對(duì)象
my_obj = {name: 'zhu'};
some_obj.say.call(my_obj,'niro') // "Haya niro, I am a zhu"
實(shí)際上就是通過call的首參數(shù)修改了對(duì)象函數(shù)this的值包竹。當(dāng)say()被調(diào)用時(shí),其中的this就被自動(dòng)設(shè)置成了my_obj對(duì)象的引用,this.name返回的不再是Ninija了周瞎,call方法可以傳遞更多的參數(shù)apply()與call()基本相同苗缩,不同在于參數(shù)的傳遞形式(apply是數(shù)組傳遞)some_obj.apple(my_obj,['qing']);
js循環(huán)(四種)
js中有四種循環(huán):while循環(huán) 、do-while循環(huán)声诸、for循環(huán)酱讶、for-in循環(huán)
while循環(huán)是最為簡(jiǎn)單的一種:分為兩個(gè)部分:小括號(hào)中的條件和大括號(hào)中的的代碼塊,僅當(dāng)條件為true是代碼塊才會(huì)被反復(fù)執(zhí)行双絮。
var i=0;
while(i<10){
i++;
}
for 循環(huán)
打印一個(gè)5行5列的星號(hào)字符串圖形
var res='\n'; //讓第一個(gè)星號(hào)回行
for(var i=0; i<5; i++){
for(var j=0; j<5; j++){
res +='* '; //這里實(shí)際上是重新定義變量res浴麻,j 循環(huán)是列出一行5個(gè)星號(hào)。
}
res +='\n'; //這里是循環(huán)在每行加一個(gè)回行符囤攀。
}
返回:
* * * * * * * * * *
* * * * * * * * * *
* * * * * * * * * *
* * * * * * * * * *
* * * * * * * * * *
加深理解
var res='\n'; //定義變量并讓第一行換行
for(var i=0; i<10; i++){
for(var j=0; j<5; j++){
res +='*'; //這里輸出的是一行5個(gè)星
}
res +='\n' + i; //這里輸出的是10列软免,沒有換行符的話就是在每5顆星后一個(gè)序列數(shù)字
}
"
*****
0*****
1*****
2*****
3*****
4*****
5*****
6*****
7*****
8*****
9"
乘法口訣:
var res='\n';
for(var i =1 ;i<=9;i++){
for(var j=1 ;j<=i;j++){ //---------------------重點(diǎn)j<=i
res +=(i+"*"+j+"="+(i*j)+" "); //----------核心是(i*j)
}
res +="\n";
}
for-in 循環(huán):
往往用來遍歷一某個(gè)數(shù)組或?qū)ο笾械脑兀旅娲蛴〕鰯?shù)組當(dāng)前所在的位置鍵值和元素值
var a = ['a','b','c','d'];
var result='\n';
for(var i in a){ //
result += 'index: ' + i + ', value: ' + a[i]+ '\n';
} // ------------------------------核心只是result += a[i]
打印出:
index: 0, value: a
index: 1, value: b
index: 2, value: c
index: 3, value: d
下面將所有對(duì)象屬性復(fù)制在一個(gè)數(shù)組中:
var o={x:1,y:2,z:3};
var a=[],i=0;
for(a[i++] in o); // 這里很簡(jiǎn)單焚挠,a和i上面已經(jīng)聲明過了結(jié)果就是a[0]膏萧、a[1]...
console.log(a) // 輸出["x", "y", "z"]
location (瀏覽器對(duì)象模型BOM的組成部分):
使用location對(duì)象可以通過編程方式來訪問瀏覽器的導(dǎo)航系統(tǒng),設(shè)置相應(yīng)的屬性蝌衔、可以逐段或整體地 修改瀏覽器的URL.
如:假設(shè)初始URL為http://www.zunyang.com/okzu/
將URL修改為"http://www.zunyang.com/okzu/#sectino1"
location.hash="#sectino1";
將URL修改為"http://www.zunyang.com/okzu/zun/"
location.pathname="zun" ;
將URL修改為"http://www.zunyang.com/okzu/?q=javascript"
location.search="?q=javascript"
等等榛泛,此外還有hostname、port
HTML5 classList屬性的方法
toggle噩斟、contains曹锨、add、remove
toggle 如果列表中已經(jīng)存在給定的值剃允,刪除她沛简,如果沒有就添加
div.classList.toggle("myClass");
確定元素中是否包含既定的類名
if(div.classList.contains("db) && !div.classList.contains("disable")){}
刪除類名remove,添加add
readyState 屬性
有兩個(gè)可能的值
1.loading,正在加載文檔 2.complete,已經(jīng)加載完文檔
if(documengt.readyState == "complete"){//執(zhí)行操作}
內(nèi)存與性能問題
在使用innerHTML斥废、outerHTML屬性椒楣、insertAdjacentHTML()方法時(shí)(以上都是HTML5規(guī)范),最好先手動(dòng)刪除要被替換元素的所有事件處理程序和JS對(duì)象屬性牡肉。假設(shè)某個(gè)HTML元素有一個(gè)事件處理程序或引用了一個(gè)JS對(duì)象作為屬性捧灰,將該元素從文檔樹中刪除后,其綁定關(guān)系并沒有一并刪除统锤,這種情況太多頁面占用內(nèi)存的數(shù)量就會(huì)明顯上升毛俏。
for(i=0;len=values.length;i<len,i++){
ul.innerHTML += "<li>" + values[i] + "<li/>";
}
要避免以上的操作,因?yàn)槊看窝h(huán)要從innerHTML中讀取信息饲窿,要像下面這樣把innerHTML放在循環(huán)體外面
var itemsHTML ="";
for(i=0;len=values.length;i<len,i++){
itemsHTML += "<li>" + values[i] + "<li/>";
}
ul.innerHTML = innerHTML; //只對(duì)innerHTML執(zhí)行了一次賦值操作拧抖;
Firefox 控制臺(tái)設(shè)置
1.地址欄輸入about:config;
2.在過濾器的搜索欄輸入strict按回車;
3.雙擊javascript.options.strict選項(xiàng)所在的行免绿,將其值改為true;
另外控制臺(tái)有多行代碼輸入選項(xiàng),一般情況下是單行擦盾,多行注意在行尾端輸入“嘲驾;”