午夜视频在线网站,日韩视频精品在线,中文字幕精品一区二区三区在线,在线播放精品,1024你懂我懂的旧版人,欧美日韩一级黄色片,一区二区三区在线观看视频

分享

js筆記

 司馬小賊 2018-02-28

前言:js由三部分組成,1. 核心(ECMAScript),語法標(biāo)準(zhǔn)    2.文檔對象模型(DOM)    3.瀏覽器對象模型(BOM)

JavaScript 的核心語言特性在ECMA-262中是以名為ECMAScript的偽語言的形式來定義的。ECMAScript中包含了所有基本的語法,操作符,數(shù)據(jù)類型以及完成基本的計算任務(wù)所必需的對象,但沒有對取得輸入和產(chǎn)生輸出的機(jī)制作出規(guī)定。

1.在web中引入js

<script></script>    使html與js混合

defer  :  延遲到頁面全部解析完后再加載js

type : mime類型, 默認(rèn)"text/javascript"??墒÷?/p>

引入外部js:

<script src=""></script> 可引入不用域的js,引入外部js時同時在標(biāo)簽內(nèi)嵌入js代碼會被忽略。

 注意:不要在js中出現(xiàn) </script> ,會造成瀏覽器錯誤解析(以為js已經(jīng)結(jié)束)。

 小tips:瀏覽器按照<script>標(biāo)簽先后順序解析,如果將js代碼放head里,瀏覽器會先解析js,然后呈現(xiàn)body中的頁面元素(頁面延遲,呈現(xiàn)空白)

2.數(shù)據(jù)類型

ECMAScript 中規(guī)定的5種基本數(shù)據(jù)類型:  Undefined,Null,Boolean,Number,String

      1種復(fù)雜數(shù)據(jù)類型:  Object   由一組無序的鍵值對組成

typeof操作符: 用于返回檢測的變臉類型   :  undefined,object,boolean,number,string,function

typeof(null); //返回"object"  空對象指針(對空對象的引用)

Undefined類型

只有一個值  undefined,變量聲明后未初始化,值就是undefined。(未聲明和聲明后未定義值都是undefined)
var name;
alert(name);//"undefined"
alert(age);//"undefined"

Null類型

同樣只有一個值  null。
var name = null;
alert(typeof  name);//"object" 對空指針的引用
小tips:在定義一個變量用來保存對象時,初始化時最后給null,這樣就只需要檢查null值就可以判斷變量是否保存了對象的引用.

  如:

  1. var person = null;  
  2. if(person!=null){  
  3.   
  4. }  
alert(null == undefined); //true,  undefined值是派生自null值的

Boolean類型

任何其他類型都有與Boolean等價的值
[javascript] view plain copy
print?
  1. Boolean(""); //false,   非空字符串返回true  
  2. Boolean(0);//0和NaN 返回 false ,   非零(包括無窮大)返回true  
  3. Boolean(null);//返回false  
  4. Boolean(undefined);//false  

使用if語句進(jìn)行流程控制時,會自動調(diào)換用Boolean()函數(shù)進(jìn)行轉(zhuǎn)換

Number類型

[javascript] view plain copy
print?
  1. var num1 = 55;  //十進(jìn)制  
  2. var num2 = 070; //八進(jìn)制  0開頭   56  
  3. var num3 = 0x1f; // 十六進(jìn)制  0x開頭   31  
  1. 浮點(diǎn)數(shù)值
由于保存浮點(diǎn)數(shù)值需要的存儲空間是整數(shù)值的兩倍,所以ECMAScript會盡可能將浮點(diǎn)數(shù)轉(zhuǎn)成整數(shù)。
var floatNum1 = 10.0; //保存的是整數(shù)10
注意:0.1+0.2 !=0.3 浮點(diǎn)數(shù)精度問題(永遠(yuǎn)不要測試某個特定的浮點(diǎn)數(shù)值)
2. 數(shù)值范圍
Number.MAX_VALUE,Number.MIN_VALUE,Number.NEGATIVE_INFINITY,Number.POSTIVE_INFINITY
Infinity正無窮, -Infinity負(fù)無窮。
isFinite()函數(shù)來判斷是否在這個范圍內(nèi),超出范圍的數(shù)值會被自動轉(zhuǎn)成相應(yīng)的無窮大值
3. NaN(Not a Number)非數(shù)值
任何數(shù)值除以0返回NaN,不會拋錯(不會影響后面代碼的執(zhí)行)
注意:任何涉及NaN的操作都會返回NaN。NaN與任何值都不相等(包括NaN)
alert(NaN == NaN); //false
isNaN();//判斷是否 "不是數(shù)值"
[javascript] view plain copy
print?
  1. alert(isNaN(NaN));  // true  
  2. alert(isNaN(10));  //false  
  3. alert(isNaN("10"));  //false,可轉(zhuǎn)換成數(shù)值   
  4. alert(isNaN("blue"));  //true,不可轉(zhuǎn)成數(shù)值   
  5. alert(isNaN(true));    //false 可轉(zhuǎn)成數(shù)值   
4. 數(shù)值轉(zhuǎn)換函數(shù) Number() ,parseInt()和parseFloat()
Number(null); // 0
Number(undefined); //NaN
Number("hehe"); //NaN
Number(""); //0

parseInt("0xAF",16); //175
parseInt("AF"); //NaN 需指定進(jìn)制
parseInt("10",2); // 2 (二進(jìn)制)

String 類型

由零或多個 16位 Unicode字符組成的字符序列
注意:字符串一旦創(chuàng)建,值就不能改變。如果改變,是先銷毀原來的字符串,然后用新字符串來填充該變量
字符串轉(zhuǎn)換:
toString();幾乎每個值都有該方法
toString(2); //可指定數(shù)值的轉(zhuǎn)換進(jìn)制
null和undefined沒有 toString()函數(shù)
可以使用String()函數(shù)來轉(zhuǎn)換:String(null); // "null"
String(undefined); //"undefined"

Object類型 (所有對象的基礎(chǔ))

Obejct屬性和方法
Constructor:構(gòu)造函數(shù)(用于創(chuàng)建當(dāng)前對象的函數(shù))
hasOwnProperty(propertyName):檢索當(dāng)前對象實(shí)例中的屬性(不是實(shí)例原型)是否存在,參數(shù)必須是字符串
isPrototypeOf(object):傳入的對象是否是另一個對象的原型
propertyIsEnumerable(propertyName):屬性是否能用for-in 遍歷
toLocalString():返回對象的字符串表示
toString():
valueOf():返回對象的字符串,數(shù)值或布爾值表示。通常與toString()返回相同

3.操作符

1.位操作符

32二進(jìn)制表示整數(shù),第32位為符號位
~ 按位非(NOT)
& 按位與(AND)
| 按位或(OR)
^ 按位異或(XOR)
<< 左移,不影響符號位
>> 有符號右移,保留符號位,不影響正負(fù)
<<< 無符號右移,連著符號位一起右移

2.關(guān)系操作符

4.語句

1.for-in 精準(zhǔn)的迭代語句,可以用來枚舉對象的屬性

[javascript] view plain copy
print?
  1. for(var propName  in window){  
  2.       document.write(propName);  
  3. }  
輸出BOM中 window對象的所有屬性
迭代前最好先檢測對象是否為null或undefined。(ECMAScript5中不執(zhí)行循環(huán)體,以前會報錯)

2.label語句,給代碼添加標(biāo)簽

3.break和continue語句(break跳出循環(huán),直接執(zhí)行循環(huán)后的代碼。continue跳出當(dāng)前循環(huán),接著進(jìn)入下一次循環(huán))

[javascript] view plain copy
print?
  1. var num =0;  
  2. outer:  
  3.       for(var i=0;i<10;i++){  
  4.            for(var j=0;j<10;j++){  
  5.                 if(i == 5 && j==5){  
  6.                       continue   outer;  
  7.                 }  
  8.                 num++;  
  9.            }  
  10.       }  
  11. alert(num);    //95  

4.  with語句(不建議使用,可讀性差)

5. switch語句

[javascript] view plain copy
print?
  1. var num = 15;  
  2. switch (true){  //輸出  Between 10 and 20,如果是false就輸出  Less than 0  
  3.     case num<0:  
  4.     alert("Less than 0");  
  5.     break;  
  6.     case num>=0&&num<=1:  
  7.     alert("Between 0 and 1");  
  8.     break;  
  9.     case num>10&&num<=20:  
  10.     alert("Between 10 and 20");  
  11.     break;  
  12.     default:  
  13.         alert("More than 20");  
  14. }  

6.函數(shù)

function關(guān)鍵字來定義函數(shù),
注意:函數(shù)無所謂傳進(jìn)來多少個參數(shù)。因?yàn)樵趦?nèi)部是用一個數(shù)組來表示的,在函數(shù)體內(nèi)可以通過arguments來訪問這個數(shù)組。
arguments對象只是與數(shù)組類似(并不是array的實(shí)例)
[javascript] view plain copy
print?
  1. function doAdd(num1,num2){  
  2.       arguments[1] = 10;    //會同步影響 num2的值,這種影響是單向的,反過來修改num2并不會影響arguments中的值  
  3.       alert(arguments[0]+num2);  
  4. }  
注意:arguments對象長度由傳入的參數(shù)個數(shù)決定,不由定義函數(shù)時聲明的參數(shù)個數(shù)決定,沒有傳值的參數(shù)自動賦值undefined

5.變量,作用域,內(nèi)存

5.1  基本類型和引用類型

基本類型值指的是簡單的數(shù)據(jù)段,而引用類型值指那些可能由多個值構(gòu)成的對象。
基本類型是按值訪問,所以可以操作保存在變量中的實(shí)際的值。
引用類型的值是保存在內(nèi)存中的對象,js不允許直接 訪問內(nèi)存中的位置(不能直接操作對象的內(nèi)存空間),實(shí)際操作的是對象的引用。
[javascript] view plain copy
print?
  1. var person = new Object();  
  2. person.name = "張三";  //給引用類型變量動態(tài)添加屬性并賦值  
  3. alert(person.name);//  張三  
  4. //無法給基本類型變量添加屬性,不報錯但是無效。  

變量復(fù)制:  基本類型

[javascript] view plain copy
print?
  1. var num1 = 5;  
  2. var num2 = num1;// num1和num2是兩個獨(dú)立的值,在進(jìn)行任何操作時不會相互影響。  
引用類型:

[javascript] view plain copy
print?
  1. var obj1  = new Object();  
  2. var obj2 = obj1;  
  3. obj1.name = "張三";  
  4. alert(obj2.name);  // 張三    
  5. //obj1和obj2指向的是堆內(nèi)存中的同一個對象  

參數(shù)傳遞:

ECMAScript中所有函數(shù)的參數(shù)都是按值傳遞的。在傳遞基本類型值是,被傳遞的值會賦給一個局部變量(命名參數(shù),arguments對象中的一個元素)

注意:傳遞引用類型時,會把這個值在內(nèi)存中的地址賦值給一個局部變量(對堆內(nèi)存中對象的引用),所以指向的還是同一個內(nèi)存空間,因此對參數(shù)的修改會影響到函數(shù)外。

[javascript] view plain copy
print?
  1. function setName(obj){  
  2.      obj.name = "張三";//obj引用指向堆中的person對象,person.name = "張三"  
  3.      obj = new Object();//給obj(參數(shù),局部變量)  指向新的對象(該對象在setName函數(shù)中創(chuàng)建,是局部的,函數(shù)結(jié)束,對象銷毀)  
  4.      obj.name = "李四";//給obj引用的局部變量動態(tài)添加name屬性賦值為"李四"  
  5. }  
  6. var person = new Object();  
  7. setName(person);  
  8. alert(person.name); //張三  
類型檢測:

通常用typeof來檢測基本類型

instanceof來檢測引用類型,根據(jù)它的原型鏈來識別。

所有引用類型都是Object的實(shí)例,用instanceof檢測所有基本數(shù)據(jù)類型,都會返回false。基本類型 不是對象。

5.2 執(zhí)行環(huán)境及作用域

說明:執(zhí)行環(huán)境定義了變量或函數(shù)有權(quán)訪問的其他數(shù)據(jù),決定了他們各自的行為。每個執(zhí)行環(huán)境都有一個與之關(guān)聯(lián)的變量對象(variable object),環(huán)境中定義的所有變量和函數(shù)都保存在這個對象中。雖然我們編寫的代碼無法訪問這個對象,但解析器在處理數(shù)據(jù)是會在后臺使用它。

全局執(zhí)行環(huán)境是最外圍的一個執(zhí)行環(huán)境。在web瀏覽器中,全局執(zhí)行環(huán)境就是window對象,因此所有全局變量和函數(shù)都是作為window對象的屬性和方法

創(chuàng)建的。某個執(zhí)行環(huán)境中的所有代碼執(zhí)行完后,保存在其中的變量和函數(shù)定義也隨之銷毀。

每個函數(shù)都有自己的執(zhí)行環(huán)境。當(dāng)執(zhí)行流進(jìn)入一個函數(shù)時,函數(shù)環(huán)境會被推入環(huán)境棧。執(zhí)行完后彈出棧,控制權(quán)交給之前的執(zhí)行環(huán)境

作用域鏈(scope chain)。保證對執(zhí)行環(huán)境有權(quán)訪問的所有變量和函數(shù)的有序訪問
 
[javascript] view plain copy
print?
  1. var color = "blue";  
  2. function changeColor(){  
  3.       var anotherColor = "red";  
  4.       function swapColors(){  
  5.                var  temColor = color;  
  6.                color = anotherColor;  
  7.                anotherColor = temColor;  
  8.       }  
  9. }  
上面代碼作用域鏈,如圖:三個作用域,內(nèi)部環(huán)境可以通過作用域鏈訪問所有的外部環(huán)境
延長作用域鏈:

1.try-catch 中的catch塊

2.with語句

[javascript] view plain copy
print?
  1. function buildUrl(){  
  2.     var qs = "?debug=true";  
  3.     with(location){  
  4.         var url = href + qs;  //location.href,url添加到最近的環(huán)境(buildUrl函數(shù)中)  
  5.     }  
  6.     return url;   
  7. }  
with語句接收的是location對象,因此其變量對象中就包含了location對象的所有屬性和方法,而這個變量對象被添加到了作用域鏈的前端,所以在函數(shù)內(nèi)部可以訪問。

沒有塊級作用域:
js沒有塊級作用域,不像java等語言,if(){},for(){}語句中定義的都是局部變量
[javascript] view plain copy
print?
  1. for(var i=0;i<10;i++){  
  2.      doSomething(i);  
  3. }  
  4. alert(i);   // 10     
js中會將if,for中聲明的變量添加到當(dāng)前的執(zhí)行環(huán)境中
變量聲明:
使用var聲明的變量會自動被添加到最接近的環(huán)境中。在函數(shù)內(nèi)部,最接近的就是當(dāng)前函數(shù)的局部環(huán)境;在with語句中,最接近的環(huán)境是函數(shù)環(huán)境。如果初始化變量時沒有var聲明,則自動添加到全局環(huán)境。
[javascript] view plain copy
print?
  1. function(num1,num2){  
  2.         sum = num1+num2; //sum未聲明,添加到全局環(huán)境  
  3.         return sum;  
  4. }  
  5. var result = add(10,20); //30  
  6. alert(sum);    //30,可訪問到  
查詢標(biāo)識符:同名變量,從最近環(huán)境開始搜索,優(yōu)先取最近環(huán)境中的值然后停止搜索。

5.3 垃圾收集

說明:JavaScript具有自動垃圾收集機(jī)制,執(zhí)行環(huán)境會負(fù)責(zé)管理代碼執(zhí)行過程中使用的內(nèi)存

局部變量只在函數(shù)執(zhí)行的過程中存在。在這個過程中,會為局部變量在棧(或堆)內(nèi)存上分配相應(yīng)的空間,以便存儲它們的值。在函數(shù)執(zhí)行結(jié)束,局部變量就沒有存在的必要,因此可以釋放它們的內(nèi)存。

標(biāo)記清除
JavaScript中最常用的垃圾收集方式是標(biāo)記清除(mark-and-sweep)。當(dāng)變量進(jìn)入環(huán)境時(如:在函數(shù)中聲明一個變量),就將這個變量標(biāo)記為"進(jìn)入環(huán)境",當(dāng)變量離開環(huán)境時,則將其標(biāo)記為"離開環(huán)境"。

垃圾收集器在運(yùn)行的時候會給存儲在內(nèi)存中的所有變量加上標(biāo)記,然后會去除環(huán)境中的變量以及被環(huán)境中的變量引用的變量的標(biāo)記。

在此之后再被加上標(biāo)記的變量將被視為準(zhǔn)備刪除的變量(環(huán)境中變量已經(jīng)無法訪問這些變量了)。最后,垃圾收集器完成內(nèi)存清除工作,銷毀帶標(biāo)記的值并回收內(nèi)存空間。

引用計數(shù)

說明:引用技術(shù)會跟蹤每個值被引用的次數(shù)。當(dāng)聲明了一個變量并將一個引用類型值賦給該變量,則這個值的引用次數(shù)就是1。如果該值又被賦給另外一個變量,則該值的引用次數(shù)加1。相反,如果對這個值引用的變量取得了另外一個值,則這個值的引用次數(shù)減一。當(dāng)這個值的引用次數(shù)變成0的時候,就說明沒法再訪問這個值了,就可以將其占用的內(nèi)存回收。當(dāng)垃圾收集器下次再運(yùn)行的時候就會釋放這些空間。
問題:對象之間循環(huán)引用會造成內(nèi)存無法回收
[javascript] view plain copy
print?
  1. function problem(){  
  2.     var objectA = new Object();  
  3.     var objectB = new Object();  
  4.     objectA.someOtherObject = objectB;  
  5.     objectB.anotherObject = objectA;  
  6. }  
A,B對象通過各自的屬性相互引用。它們之間的引用次數(shù)永遠(yuǎn)不會是0。如果這個函數(shù)被重復(fù)多次調(diào)用,就會導(dǎo)致大量內(nèi)存無法回收。
問題:IE中有一部分并不是原生JS對象,BOM和DOM中的對象就是使用C++以COM(Component  Object  Model,組件對象模型)對象的形式實(shí)現(xiàn)的,而COM對象的垃圾收集機(jī)制采用的就是引用計數(shù)策略。所以,即使IE的JS引擎是使用標(biāo)記清除策略,但JS訪問的COM對象依然是基于引用計數(shù)策略的。這就照成只要在IE中涉及COM對象就會存在內(nèi)存引用的問題。
[javascript] view plain copy
print?
  1. var element = document.getElementById("some_element");  
  2. var myObject = new Object();  
  3. myObject.element = element;  
  4. element.somObject = myObject;//DOM元素和JS對象相互引用,循環(huán)引用照成即使DOM從頁面中移除,它也不會被回收。  

可以通過賦值為null來手動斷開這兩個元素間的引用。如:
myObject.element =null;
element.somObject = null;
IE9中把BOM和DOM對象都轉(zhuǎn)成了JS對象,也可以避免兩種垃圾回收算法并存的問題(消除常見的內(nèi)存泄漏現(xiàn)象)。

性能問題

說明:垃圾收集器是周期性運(yùn)行的,原IE7策略問題:根據(jù)內(nèi)存分配量運(yùn)行,達(dá)到256個變量,4096個對象(或數(shù)組)或者64KB其中任一標(biāo)準(zhǔn),垃圾收集器就會運(yùn)行,這就導(dǎo)致如果一個腳本中包含這么多變量,那么這個腳本在器生命周期中很可能會一直保有這么多變量。這樣一來,垃圾收集器就會頻繁運(yùn)行,導(dǎo)致性能急劇下降。

解決方法:如果回收的內(nèi)存分配量低于15%,則臨界值加倍。如果到了回收85%的內(nèi)存分配量,就將臨界值重置回默認(rèn)值。這樣循環(huán)往復(fù),看似簡單,實(shí)則極大提升了IE在運(yùn)行包含大量JS的頁面時的性能。

5.4 內(nèi)存管理

說明:出于安全考慮,瀏覽器的可用內(nèi)存數(shù)量比較少(防止運(yùn)行JS的網(wǎng)頁耗盡全部系統(tǒng)內(nèi)存而導(dǎo)致系統(tǒng)崩潰)。內(nèi)存限制不僅影響給變量分配內(nèi)存,同時還會影響調(diào)用棧以及在一個線程中能夠同時執(zhí)行的語句數(shù)量。

tips:一旦數(shù)據(jù)不再有用,最好通過將其值設(shè)置為null來釋放其引用(解除引用dereferencing)。該做法適用大多數(shù)全局變量和全局對象屬性。局部變量會在它們離開執(zhí)行環(huán)境時自動被解除引用

[javascript] view plain copy
print?
  1. function createPerson(name){  
  2.     var localPerson  = new Object(); //localPerson局部變量,不用手工解除  
  3.     localPerson.name = name;  
  4.     return localPerson;  
  5. }  
  6. var globalPerson = createPerson();  
  7. //手動解除globalPerson的引用  
  8. globalPerson = null;  

解除globalPerson的引用,讓值脫離執(zhí)行環(huán)境,以便垃圾收集器下次運(yùn)行時將其回收

小結(jié):

  • 基本類型值在內(nèi)存中占據(jù)固定大小的空間,被保存在棧內(nèi)存中
  • 從一個變量向另一個變量復(fù)制基本類型的值,會創(chuàng)建這個值的一個副本
  • 引用類型的值是對象,保存在堆內(nèi)存中
  • 包含引用類型值的變量實(shí)際上包含的并不是對象本身,而是一個指向該對象的指針
  • 從一個變量向另一個變量復(fù)制引用類型的值,復(fù)制的其實(shí)是指針,因此兩個變量最終都指向同一個對象
  • 確定一個值是哪種基本類型使用typeof(),確定值是哪種引用類型使用instanceof()

所有變量都存在于一個執(zhí)行環(huán)境(作用域)中,這個執(zhí)行環(huán)境決定了變量的生命周期,以及哪一部分代碼可以訪問其中的變量。

  • 執(zhí)行環(huán)境有全局執(zhí)行環(huán)境和函數(shù)執(zhí)行環(huán)境之分;
  • 每次進(jìn)入一個新執(zhí)行環(huán)境,都會創(chuàng)建一個用于搜索變量和函數(shù)的作用域鏈;
  • 函數(shù)的局部環(huán)境不僅有權(quán)訪問函數(shù)作用域中的變量,而且有權(quán)訪問其父環(huán)境,乃至全句環(huán)境中的變量;
  • 全局環(huán)境只能訪問在全局環(huán)境中定義的變量和函數(shù),而不能直接訪問局部環(huán)境中的任何數(shù)據(jù);
  • 變量的執(zhí)行環(huán)境有助于確定應(yīng)該何時釋放內(nèi)存
JavaScript是自動進(jìn)行垃圾回收的,開發(fā)人員不必關(guān)心內(nèi)存分配和回收問題。
  • 離開作用域的值將被自動標(biāo)記為可以回收,因此將在垃圾收集期間被刪除。
  • "標(biāo)記清除"是目前主流的垃圾收集算法,思想就是給當(dāng)前不使用的值加上標(biāo)記,然后再回收其內(nèi)存
  • "引用計數(shù)"的思想是跟蹤記錄所有值被引用的次數(shù),JS引擎目前都不使用這種算法
  • 在代碼中循環(huán)引用時,"引用計數(shù)"算法會出現(xiàn)問題(內(nèi)存泄漏)
  • 解除變量引用不僅有助于消除循環(huán)引用現(xiàn)象,而且對垃圾收集也有好處。為了確保有效地回收內(nèi)存,應(yīng)該及時解除不再使用的全局對象,全局對象屬性及循環(huán)引用變量的引用。

    本站是提供個人知識管理的網(wǎng)絡(luò)存儲空間,所有內(nèi)容均由用戶發(fā)布,不代表本站觀點(diǎn)。請注意甄別內(nèi)容中的聯(lián)系方式、誘導(dǎo)購買等信息,謹(jǐn)防詐騙。如發(fā)現(xiàn)有害或侵權(quán)內(nèi)容,請點(diǎn)擊一鍵舉報。
    轉(zhuǎn)藏 分享 獻(xiàn)花(0

    0條評論

    發(fā)表

    請遵守用戶 評論公約

    類似文章 更多