前言
在看書的程序中,發現有一些內容屬于那種邊邊角角容易忘記卻又非常重要,
所以,在這里留下一篇筆記,以便查閱,
第1章 js簡介
js組成部分:ECMAScript、DOM、BOM
瀏覽器就是js的解釋器,
DOM是檔案物件模型,通過它來操作網頁物件上的元素,這些元素就是HTML上的各種標簽,
BOM是瀏覽器物件模型,可以操作瀏覽器,其中XMLHttpRequest這個物件很重要,ajax異步處理技術就會用到它,
第2章 在HTML中使用js
js腳本默認是從上到下依次執行的,如果寫在head里,就會堵塞,
script元素用來將js腳本插入HTML檔案,
script中的async屬性的作用是異步加載,不用等待,不用排隊,要注意的是它不保證哪一個腳本先執行完畢,所以在加載期間不要改DOM,
script中的defer屬性的作用是延遲加載,相當于放在body元素的底部位置,等頁面全部呈現了才會執行,它也不保證誰先執行完畢,
綜上,最后把腳本放在body元素內的底部,即主體內容后面,</body>的前面,
noscript元素內的文本會在瀏覽器不支持js的情況下顯示出來,
第3章 基本概念
識別符號就是變數、函式、屬性、函式引數的名字,
區分大小寫,
字母數字下劃線和美元符號,
其中,數字不可以作為開頭,
最好用小駝峰,像這樣:myName,hisAge,
保留字、關鍵字、布林值(true、false)、null不可以做識別符號,
嚴格模式:"use strict" 對那些不確定的行為和不安全的方式加以限制,如果發生會報錯,讓代碼更強壯,
陳述句最好加分號,
關鍵字就是像宣告時用的var、let、function……
保留字就是暫時還沒有規定用途的準關鍵字,
未初始化的變數(就是沒有給值的變數)保存了undefined,
在函式中不加var來宣告的變數,就會保存到window上,變成全域變數,
全域變數哪都能用,
typeof運算子可以判斷:undefined boolean number string function object
其中null經過typeof也回傳給你object,因為它被當成一個空的參考,
陣列、函式、物件都是物件,它在記憶體上保存的僅僅是一個參考地址,通過這個參考才可以找到真正的值,
undefined == null => true
undefined === null => false
NaN === NaN => false
+0 === -0 => true
Object.is()用來判斷兩者是否相等,
Object.is(NaN, NaN); => true
Object.is(+0, -0); => false
parseInt(開頭不是數字的字串); => NaN
parseFloat(開頭不是數字的字串); => NaN
null和undefined沒有toString()方法,
var o = new Object();
var o = new Object; // 可以省略 但最好不要省略
Object相當于Object類,而o就是Object這個建構式原型派生出來的一個物件,
Object的實體的屬性方法:
o.constructor:建構式,保存著當前實體的函式,比如上面的Object,
o.hasOwnProperty(propertyName):檢查當前實體上是否存在給定的屬性,(跟原型無關)
Object.prototype.isPrototypeOf(o):用于測驗一個物件是否存在于另一個物件的原型鏈上,
toString():回傳字串表示,
valueOf():回傳當前物件的字串、陣列或布林值表示,
var a=0
++a; // 0
a // 1
var b=0
b++; // 1
b // 1
與&&
或||
非! !true === false
邏輯短路:
true && 1 => 1
true || 1 => true
false && 2 => false
false || 2 => 2
2**3 => 8
23 < 3 => false
"23" < 3 => false 先把"23"轉換成數字23,然后比較
"a" < 3 => false "a"轉換成數字變成NaN,NaN不等于任何數字
"23" < "3" => true 都是字串就比較字符編碼的大小
如果是物件的比較,先執行valueOf(),如果沒有valueOf()方法,那么就呼叫toString()方法,然后用基本型別值繼續比較,
三元運算子:var value = https://www.cnblogs.com/buildnewhomeland/p/5 > 10?'5勝出!' : '10勝出';
回圈陳述句可以重復做一件事情,這樣就不用每一次代碼都寫出來了,
有固定次數時,使用for回圈,否則用while回圈,
回圈中有兩種特殊用途的陳述句:break陳述句和continue陳述句,
break陳述句跳出當前回圈體,不回圈了,
continue陳述句跳過當前一輪的回圈,進行下一輪回圈,
函式是一組邏輯的封裝,一般一個函式就代表一個功能,通過執行函式來實作對應的功能,
函式放在物件里,就稱為物件的方法,執行物件里的函式,我們稱之為呼叫物件的方法,
函式無需指定回傳值,因為它沒有指定回傳值型別這一說,但最好有回傳值,格式是return 回傳值,
如果沒有指定回傳值,那么會默認回傳一個undefined作為回傳值,
return陳述句后面的陳述句永遠不會執行,
函式的實參可以隨便傳幾個,它們會被保存在arguments物件里,arguments是一個類陣列,(一個有length屬性,類似陣列,保存著實參的串列,)
如果沒有傳遞引數,和var未初始化一樣,會被賦值為undefined,
Java中可以定義函式簽名(接受引數的型別和數量),只要簽名不同,就可以同時存在同名的函式,
但是JS中不可以!它的函式引數是一個類陣列,因此JS沒有函式多載,重名會被后者覆寫!
第4章 變數作用域和記憶體問題
變數的值分兩種,一種是基本資料型別值,一種是參考型別值,
基本資料型別值是按值訪問的,它可以直接操作保存在變數中的實際的值,他們被放在堆疊記憶體中,
參考型別值是按參考訪問的,只能操作它的參考地址,不能操作物件的記憶體空間,他們被放在堆記憶體中,

參考型別會有各種屬性和方法,
當我們復制基本型別值時,原來的值和復制得到的值是相互獨立、互不干擾的,是兩碼事,
當我們復制參考型別值時,復制的值只是一個指標一個地址而已,這兩個指標指向同一個物件,當操作任何一個變數時,都會互相發生作用,
js中的所有函式引數都是按值傳遞的,這意味著函式執行后并不會改變作為引數傳遞進去的那個外部的變數值,
通過instanceof運算子檢測物件的型別,看它是哪個建構式的實體物件,(instance就是例子的意思,)
如果用基本型別就會回傳false,因為基本型別不是物件,基本型別使用typeof來檢測,
執行環境又叫執行背景關系, 環境中的變數和函式可以訪問其他資料,而每個環境中都有一個對應的變數物件(VO),這個變數物件里保存著環境中所有的變數和函式,
按規則在瀏覽器中,window物件被認為是全域的執行環境,所以所有的全域變數和函式都是掛載在window物件上的,這個window物件就是全域環境中的變數物件,
這就是當你var value = https://www.cnblogs.com/buildnewhomeland/p/123;時,你就能訪問到window.value是123的原因,
每個函式都有自己的執行環境,當執行函式時,函式會產生一個環境,這個環境被推入到一個環境堆疊中(此時它掌握控制權),而函式一旦執行完成,函式環境就會從環境堆疊中彈出,
注意,當環境出現時,就會隨之產生一個變數物件,通過變數物件的作用域鏈,我們可以訪問所有的變數和函式,
活動物件:如果這個執行環境是函式產生的,它的變數物件就是活動物件(AO),這里面一開始只有一個arguments物件(全域環境中并沒有它),沿著作用域鏈可以找到上一層的變數物件,最外層就是全域的變數物件(GO),(全域的變數物件始終是作用域鏈的最后一個物件,)
原生JS中只有全域作用域和函式作用域,(函式作用域也叫區域作用域)
簡而言之就是,每一個環境下(不管是全域環境還是函式的區域環境),都會對應有一個變數物件,變數物件包含著當前作用域中所有的變數和函式,
比如,全域環境下的變數物件就有全域中所有的變數和函式,
特殊一點的是,在執行函式時會產生函式環境,它的變數物件叫做活動物件,與全域環境不同的是,arguments物件是函式變數物件的專屬,
在函式環境中,可以訪問到父級作用域內變數的原因就是作用域鏈,沿著它就能訪問上一層作用域的變數了,這就是為什么函式內部可以訪問全域變數的原因,
另外,外部環境是沒有辦法反過來訪問到內部環境中的變數的,函式一旦執行完畢,函式環境內的變數就會被銷毀,
但是如果在執行函式時,函式內部的變數被回傳出來,因為它是連著活動物件的作用域鏈,所以這時外部就能訪問內部的值,這就是閉包,
(上面的變數包括基本型別和參考型別,執行環境也叫作作用域,)
原生JS只有全域作用域和區域作用域(函式),但是沒有塊級作用域,這就意味著類似于for回圈這種代碼塊里的變數可以被全域使用,這樣代碼塊里的變數就很容易被污染,
標記清除,給當前不適用的值加上標記,然后再回收記憶體,(主流)
參考計數,當宣告一個變數并參考值給它時,就會產生1個參考計數,變數每次被參考時次數+1,使用完成后次數-1,當計數為0時意味著它的記憶體被回收,(幾乎不用)
JS的記憶體分配和回識訓自動執行,它有自動垃圾收集機制,
第5章 參考型別
物件是參考型別的值,它是某個特定參考型別的實體,
物件是描述了一類事物的屬性和方法,
新物件通過new+建構式來創建,
var person = new Perosn(); // person就是Person這個建構式的實體/物件,
物件還可以用物件字面量表示法來創建,var perosn = {};
訪問物件的方法:第一種是點表示法,第二種是方括號表示法,
點表示法:obj.propertyName
方括號表示法:obj[propertyName] //注意:方括號里不僅可以放字串,放一個值為字串的變數也是可以的!
陣列也是物件的一種,new Array()得到陣列實體,
new Array(20)表示一個length長度為20的陣列,
陣列字面量表示法:var arr = [1,2,3,4];
陣列的下標從0開始,比如你要訪問第一個陣列項arr[0],如果是第二個呢?那就是arr[1],
陣列的最后一項下標是length-1
檢測陣列的方式一:arr instanceof Array
檢測陣列的方式二:Array.isArray(arr)
因為陣列也是物件,因此它繼承了Object原型物件中的方法toString()、valueOf()等方法,
toString()方法可以把陣列內的陣列項按照字串形式回傳,默認是用逗號分隔的,
陣列的join()方法可以指定分隔符將陣列項以字串形式回傳,
陣列屬性和方法
函式也是物件,每個函式都是Function型別的實體,
函式的宣告方式有兩種,一種是函式宣告,一種是函式運算式,
函式宣告:function f() {};
函式運算式:var f = function(){}
還有一種方式不推薦:var sum = new Function('n1', 'n2', 'return n1+n2'); // 函式是物件,函式名是指標,
JS有個規則是宣告提升,意思是說js在決議程序中會進行預先的編譯(預編譯)找到那些宣告,并把它們提升到頂部,
函式宣告的優先級大于函式運算式,函式宣告在執行代碼之前就可以訪問,但是函式運算式不行,它必須要等到執行到那一行才可以,否則在這之前都是undefined,
函式內部有兩個特殊的物件:this和arguments,
this參考的是函式執行的環境物件,一般來說這個this物件是window,但是如果被其他物件呼叫,那么this就指向那個呼叫它的物件,
注意,函式名實際上是一個含有指標的變數,它是指向一個函式的,雖然呼叫它的可能是不同的人讓this物件發生了變化,但是這個函式名背后的函式一直是同一個函式,
函式的屬性:length和prototype
length是指它的形參長度,
prototype是指它的原型物件,所有物件都有toString()方法,這個toString()方法實際上就保存在prototype里,
函式的方法:apply()和call()
它們的作用都是在特定作用域中呼叫函式,這樣就可以設定函式體內this物件的值,
這就意味著物件不用在內部定義一堆方法,可以通過call方法呼叫其他作用域中的函式,
apply和call的第一個引數都是目標物件,第二個引數略有不同,
apply的第二個引數可以傳入一個arguments物件,也可以傳入一個陣列,
call只能一個一個傳值,
bind()方法可以將this系結到它給定的物件上,它會回傳這個函式的的實體,
基本包裝類有Boolean、Number、String,它們是比較特殊的參考型別,
new Boolean()、new Numeber()、new String()
當給他們這些參考型別去賦值或者呼叫方法時,都會經歷一個程序:創建一個相關實體,實體呼叫指定方法,銷毀這個實體,
參考型別和包裝型別的主要區別在于物件的生存周期,
new出來實體會一直保存在記憶體中,直到當前作用域消失,
包裝型別的物件只會存在于一行代碼執行的瞬間,然后立即銷毀,(這就是為什么給包裝類指定了屬性再訪問它卻只是輸出undefined的原因,當你去訪問時那個實體早就消失了,)
當我們用typeof去檢測包裝類的型別時,回傳object,
轉型函式:var str = '25'; var num = Number(str); // num=25
保留2位有效數字字串:num.toFixed(2);
字串屬性和方法
兩個內置物件:Global物件和Math物件,
Global物件通過window物件來訪問,全域變數和函式都是Global物件的屬性,
第6章 面向物件程式設計
ESMAScript中沒有類的概念,
物件是一組無序屬性的集合,屬性可以包含基本值或參考值,
物件每一個屬性或方法都有一個名字,每個名字對應一個值,
只有物件內部才可以訪問的屬性,用[[]]封閉起來,這些屬性有資料屬性和訪問器屬性,
資料屬性有[[configurable]]、[[enumerable]]、[[writable]]、[[value]],
[[configurable]]:能否洗掉和修改屬性,
[[enumerable]]:能否通過for in回圈回傳屬性,也就是是否是可列舉的,
[[writable]]:能否修改屬性值,
[[value]]:資料值,讀的時候從這里讀,寫的時候新值保存在該位置,
Object.defineProperty(目標物件,屬性名稱,描述物件) // 修改物件的內部特性Property
var person = {};
Object.defineProperty(person, 'name', {
writable: true,
value: 'mike'
});
一旦描述物件中的configurable被設定為false,表示不可配置,于是就不能把它變回可配置了,
如果通過這個方法來創建一個新屬性時沒有給描述屬性配置相關的屬性,那么configurable、enumerable、writable的值為false,
如果是修改已經存在的屬性,那么就沒有這種限制,
訪問器屬性沒有[[value]],而有[[get]]、[[set]],
[[get]]:在讀取屬性時呼叫的函式getter,默認值為undefined
[[set]]:在設定屬性時呼叫的函式setter,默認值為undefined
定義多個屬性:Object.defineProperties(目標物件,{目標屬性1:{描述屬性}, 目標屬性2:{描述屬性}, ...})
讀取屬性的特性:Object.getOwnPropertyDescriptor(目標物件,屬性名稱)
創建物件:工廠模式(問題:有物件識別問題)、建構式模式(問題:實體方法每次都會重建一遍)、原型模式(問題:共享一個原型物件,一個變化所有實體都變)、組合模式(建構式+原型,認可度最高),
new實體經歷的程序:1.創建一個新物件;2.將建構式的作用域給新物件(this指向這個新物件);3.指向建構式中的代碼(新物件添加屬性);4.回傳新物件,
js繼承的基本思想是利用原型讓一個參考型別繼承另一個參考型別的屬性和方法,
函式有原型物件,物件有原型指標,
每一個實體物件的原型指標都指向了它的建構式的原型物件,
繼承方式:原型式繼承、寄生式繼承、寄生組合式繼承,
未完待續,,,
轉載請註明出處,本文鏈接:https://www.uj5u.com/qiye/93694.html
標籤:JavaScript
上一篇:What are the Advantages and Disadvantages of Angular?
下一篇:物件淺拷貝和深拷貝有什么區別
