JavaScript權威指南(第6版) PDF中文版+英文版+源代碼 下載地址:http://www.linuxidc.com/Linux/2013-10/91056.htm
最近每天工作之余看下js的細節部分,時間不是很多,所以看的進度也不會太快,寫個博客監督自己每天都看下。
以前不知道的細節或者以前知道但是沒注意過的地方都會記錄下來,所以適合有一定基礎的,不適合零基礎新手。
---------------------------------------------------------國慶期間 開始---------------------------------------------------------
js中所有數字都是浮點數,比如5/2不是2,是2.5,0/0為NaN,如果想實現5/2=2可以采用5>>2=2
"1.23" == 1.23 會將字符串轉換為數字
33 + '33' = '3333' 字符串和數字相加,會將數字轉換成字符串
object == number|string PS: new Number(123) == 123 或者 new String('123') == '123' 為true ,其他為false
見未知
字符串連接中,使用join比使用+=要快幾十倍,比如: ["abc","def"].join("")
--------------------------------------16.10.10添加 開始----------------------------------
包裝對象
var s = "hello"
alert(s.length) => 5
在JS定義中字符串s為原始值,那為什麼會有length屬性?
因為在JS中,只要引用了字符串s的屬性,js就會調用new String(s)來轉換成對象,這個對象繼承了字符串的方法,並被用來處理屬性的引用。一旦屬性引用結束,這個對象就會銷毀。
比如:
var s = "123"
s.len = 4;
alert(s.len); => undefined
這是因為第二行創建完臨時對象以後,馬上就被銷毀了。所以第三行自然引用不到。
再看:
var s = "123"
s.length = 4;
alert(s.length); => 3
同樣的,因為第二行創建的對象並進行賦值以後,馬上就被銷毀了,第三行創建的是一個新的對象,所以自然就是3了
同樣的數字和布爾值也有Number()和Boolean()方法,但是null和undefined就沒有。
見46頁3.6
--------------------------------------16.10.10添加 結束----------------------------------
js 字符串,數值和布爾值都是不可變的
如:var s=“hello”
s.toUpperCase();
console.log(s)
輸出s為hello而不是HELLO
因為函數返回的是一個新字符串,而本身是不會改變的。
見47頁3.7
js類型轉換表
見49頁上
js中對象永遠不相等,即使對象中的所有索引以及屬性值都一樣也不相等,同樣兩個單獨的數組也是永遠不相等
原因:對象為引用類型,對象的比較為引用的比較,當為同一個引用對象時才相同
也就是說
var a ={};
var b=a;
此時a===b為true。
見47頁底部
--------------------------------------16.10.10添加 開始----------------------------------
js中對象的toString/valueOf方法
對象轉換到字符串是先toString後valueOf,轉換到數字反之
ps:沒看出toString/valueOf方法有什麼區別,有待深入了解(除了書本上寫了Date的對象,toString返回一段時間字符串,valueOf方法返回時間戳)
var a = {x:1} => [object Object]
var a = ['1',2,'你好'] => "1,2,你好" 在元素之間添加逗號後合並成字符串返回
var a = function() { return 0 } => function() { return 0 } 返回賦值的定義
function a() {return 0} => function a() {return 0} 返回定義的字符串
/\d+/g => /\d+/g
見52頁
--------------------------------------16.10.10添加 結束----------------------------------
變量作用域不受{}代碼塊限制,只受函數聲明限制,函數體內聲明的變量都被“提前”至函數體頂部,也就是說在函數體內任何地方定義的變量都可以在函數體內任意地方使用,只是有可能未賦值(如果使用在聲明之前)
見57頁3.10.1
附加:
-
所有全局變量都是window或Global的屬性
-
函數聲明會被提到范圍作用域的頂端
-
變量聲明被提到范圍作用域的頂端
-
變量聲明比函數聲明優先級高,變量聲明優於函數聲明,如果兩者同時存在,後被提升的函數聲明會覆蓋被提升的變量聲明
-
變量賦值不會被提升,到執行行代碼才開始賦值
1.聲明的全局變量和2.未聲明直接賦值產生的全局變量的不同之處。
1.不能用delete刪除
2.可以用delete刪除
見58頁3.10.2
因為用戶用var聲明的變量不能用delete刪除
見89頁中上
.訪問和[]訪問的區別
.訪問會直接查找.後的屬性值
[]訪問會計算括號內的表達式並轉為字符串後進行訪問
這個特點導致如果屬性名稱是一個保留字(ES3)或者包含空格和標點符號,或是一個數字(對數組來說),則必須使用方括號
見63頁底部
運算符相關
見66頁
js比較運算符,如果比較的兩個操作數,有一個為NaN,那麼總是返回false,NaN和任何值都不相等,包括它自己,所以判斷x是否為NaN可以用x!==x來判斷
見77頁上方
eval()作用
1.定義別名後eval就是全局的,此時可以在函數內使用全局變量的值(即使函數內有同名變量)
見85頁代碼段
2.未知
function定義
1.var funcname = function(){;}函數定義表達式
2.function funcname(){;}函數聲明語句
區別:1.同var聲明變量一樣,只有變量聲明被提前到了作用域頂部,但是沒有值
2.整體都被提前
見95頁底部
52-54需要細看
else if並不是真正的js語句,只不過是多條if/else 語句連在一起時的一種慣用寫法
見98頁
使用switch的場景
所有分支都依賴同一個表達式的值時,重復計算多條if語句中的表達式非常浪費
見99頁上
switch中case後面的表達式與switch後的表達式的值是用“===”進行判斷
見99頁中
default可以放在switch內任何地方
見101頁上
5.5.4
for/in
for(var i in o)
每次會將循環到的o的值賦值給i
所以可以這樣
var a = { x:1,y:2}
var an =[];
var i=0;
for(an[i++] in a);
來獲取a中的所有屬性
見104頁
標簽語句
類似c語言goto,不常用,使用方法不熟悉
見106頁
continue語句在不同循環體中不同的表現行為
while 判斷開始的循環表達式
do/while 判斷結尾的循環表達式
for 先計算自增表達式,再判斷循環表達式
for/in 遍歷下一個屬性名
見108頁5.6.3
throw的向上傳遞
見110頁5.6.5下
finally執行問題
只要try語句中有一部分代碼執行了,finally就會執行。就算try中使用了return,continue,break也是如此
利用try/finally使while循環模擬for循環(無法完美實現)
見112頁下
with語句
將對象添加到作用域鏈的頭部,不建議使用
見113頁5.7.1
debugger
設置程序斷點,用於程序調試(作為ACMer)
見114頁5.7.2
“use strict”
使用嚴格模式
嚴格模式區別(前三條非常重要):
1.禁止使用with語句
2.所有變量都要先聲明
3.調用的函數(不是方法)中的this為undefined
4.通過call和apply來調用函數時,this就是傳入的第一個參數
其余見115頁中
------------------------------------------------國慶期間 結束---------------------------------------------------------------------------
------------------------------------------------16.10.11 開始---------------------------------------------------------------------------
對象的屬性名如果為保留字(ES3)/有空格/有-連字符的話必須用引號引起來
最後一個屬性後的逗號將忽略,ES3中大部分實現中也可以,但是在IE中報錯。
見120頁中下
創建對象的三種方法:
1、var o1 = {};
2、var o2 = new object();
3、var o3 = Object.create(Objecet.prototype);
這三種方法創建出來的對象都是一樣的,都是繼承自Objecet.prototype。
是不一樣的。
其中2和3方法都可以指定原型對象.
var p = {x:1}
var o2 = new object(p);
var o3 = Object.create(p);
見121頁6.2.1
------------------------------------------------16.10.11 結束---------------------------------------------------------------------------
------------------------------------------------16.10.13 開始---------------------------------------------------------------------------
對象的屬性的賦值操作會首先檢查原型鏈,如果原型鏈中有,並且是只讀的,那麼賦值操作就是不允許的。否則,就在原始對象(不是原型鏈上的)添加新的屬性或者對已有的屬性賦值。
在查詢屬性時才會體會到繼承的存在,而設置屬性則和繼承無關。
見125頁下
給對象o設置屬性p失敗的場景:
1、o中的屬性p是只讀的。
2、o中的屬性p是繼承屬性,而且是只讀的。
3、看不懂,參見6.8.3
見127頁中
126頁6.2.3的上面有一段看不懂,參見6.6,以後回來再看。
如果o繼承了x屬性,而x屬性恰好是一個存取器屬性(參見6.6)那麼如果設置o.x=2是不會創建屬性的,也不會修改父類的值,只會修改本類的值。
var a ={
x:1,
get r(){return this.x},
set r(value){this.x = value}
}
var b = Object.create(a);
b.r = 2; //這個操作修改了b中x的值
b.x //2
a.x //因為b中的操作只會修改b的值,所以a.x值不會變。
檢測屬性是否在對象中。
in/ !==:()
屬性名 in 對象
var o = {x:1}
"x" in o //true
o.x !== undefined; //true
"y" in o //false
o.y !== o //false
"toString" in o //true o繼承toString屬性
o.toString !== o //true o繼承toString屬性
有一種情況in和!==不同,即屬性值為undefined的時候,"x" in o 為true o.x !== undefined 為false。
檢測屬性是否為對象的自有屬性(非繼承)
hasOwnProperty():
o.hasOwnProperty("x"); //true
o.hasOwnProperty("y"); //false
o.hasOwnProperty("toString") //false toString是繼承屬性
檢測屬性是否為對象的自有屬性,並且屬性是否為可枚舉的
propertyIsEnumerable():
o.propertyIsEnumerable("x"); //true o有一個可枚舉的自有屬性x
object.prototype.propertyIsEnumerable("toString"); //false:不可枚舉
見128頁6.4
------------------------------------------------16.10.13 結束---------------------------------------------------------------------------
-----------------------------------------------16.10.15 開始---------------------------------------------------------------------------
枚舉屬性
for/in循環可以遍歷繼承來的屬性
見130頁上
Object.getOwnPropertyNames(o); // 獲取對象的所有自有屬性。
見132頁上
-----------------------------------------------16.10.15 結束---------------------------------------------------------------------------
-----------------------------------------------16.10.16 開始---------------------------------------------------------------------------
getter和setter
和數據屬性不同,由getter和setter定義的為存取器屬性
var o = {
x:1,
get r(){ return this.x},
set r(value) { this.x = value},
}
o.r //1
o.r = 2;
o.r //2
此時r這個屬性是可讀可寫的,如果我們將set去掉。不管怎麼給o.r賦值,o.r的屬性一直都是不變的。但是在非嚴格模式下是不會報錯的。同理,去掉get以後就無法獲取屬性值,o.r的值就為undefined。
見132頁6.6
var a= {
$n = 0 //$符號暗示這個屬性是一個私有屬性
}
a.n //undefined
見134頁上
屬性的特性(API對庫開發者來說非常重要)因為:
1、 可以通過這些API給原型對象添加方法,並將它們設置成不可枚舉的,這讓它們看起來更像內置方法。
2、可以通過這些API給對象定義不能修改或刪除的屬性,借此“鎖定”這個對象。
屬性的4個特性(‘屬性描述符’對象):
1、數據屬性:值(value)、可寫性(writable)、可枚舉性(enumerable)、可配置性(configurable)
2、存取器屬性:讀取(get)、寫入(set)、可枚舉性、可配置性
通過Object.getOwnPropertyDescriptor()可以獲得某個對象特定屬性的屬性描述符:
Object.getOwnPropertyDescriptor({x:1},"x") // 返回{value:1, writable:true, enumerable:true, configurable:true}
Object.getOwnPropertyDescriptor(o,"r") //查詢上面定義的o的r屬性,返回{get:/*func*/, set:/*func*/, enumerable:true, configurable:true}
如果屬性不存在,或者為繼承屬性,則返回undefined
見134頁6.7
設置屬性特性:
var o = {}
Object.defineProperty(o,"x",{ value:1,
writable:true,
enumerable:false,
configurable:true});
//給o對象添加一個不可枚舉的數據屬性x,並賦值為1
Object.keys(o) //因為o的x屬性是不可枚舉的,所以返回空數組[]
Object.defineProperty(o,"x",{writable:false}); //將x屬性變成只讀
o.x = 2 //操作失敗,但在非嚴格模式中不會報錯
o.x //為1
Object.defineProperty(o,"x",{value:2}) //因為屬性依然是可配置的,所以可以通過這種方法進行修改
Object.defineProperty(o,"x",{get:function(){return 0;}}); //還可以將x從數據屬性改為存取器屬性
o.x //輸出0
從上面可以看出來Object.defineProperty()的屬性描述符參數對象不需要包含所有的4個特性,如果是新創建的,那麼默認的就是false或者undefined。如果是修改的,那麼就只修改設置的。
注意:這個方法要麼修改已有屬性,要麼新建自有屬性,並不能修改繼承屬性。
見135頁中下
同時修改或創建多個屬性:
var o = {};
Object.defineProperties(o,{
x:{value:1, writable:true, enumerable:true, configurable:true},
y:{value:2, writable:true, enumerable:true, configurable:true},
r:{
get:function(){return Math.sqrt(this.x*this.x+this.y*this.y)},
enumerable:true,
configurable:true
}
});
見136頁中
Object.defineProperty()和Object.defineProperties()使用規則:
1、如果對象是不可擴展的(參見6.8.3節),則可以編輯已有的自有屬性,但不能給它添加新屬性。
2、如果屬性是不可配置的,則不能修改它的可配置性和可枚舉性。
3、如果存取器屬性是不可配置的,則不能修改其getter和setter方法,也不能將它轉換為數據屬性。
4、如果數據屬性是不可配置的,則不能將它轉換為存取器屬性。
5、如果數據屬性是不可配置的,則不能將它的可寫性從false修改為true,但可以從true修改為false。
6、如果數據屬性是不可配置且不可寫的,則不能修改它的值。然而可配置但不可寫屬性的值是可以修改的(實際上是先將它標記為可寫的,然後修改它的值,最後轉換為不可寫的)。
見136頁下
檢測對象是否是另一個對象的原型:
var p={x:1}
var o = Object.creat(p);
p.isPrototypeOf(o); //true
Object.prototype.isPrototypeOf(o) //true
isPrototypeOf()和instanceof運算符非常類似
-----------------------------------------------16.10.16 結束---------------------------------------------------------------------------
-----------------------------------------------16.10.20 開始---------------------------------------------------------------------------
對象的可擴展性:
ES5中所有內置對象和自定義對象都是顯式可擴展的,除非將他們轉換為不可擴展的。宿主對象的可擴展性是由JS引擎定義的。
Object.esExtensible(o) //判斷o對象是否是可擴展的
Object.preventExtensions(o) //將o對象轉換為不可擴展的,注意,如果轉換為不可擴展的,則無法再將其轉換為可擴展的。
同時,preventExtensions只會影響到對象本身的可擴展性。如果給一個不可擴展的對象的原型添加屬性,這個對象同樣會繼承這些屬性。
Object.seal(o) //封鎖,將對象設置為不可擴展的,並且將對象所有的自有屬性設置為不可配置的。即無法添加,刪除或配置。如果是已有的可寫屬性,則依然可以設置。
Object.isSealed(o) //判斷是否封鎖對象
Object.freeze(o) //凍結,seal的升級版,會將所有數據屬性設置為只讀,存取器屬性不受限制。
Object.isFreeze(o) //判斷是否凍結對象
見140頁6.8.3
序列化對象:
JSON.parse() //將字符串轉換為JSON對象()
JSON.stringify() //將JSON對象轉換為字符串(只能序列化對象可枚舉的自有屬性)
見141頁6.9
6.10對象方法以後看
數組:
數組是一個特殊化的對象。當使用非整數或負數的作為下標的時候,則自動添加下標為屬性名,當添加的下標為非負整數時,則自動維護其length屬性
var a=[];
a[-1.23] = true; //創建一個名為'-1.23'的屬性
a["100"] = 0; //這是數組的第101個屬性,同時數組的length變為101
a[1.000] = 0 //和a[1]相等
見146頁下
稀疏數組:
按書中的說法,當采用new方法時才會產生稀疏數組,采用直接量的時候就不會,比如:
var a1 = [,,,];
var a2 = new Array(5);
0 in a1 //true
0 in a2 //false
但是實際操作中,兩個都是顯示的false
然後在下面的操作中又說了:
var a1=[,];
var a2 = [undefined];
0 in a1 //false
0 in a2 //true
見147頁下
如果將數組length設置為比數組真實長度小時,數組會刪除超出部分的元素。比如:
var a = [1,2,3,4,5];
a.length = 3; //a=[1,2,3]
因此,如果讓一個數組元素不能配置,那麼就不能刪除它,所以length的值就不能小於這個元素的索引值+1,如果小於,不會報錯,但是不會發生改變。
見148頁下
a.push(“123”) === a[a.length] = “123”
用delete刪除數組中的元素,不會影響數組的length
見149頁7.5
如果數組同時擁有對象屬性和數組元素,返回的的屬性名很有可能是按照創建的順序而非數值的大小順序。所以盡量避免使用for/in循環數組(雖然我的測試是先循環數組,再循環屬性)
見151頁上
-----------------------------------------------16.10.20 結束---------------------------------------------------------------------------
-----------------------------------------------16.10.21 開始---------------------------------------------------------------------------
JS不支持真正的多維數組,但可以用數組的數組來近似。
見151頁7.7
數組方法:見152頁7.8或者本博客的JAVASCRIPT筆記
sort()方法
var a = [1,3,2,4,6,5]
a.sort() //當不帶參數時,ASCII碼順序排列。
a.sort(function(a,b){return b-a}) //帶參數的sort,參數為一個函數,規定了排列的順序,如果a要排在b前面,則返回小於0的數,如果b要在a之前,則返回大於0的數,如果無所謂,返回0,這個例子返回從大到小排列的數組
ES5中的數組方法:
forEach() //將數組按照索引的順序按個傳遞給定義的一個函數。
var data=[1,2,3,4,5];
var sunOfSquares = 0;
data.forEach(function(x){
sumOfSquares +=x*x;
});
data.forEach(function(v,i,a){a[i] = v+1} //可以使用三個參數,分別為元素,索引和數組本身
注意:forEach循環無法使用break提前終止語句,如果需要提前終止,必須放在try塊中,並能拋出一個異常。比如:
function foreach(a,f,t){
try{a.forEach(f,t);}
catch(e){
if(e === foreach.break) return;
else throw e;
}
}
foreach.break = new Error("stopIteration");
map()
a = [1,2,3];
b = a.map(function(x){return x*x}); //b為[1,4,9],與forEavh不同的是,map有返回值,返回一個新的數組。它不修改調用的數組。
filter()
filter()返回的數組元素是調用的數組的一個子集。傳遞的函數是用來邏輯判定的:該函數返回true或false。來決定該元素是否屬於這個子集。
a = [5,4,3,2,1];
b = a.filter(function (x) {return x<3}); //[2,1]
c = a.filter(function(x,i) {return i%2 == 0}); //[5,3,1];
注意:filter()會跳過數組中缺少的元素,他的返回數組總是稠密的。
所以我們可以這樣:a = a.filter(function() {return true;})來使數組變為稠密數組
甚至,壓縮空缺並刪除undefined和null元素,可以這樣使用filter();
a = a.filter(function(x) {return x !== undefined && x != null});
every()和some()
這兩個函數是對數組中的每個元素進行邏輯判定,返回true或false、
every()相當於數學中的所有量詞,比如:
a = [1,2,3,4,5]
a.every(function(x){return x<10};) //true,數組中所有元素<10
a.every(function(x){return x%2 === 0;}) //false,數組中並不是所有元素都為偶數
some()則相對,比如:
a.some(function(x){return x%2 === 0;}) //true,數組中有偶數值
a.some(isNaN) //false,數組中不包含非數值元素
需要注意的時,這兩個函數一旦確定需要返回什麼樣的值就會停止遍歷元素,如同復合的if條件一樣
reduce()和reduceRight()
不知道怎麼描述這個函數。直接看例子吧
var a = [1,2,3,4,5];
var sum = a.reduce(function(x,y){return x+y},0); //數組求和
var product = a.reduce(function(x,y){return x*y},1); //數組求積
var max = a.reduce(function(x,y){return (x>y)?x:y;}); //求最大值
如上所示,reduce函數需要兩個參數,第一個是函數,函數會返回一個計算後的值,第二個是初始值。函數中第一個參數是到目前為止的操作累積結果,第2-4個參數為v,i,a三兄弟。
在第一次調用的時候,初始值就為函數的第一個參數,第二次的時候就是函數返回的值為第一個參數,以此類推。
如果不傳遞第二個參數,則函數會選擇數組的第一個元素為第一參數,第二���元素作為第二參數,所以上面的例子中其實是可以省略第二個參數的。但是在空數組上,不帶初始值參數調用reduce()會導致類型錯誤異常。如果只有一個值,或者空數組帶一個初始值,則只會返回那個數,並不會執行函數,比如:
a = [];
a.reduce(function(x,y){return x*2},2); //返回2,並沒有執行*2操作
reduceRight()和reduce()的區別就是reduceRight是從高到低執行
indexOf()和lastIndexOf()
獲取數組中給定元素的索引,沒有則返回-1
a = [6,1,4,3,1];
a.indexOf(1); //1
a.lastIndexOf(1); //4
a.indexOf(1,3) //4,第二個參數為指定起始位置
見156頁7.9
-----------------------------------------------16.10.21 結束---------------------------------------------------------------------------
-----------------------------------------------16.10.22 開始---------------------------------------------------------------------------
this:
嵌套函數作為函數調用時,this值指向全局對象(非嚴格模式下)或者為undefined(嚴格模式下)。
比如:
var o={
m:function(){
var self = this;
console.log(this === o) //true
f();
function f(){
console.log(this===o) //false
console.log(self === o) //true
}
}
}
見171頁下
構造函數:
如果沒有形參,則可以省略()
var o = new Object();
var o = new Object;
這兩行代碼是一模一樣的。
-----------------------------------------------16.10.22 結束---------------------------------------------------------------------------
-----------------------------------------------16.10.23 開始---------------------------------------------------------------------------
實參對象:arguments
arguments實際上並不是真正的數組,它是一個實參對象。只是碰巧具有以數字為索引的屬性。
arguments還有callee和caller兩個屬性
callee:指代當前正在執行的函數
caller:指代當前正在執行的函數的函數
見175頁
自定義函數屬性:
function factorial(n){
if(isFinite(n) && n > 0 && n == Math.round(n)){
if(!(n in factorial))
factorial[n] = n * factorial(n-1);
return factorial[n];
}
else return NaN;
}
factorial[1] = 1;
這個函數使用自身的屬性,來緩存了每一次計算的結果。
見180頁
閉包
可以讓函數外部訪問到函數內部的變量。
初看很強大,之前也是這個部分很難理解,現在一路看下來要好很多了,具體的,明天靜下心來好好看。
見182頁8.6
-----------------------------------------------16.10.23 結束---------------------------------------------------------------------------
-----------------------------------------------16.10.24 開始---------------------------------------------------------------------------
看半天閉包看不明白,花了時間把這個博客看完了,講的很贊,容易懂,點擊這裡
但是很遺憾文章裡面沒有講到,倒是書上講到了一個內容,就是多個閉包時,變量的共享:
function constfuncs(){
var funcs = [];
for(var i = 0; i < 10; i++)
funcs[i] = function(){return i};
return funcs;
}
var funcs = constfuncs();
funcs[5]() //返回10
這是因為關聯到閉包的作用於鏈都是“活動的”
見187頁下
-----------------------------------------------16.10.24 結束---------------------------------------------------------------------------
-----------------------------------------------16.10.25 開始---------------------------------------------------------------------------
call()和apply()區別
apply()傳入實參後,剩下的參數都以數組的形式傳遞,可以使用類數組對象,也可以將當前的函數的arguments數組直接傳入apply()來調用另一個函數
見190頁中
這節有點難度,不是很好理解,明天重新看一遍
-----------------------------------------------16.10.25 結束---------------------------------------------------------------------------
-----------------------------------------------16.10.26 開始---------------------------------------------------------------------------
bind()方法:
f().bind(o),並傳入一個對象o作為參數,這個方法將返回新的函數。
也可以傳入n個參數,將第2-n個參數作為f()的參數再傳給f()
用bind()返回的函數做構造函數的那部分看不懂
見192頁中
Function構造函數
可以動態的創建並編譯函數,比如放在if中
見193頁中
函數式編程
參數是函數,返回的也是函數。
代碼看起來很優雅,把一個函數拆分成了很多個小的函數,感覺封裝思想很好。但是確實繞來繞去的。
考慮到工作中主要是進行DOM和BOM操作,所以從明天開始看第二部分的客戶端JS
-----------------------------------------------16.10.26 結束---------------------------------------------------------------------------
-----------------------------------------------16.11.02 開始---------------------------------------------------------------------------
343頁中說,document對象有一個URL屬性,Location對象也表示的為該窗口中當前顯示的文檔的URL,但是如果定位到文檔中的片段標識符(如#top),location對象會做相應的更改,而document.URL屬性卻不會改變。(書中原文)但實際上,在chrome中測試的時候發現,ducoment.URL屬性是也會改變的。
location.assign("http://www.baidu.com")和location.href="http://www.baidu.com"看上去是一樣的 //在當前頁面到基礎上載入新的文檔,如果在新的文檔按返回鍵,則會返回當前頁面
location.replace("http://www.baidu.com") //載入新的文檔,如果在新的文檔按返回鍵,則會返回首頁
見344頁14.2.2
現在有了ajax技術後,我們很多情況下都會使用無刷新的方式來進行文檔載入,那麼就會存在一個問題,就是這個無刷新的過程中url是不會改變的,那麼如果實現前進和後退功能呢,這個時候我們可以在使用了ajax技術的地方采用a標簽錨點方式。比如<a href="#page_1">第一頁</a> 因為浏覽器會讀取這個錨點信息,所以url會進行改變,url改變了,那麼自然這個網頁就進入到了歷史紀錄中了。就可以采用前進後退到方式進行浏覽了。
-----------------------------------------------16.11.02 結束---------------------------------------------------------------------------
-----------------------------------------------16.11.03 開始---------------------------------------------------------------------------
navigator對象
屬性:
appName 除了IE為"Microsoft Internet Explorer",其它浏覽器通常為了兼容取值為"Netscape"
appVersion 此屬性通常以數字開始,並包含浏覽器廠商和版本信息的詳細字符串。沒有標准的格式,所以沒有辦法直接用它來判斷浏覽器類型。
userAgent 浏覽器在它的USER-AGENT HTTP頭部中發送的字符串。這個屬性通常包含appVersion中的所有信息。並且常常也可能包含其它細節。由於這個屬性包涵絕大部分信息,因此浏覽器嗅探代碼通常用它來嗅探
platform 在其上運行浏覽器的操作系統(並且可能是硬件)的字符串。
onLine 表示浏覽器當前是否連接到網絡
geolocation 定義用於確定用戶地理位置信息的借接口。
javaEnabled() 一個非標准的方法,當浏覽器可以運行java小程序時返回true。
cookieEnable() 非標准的方法,如果浏覽器可以永久保存的cookie時,返回true。當cookie配置為“視具體情況而定”時可能會返回不正確的值。
screen對象
width和height 以像素為單位的窗口大小
availWidth和availHeight 實際可用的顯示大小
見346頁14.4.1
-----------------------------------------------16.11.03 結束---------------------------------------------------------------------------
-----------------------------------------------16.11.17 開始---------------------------------------------------------------------------
作為window對象屬性的文檔元素
如果一個dom元素用id屬性來為元素命名,並且如果window對象沒有此名稱的屬性(包括全局變量,因為全局變量也是掛載在window的屬性上的),那麼window對象就會將這個id作為自己的屬性,用來表示對應的dom元素。(非常驚奇,原來還可以這樣)
以下HTML元素如果有name屬性的話,也會這樣表現:
a applet area embed form frame frameset iframe img object
因為name不是唯一的,所以如果有多個相同的name屬性,具有該名稱的隱式全局變量會引用一個類數對象,這個類數組對象的元素是所有命名的元素。
見352頁
-----------------------------------------------16.11.17 結束---------------------------------------------------------------------------
-----------------------------------------------16.11.19 結束---------------------------------------------------------------------------
接觸到新名詞HTMLCollection對象,如:document.images和document.forms。
像getElementsByClassName()返回的為NodeList對象。
HTMLCollection對象為只讀的類數組對象。
見367頁方框
node對象的屬性
document對象,它Element對象和文檔中表示文本的Text對象都是node對象。
parentNode 節點的父節點
childNodes 節點的子節點(NodeList對象)
firstChild 第一個子節點
lastChild 最後一個子節點
nextSibling 下一個兄弟節點
previousSibling 上一個兄弟節點
nodeType 節點類型,數字表示
nodeValue Text或者Comment節點(即注釋)的文本內容
nodeName 元素的標簽名,全大寫。
下面的屬性忽略Text和Comment節點,只考慮element節點,除IE之外
firstElementChild
lastElementChild
nextElementSibling
previousElementSibling
childElementCount
-----------------------------------------------16.11.19 結束---------------------------------------------------------------------------
-----------------------------------------------16.11.21 開始---------------------------------------------------------------------------
有些HTML屬性在js中是保留字。對於這些屬性,一般的規則是為屬性名加'html'例如,HTML中label的for屬性就變成了‘htmlFor’,
但是class是個例外,在js中為className。
見376頁中上部。
Node類型定義了attributes屬性。對於element對象,attributes屬性是只讀的類數組對象,它代表元素的所有屬性。並且還可以用屬性名索引:
document.body.attributes[0] //body元素的第一個屬性
document.body.attributes.bgcolor //元素的bgcolor屬性
document.body.attributes["ONLOAD"] //元素的onload屬性
見378頁15.4.4
通常設置innerHTML效率非常高,但是對innerHTML使用+= 通常效率低下,因為它既要序列化又要解析
outerHTML屬性,包括了innerHTML以及元素本身。
見379頁中部
-----------------------------------------------16.11.21 結束---------------------------------------------------------------------------
---------------------------------------------相關函數-----------------------------------------------------
Object.create(o) //創建對象,o為原型對象 121頁6.2.1
o.hasOwnProperty("x") //判斷屬性x是否為o的自有屬性(非繼承) 128頁6.4
o.propertyIsEnumerable("x") //判斷屬性是否為o的自有屬性,並且可以枚舉 128頁6.4
Object.keys(o) //返回一個由o對象中可枚舉的自有屬性的名稱組成的數組。 132頁上
Object.getOwnPropertyNames(o) //返回o對象的所有自有屬性的名稱。 132頁上
Object.getOwnPropertyDescriptor(o,"r") //查詢o對象的r屬性的屬性描述符對象
Object.defineProperty(o,"x",{ value:1,
writable:true,
enumerable:false,
configurable:true});
//給o對象設置x屬性,並對x屬性添加屬性描述符
Object.defineProperties(o,{
x:{value:1, writable:true, enumerable:true, configurable:true},
y:{value:2, writable:true, enumerable:true, configurable:true},
r:{
get:function(){return Math.sqrt(this.x*this.x+this.y*this.y)},
enumerable:true,
configurable:true
}
});
//給o對象設置多個屬性值,並對每個屬性值添加屬性描述符
Object.esExtensible(o) //判斷o對象是否是可擴展的
Object.preventExtensions(o) //將o對象轉換為不可擴展的,注意,如果轉換為不可擴��的,則無法再將其轉換為可擴展的。
Object.seal(o) //封鎖,將對象設置為不可擴展的,並且將對象所有的自有屬性設置為不可配置的。即無法添加,刪除或配置。如果是已有的可寫屬性,則依然可以設置。
Object.isSealed(o) //判斷是否封鎖對象
Object.freeze(o) //凍結,seal的升級版,會將所有數據屬性設置為只讀,存取器屬性不受限制。
Object.isFreeze(o) //判斷是否凍結對象
JSON.parse() //將字符串轉換為JSON對象
JSON.stringify() //將JSON對象轉換為字符串(只能序列化對象可枚舉的自有屬性)
forEach() //將數組按照索引的順序按個傳遞給定義的一個函數。