摘要:紅寶書筆記在中使用加載外部腳本文件,通知瀏覽器立即下載,異步執(zhí)行腳本可以延遲到文檔完全被解析和顯示之后在執(zhí)行瀏覽器不支持腳本。對數(shù)組中的每一項運行給定函數(shù),返回該函數(shù)會返回的項組成的數(shù)組。
紅寶書筆記 1.在HTML中使用JavaScript
async:加載外部腳本文件,通知瀏覽器立即下載,異步執(zhí)行
defer:腳本可以延遲到文檔完全被解析和顯示之后在執(zhí)行
noscript:
瀏覽器不支持腳本。
瀏覽器支持腳本,但是腳本被禁用
復制變量值
復制基本類型值,這兩個變量相互獨立,互不影響。
復制引用類型(對象),值引用是一個指針,改變其中一個對象,會影響另一個對象。
function setName(obj) { obj.name = "Nicholas"; obj = new Object(); obj.name = "Greg"; } var person = new Object(); setName(person); alert(person.name); //"Nicholas"
在函數(shù)重寫obj時,這個變量引用就是一個局部對象。而這個對象會在函數(shù)執(zhí)行完畢后立即被銷毀。
檢測類型
使用typeof檢測基本數(shù)據(jù)類型,但是在檢測引用類型的值是,這個操作符的用處不大,因為使用typeof無法知道它是什么類型的對象。為此,ECMAScript提供了 instanceof操作符。
var s = "test"; var b = true; var i = 22; var u; var n = null; var o = new Object() console.log(typeof s); // string console.log(typeof b); // boolean console.log(typeof i); // number console.log(typeof u); // undefined console.log(typeof n); // object console.log(typeof o); // object
延長作用域鏈
try-catch語句中的catch塊
with語句
垃圾回收
標記清除
垃圾收集器在運行的時候會給存儲在內(nèi)存中的所有變量都加上標記
引用計數(shù)
當它們被賦值為指向某個對象時,要給它們原本持有的引用所指向的對象的引用計數(shù)減1,然后給它們新指向的對象的引用計數(shù)加1。當它們的生命期結(jié)束的時候,要給它們所指向的對象的引用計數(shù)減1,當引用計數(shù)為0時,則可以將其占用的內(nèi)存空間進行回收
3.引用類型 Array類型檢測數(shù)組
value instanceof Array Array.isArray(value)
棧方法(后進先出)
push:將參數(shù)逐個添加到數(shù)據(jù)末尾
pop:從數(shù)組末尾移除最后一項
隊列方法(先進先出)
shift:刪除數(shù)組的第一項并返回該項
unshift:向數(shù)組前添加任意個項并返回新數(shù)組的長度
重排序方法
reverse:反轉(zhuǎn)數(shù)組
sort:按升序排列數(shù)組
操作方法
concat:將參數(shù)添加到數(shù)組的末尾,并返回新的數(shù)組
slice:基于當前數(shù)組中的一或多個項創(chuàng)建一個新數(shù)組,slice()方法可以接受一或者兩個參數(shù),即要返回項的起始和結(jié)束為止
var colors = ["red", "green", "blue", "yellow", "purple"]; var colors2 = colors.slice(1) var colors3 = colors.slice(4) console.log(colors2); // ["green", "blue", "yellow", "purple"] console.log(colors3); // ["purple"]
splice:返回新的數(shù)組,能夠刪除、插入和替換多個項
var colors = ["red", "green", "blue"]; var removed = colors.splice(0,1); // 刪除第一項 alert(colors); // green,blue alert(removed); // red,返回的數(shù)組中只包含一項 removed = colors.splice(1, 0, "yellow", "orange"); // 從位置1 開始插入兩項 alert(colors); // green,yellow,orange,blue alert(removed); // 返回的是一個空數(shù)組 removed = colors.splice(1, 1, "red", "purple"); // 插入兩項,刪除一項 alert(colors); // green,red,purple,orange,blue alert(removed); // yellow,返回的數(shù)組中只包含一項
位置方法
indexOf:從數(shù)組開頭開始向后查找位置
lastIndexOf:從數(shù)組末尾開始向前查找
迭代方法
every(): 對數(shù)組中的每一項運行給定函數(shù),如果該函數(shù)對每一項都返回true,則返回true。
filter(): 對數(shù)組中的每一項運行給定函數(shù),返回該函數(shù)會返回true 的項組成的數(shù)組。
forEach(): 對數(shù)組中的每一項運行給定函數(shù)。這個方法沒有返回值。
map(): 對數(shù)組中的每一項運行給定函數(shù),返回每次函數(shù)調(diào)用的結(jié)果組成的數(shù)組。
some(): 對數(shù)組中的每一項運行給定函數(shù),如果該函數(shù)對任一項返回true,則返回true。
縮小方法
reduce():遍歷數(shù)組所有項,并返回最終的值,從第一項開始,逐個遍歷到最后
reduceRight():從最后一項開始,逐個遍歷到第一項
var values = [1, 2, 3, 4, 5]; var sum = values.reduce((prev, cur, index, array) => { return prev + cur; }); console.log(sum); // 15Function類型
函數(shù)內(nèi)部屬性
函數(shù)內(nèi)部有兩個特殊的對象:argumens和this
屬性和方法
每個函數(shù)都包含兩個屬性
length: 表示函數(shù)希望接收的命名參數(shù)的個數(shù)
prototype: 保存實例方法
每個函數(shù)都包含兩個非繼承而來的方法
call()和apply()這兩個方法的用途都是在特定的作用域中調(diào)用函數(shù),實際上等于設置函數(shù)體內(nèi)this對象的值
apply()接收兩個參數(shù):一個是在其中運行的函數(shù)作用域,另一個是參數(shù)數(shù)組
call()接收的參數(shù),第一個參數(shù)是this值沒有變化,變化的是其余參數(shù)都直接傳遞給函數(shù)
bind()方法會創(chuàng)建一個實例,其this值會被綁定到傳給bind()函數(shù)的值
function sum (num1, num2) { return num1 + num2; } function callSum1 (num1, num2) { return sum.apply(this, [num1, num2]); } function callSum2 (num1, num2) { return sum.call(this, num1, num2); } callSum1(10, 10); // 20 callSum2(10, 10); // 20 var callSum3 = sum.bind(null) callSum3(10, 10) // 20單體內(nèi)置對象
Global對象
encodeURI()和encodeURIComponet()方法可以對URI進行編碼,以便發(fā)送給瀏覽器
encodeURI()編碼后的結(jié)果是除了空格之外的其他字符都原封不動,只有空格被替換成了%20,對應decodeURI()方法
encodeURIComponet()方法則會使用對應的編碼替換所有非字母數(shù)字字符,這也正式可以對整個URL使用encodeURI(),而只能對附加在現(xiàn)有URL后面的字符串使用encodeURIComponet()的原因所在。對應decodeURIComponet()方法
4.面向?qū)ο蟮某绦蛟O計 理解對象屬性類型
ECMAScript中有兩種屬性:數(shù)據(jù)屬性和訪問器屬性
數(shù)據(jù)屬性
[[Configurable]]:表示能否通過delete刪除屬性從而重新定義屬性,能否修改屬性的特性,或者能否把屬性修改為訪問器屬性,默認值為true
[[Enumerable]]:表示能否通過for-in循環(huán)返回屬性。默認值為true
[[Writable]]:表示能否修改屬性的值。默認值為true
[[Value]]:包含這個屬性的數(shù)據(jù)值,默認值為undefined
要修改屬性默認的特性,必須使用Object.defineProperty()方法。這個方法接收三個參數(shù):屬性所在對象、屬性的名字和一個描述符對象。其中,描述符對象的屬性必須是:configurabel、enumerable、writable、和value。設置其中的一個或多個值。
var person = {} Object.defineProperty(person, "name", { writable: false, configurable: false, value: "Nicholas" }); console.log(person.name); // Nicholas person.name = "Greg"; console.log(person.name); // Nicholas delete person.name console.log(person.name); // Nicholas
Object.defineProperty()方法會對configurable為false的屬性修改做限制
訪問器屬性
[[Configurable]]:表示能否通過delete刪除屬性從而重新定義屬性,能否修改屬性的特性,或者能否把屬性修改為數(shù)據(jù)屬性。默認值為true
[[Enumerable]]:表示能否通過for-in循環(huán)返回屬性。默認值為true
[[Get]]:在讀取屬性時調(diào)用的函數(shù)。默認值為undefined
[[Set]]:在寫入屬性時調(diào)用的函數(shù)。默認值為undefined
訪問器屬性不能直接定義,必須使用Object.defineProperty()來定義
var book = { _year: 2004, edition: 1 }; Object.defineProperty(book, "year", { get: function() { return this._year }, set: function(newValue) { if (newValue > 2004) { this._year = newValue; this.edition += newValue - 2004 } } }); book.year = 2005; console.log(book.edition); // 2
定義多個屬性
ECMAScript5定義了一個Object.defineProperties()方法。利用這個方法可以通過描述符一次定義多個屬性。這個方法接收兩個對象參數(shù)。
var book = {}; Object.defineProperties(book, { _year: { value: 2004 }, edition: { value: 1 }, year: { get: function() { return this._year }, set: function(newValue) { if (newValue > 2004) { this._year = newValue; this.edition += newValue - 2004 } } } });
讀取屬性的特性
使用Object.getOwnPropertyDescriptor()方法,可以取得給定屬性的描述符
var descriptor = Object.getOwnPropertyDescriptor(book, "_year") console.log(descriptor.value); // 2004 console.log(descriptor.configurable); // false創(chuàng)建對象
工廠模式
function createPerson (name, age, job) { var o = new Object(); o.name = name; o.age = age; o.job = job; o.sayName = function () { console.log(this.name); }; return o; } var person1 = createPerson("Nicholas", 29, "Software Engineer"); var person2 = createPerson("Greg", 27, "Doctor");
構造函數(shù)模式
function Person (name, age, job) { this.name = name; this.age = age; this.job = job; this.sayName = function () { console.log(this.name); }; } var person1 = new Person("Nicholas", 29, "Software Engineer"); var person2 = new Person("Greg", 27, "Doctor");
原型模式
理解原型對象
function Person () {} Person.prototype.name = "Nicholas"; Person.prototype.age = 29; Person.prototype.job = "Software Engineer"; Person.prototype.sayName = function () { console.log(this.name); }; var person1 = new Person(); var person2 = new Person();
在默認情況下,所有原型對象都會自動獲得一個constructor(構造函數(shù))屬性,這個屬性包含一個指向一個prototype屬性所在函數(shù)的指針。例如,Person.prototype.constructor指向Person
我們可以通過isPrototypeof()方法來確定對象之間是否存在原型關系。從本質(zhì)上講,如果[[Prototype]]指向調(diào)用isPrototypeof()方法的對象(Person.prototye),那么這個方法就返回true。
console.log(Person.prototype.isPrototypeOf(person1)); // true console.log(Person.prototype.isPrototypeOf(person2)); // true
ECMAScript5增加了一個新方法,叫Object.getPrototypeOf(),在所有支持的實現(xiàn)中,這個方法返回[[Prototype]]的值。例如:
console.log(Object.getPrototypeOf(person1) === Person.prototype); // true
雖然可以通過對象實例訪問保存在原型中的值,但卻不能通過對象實例重寫原型中的值。如果我們在實例中添加了一個屬性,而該屬性與實例原型中的一個屬性同名,那我們就在實例中創(chuàng)建該屬性,該屬性將會屏蔽原型中的那個屬性。
function Person() {} Person.prototype.name = "Nicholas"; Person.prototype.age = 29; Person.prototype.job = "Software Engineer"; Person.prototype.sayName = function() { alert(this.name); }; var person1 = new Person(); person1.name = "Greg"; console.log(person1.name); //"Greg" — 來自實例 delete person1.name; console.log(person1.name); //"Nicholas" — 來自原型
通過delete操作符刪除實例的屬性,就恢復了對原型中name屬性的連接。因此接下來再調(diào)用person1.name是,就返回了原型中name屬性的值了。
Object.hasOwnProperty()方法可以檢測一個屬性是否存在于實例中,還是存在于原型中。
原型與in操作符
in操作符只要通過對象能夠訪問到屬性就返回true,Object.hasOwnProperty()只在屬性存在于實例中才返回true,因此只要in操作符返回true而Object.hasOwnProperty()返回false,就可以確定屬性是原型中的屬性。
function hasPrototypeProperty (object, name) { if (name in object) { return object.hasOwnProperty(name) // true:屬性在實例中,false:屬性在對象中 } else { console.log("沒有該屬性"); } }
要取得對象上所有可枚舉的實例屬性,可以使用ECMAScript5的Object.keys()方法
function Person () {} Person.prototype.name = "Nicholas"; Person.prototype.age = 29; Person.prototype.job = "Software Engineer"; Person.prototype.sayName = function () { console.log(this.name); }; Object.keys(Person.prototype); // ["name", "age", "job", "sayName"] var person1 = new Person(); person1.name = "Rob"; person1.age = 31; Object.keys(person1); // ["name", "age"]
Object.getOwnPropertyNames()可以得到所有的屬性,無論它是否可枚舉
Object.getOwnPropertyNames(Person.prototype); // ["constructor", "name", "age", "job", "sayName"]
更簡單的原型方法
function Person () {} Person.prototype = { name: "Nicholas", age: 29, job: "Software Engineer", sayName: function () { console.log(this.name); } }
我們將Person.prototype設置為一個新的對象,本質(zhì)上是完全重寫了默認的prototype對象。但是這樣有一個例外,constructor屬性不再指向Person了,而是指向Object。所以我們需要將他的constructor屬性設置成Person
function Person () {} Person.prototype = { constructor: Person, name: "Nicholas", age: 29, job: "Software Engineer", sayName: function () { console.log(this.name); } }
但是這種方式重設constructor屬性會導致它的[[Enumerable]]的特性被設置為true,默認情況下,原生的constructor屬性是不可枚舉的。
function Person () {} Person.prototype = { name: "Nicholas", age: 29, job: "Software Engineer", sayName: function () { console.log(this.name); } } Object.defineProperty(Person.prototype, "constructor", { enumerable: false, value: Person });
原型的動態(tài)性
重寫整個原型對象會切斷構造函數(shù)與最初原型之間的聯(lián)系。記住:實例中的指針僅指向原型,而不指向構造函數(shù)
function Person () {} var friend = new Person(); Person.prototype = { constructor: Person, name: "Nicholas", age: 29, job: "Software Engineer", sayName: function () { console.log(this.name); } } friend.sayName(); // error
原生對象的原型
原型模式的重要性不僅體現(xiàn)在創(chuàng)建自定義類型方面,就連所有的原生的引用類型,都是采用這種模式創(chuàng)建的。所有原生引用類型(Object、Array、String,等等)都在其構造函數(shù)的原型上定義了方法。
原型對象的問題
原型模式的所有實例在默認情況下都將取得相同的屬性值,最大的問題是其共享的本性所導致的。
function Person () {} Person.prototype = { constructor: Person, name: "Nicholas", age: 29, job: "Software Engineer", friends: ["Shelby", "Court"], sayName: function () { console.log(this.name); } } var person1 = new Person(); var person2 = new Person(); person1.friends.push("Van"); console.log(person1.friends); // ["Shelby", "Court", "Van"] console.log(person2.friends); // ["Shelby", "Court", "Van"]
組合使用構造函數(shù)和原型模式
創(chuàng)建自定義類型的最常見的方式,構造函數(shù)模式用于定義實例屬性,而原型模式用于定義方法和共享的屬性。
每個實例都會有自己的一份實例屬性的副本,但同事又共享著對方法的引用,最大的節(jié)省了內(nèi)存
function Person (name, age, job) { this.name = name; this.age = age; this.job = job; this.friends = ["Shelby", "Court"]; } Person.prototype = { constructor: Person, sayName: function () { console.log(this.name); }; } var person1 = new Person("Nicholas", 29, "Software Engineer"); var person2 = new Person("Greg", 27, "Doctor"); person1.friends.push("Van"); console.log(person1.friends); // ["Shelby", "Court", "Van"] console.log(person2.friends); // ["Shelby", "Court"]
動態(tài)原型模式
通過在構造函數(shù)中初始化原型(僅在必要的情況下),又保持同時使用構造函數(shù)和原型模式的優(yōu)點。換句話說,可以通過檢查某個應該存在的方法是否有效,來決定是否需要初始化原型。
function Person (name, age, job) { this.name = name; this.age = age; this.job = job; this.friends = ["Shelby", "Court"]; if (typeof this.sayName === "function") { Person.prototype.sayName = function () { console.log(this.name); }; } }繼承
原型鏈
構造函數(shù)、原型和實例的關系:每個構造函數(shù)都有一個原型對象,原型對象都包含一個指向構造函數(shù)的指針,而實例都包含一個指向原型對象的內(nèi)部指針。
function SuperType () { this.property = true; } SuperType.prototype.getSuperValue = function () { return this.property }; function SubType () { this.subproperty = false } // 繼承了SuperType SubType.prototype = new SuperType(); SubType.prototype.getSubValue = function () { return this.subproperty; }; var instance = new SubType(); console.log(instance.getSuperValue()); // true
別忘記默認原型
所用引用類型默認都繼承Object,而這個繼承也是通過原型鏈實現(xiàn)的。所有函數(shù)的默認原型都是Object的實例,因此默認原型都會包含一個內(nèi)部指針,指向Object.prototype。
確定原型與實例的關系
instanceof操作符
console.log(instance instanceof Object); // true console.log(instance instanceof SuperType); // true console.log(instance instanceof SubType); // true
isPrototypeOf()方法,只要是原型鏈中出現(xiàn)過的原型,都可以說是該原型鏈所派生的實例的原型
console.log(Object.isPrototypeOf(instance)); // true console.log(SuperType.isPrototypeOf(instance)); // true console.log(SubType.isPrototypeOf(instance)); // true
謹慎的定義方法
子類型有時需要重寫超類型中的某個方法,或者需要添加超類型中不存在的某個方法。但不管怎樣,給原型添加方法的代碼一定要放在替換原型語句之后。
原型鏈的問題
通過原型來實現(xiàn)繼承時,原型實際上會變成另一個類型的實例,包含引用類型值的原型屬性會被所有實例共享。
在創(chuàng)建子類型的實例時,不能向超類型的構造函數(shù)中傳遞參數(shù)。
借用構造函數(shù)
在解決原型中包含引用類型值所帶來問題的過程中,開始使用借用構造函數(shù)的技術。即在子類型構造函數(shù)的內(nèi)部調(diào)用超類型構造函數(shù)
function SuperType () { this.colors = ["red", "blue", "green"]; } function SubType () { // 繼承了SuperType SuperType.call(this); // SuperType.apply(this); } var instance1 = new SubType(); instance1.colors.push("black"); console.log(instance1.colors); // ["red", "blue", "green", "black"] var instance2 = new SubType(); console.log(instance2.colors); // ["red", "blue", "green"]
傳遞參數(shù)
相對于原型鏈而言,借用構造函數(shù)有一個很大的優(yōu)勢,既可以在子類型構造函數(shù)中向超類型構造函數(shù)傳遞參數(shù)
function SuperType (name) { this.name = name; } function SubType () { // 繼承了SuperType SuperType.call(this, "Nicholas"); this.age = 29 } var instance = new SubType(); console.log(instance.name); // "Nicholas" console.log(instance.age); // 29
借用構造函數(shù)的問題
方法都在構造函數(shù)中定義,因為函數(shù)復用就無從談起
組合繼承
既能通過在原型上定義方法實現(xiàn)了函數(shù)復用,又能保證每個實例都有它自己的屬性
function SuperType (name) { this.name = name; this.colors = ["red", "blue", "green"]; } SuperType.prototype.sayName = function () { console.log(this.name); }; function SubType (name, age) { // 繼承了SuperType SuperType.call(this, name); this.age = age } // 繼承了SuperType SubType.prototype = new SuperType(); SubType.prototype.sayAge = function () { console.log(this.age); }; var instance1 = new SubType("Nicholas", 29); instance1.colors.push("black"); console.log(instance1.colors); // ["red", "blue", "green", "black"] instance1.sayName(); // "Nicholas" instance1.sayAge(); // 29 var instance2 = new SubType("Greg", 27); console.log(instance2.colors); // ["red", "blue", "green"] instance2.sayName(); // "Greg" instance2.sayAge(); // 275.函數(shù)表達式
定義函數(shù)的方式有兩種:一種是函數(shù)聲明,另一種是函數(shù)表達式。閉包
函數(shù)聲明的特征是函數(shù)聲明提升,意思是在執(zhí)行代碼之前會先讀取函數(shù)聲明。
函數(shù)作用域鏈
當某個函數(shù)第一次被調(diào)用時,會創(chuàng)建一個執(zhí)行環(huán)境及相應的作用域鏈,并把作用域鏈賦值給一個特殊的內(nèi)部屬性(即[[Scope]])。然后,使用this.arguments和其他命名參數(shù)的值來初始化函數(shù)的活動對象。但在作用域鏈中,外部函數(shù)的活動對象始終處于第二位,外部函數(shù)的外部函數(shù)的活動對象始終處于第三位,......直至作為作用域鏈終點的全局執(zhí)行環(huán)境。
閉包與變量
// i 最終為10 function createFunctions () { var result = new Array(); for (var i = 0; i < 10; i++) { result[i] = function () { return i } } return result; } // i 為 0,1,2...9 function createFunctions () { var result = new Array(); for (var i = 0; i < 10; i++) { result[i] = function (num) { return function (arguments) { return num; }; }(i) } return result; }
關于this對象
this對象是在運行中基于函數(shù)的執(zhí)行環(huán)境綁定的:在全局函數(shù)中,this等于window,而當函數(shù)被作為某個對象的方法調(diào)用時,this等于那個對象。不過匿名函數(shù)的執(zhí)行環(huán)境具有全局性,因此其this對象通常指向window。當然,再通過call()和apply()改變執(zhí)行函數(shù)執(zhí)行環(huán)境的情況下,this就會指向其他對象
var name = "The Window"; var object = { name: "My Object", getNameFunc: function () { return function () { return this.name } } } console.log(object.getNameFunc()()); // "The Window"
模仿塊級作用域
匿名函數(shù)可以用來模仿塊級作用域并避免這個問題。用塊級作用域(通常稱為私有作用域)的匿名函數(shù)的語法如下所示。
(function(){ })()
私有變量
function Person(name) { this.getName = function() { retirm name; } this.setName = function(value) { name = value } } var person = new Person("Nicholas"); console.log(person.getName()); // "Nicholas" person.setName("Greg"); console.log(person.getName()); // "Greg"
以上代碼的構造函數(shù)中定義了兩個特權方法:getName()和setName()。這兩個方法都可以在構造函數(shù)外部使用,而且都有權訪問私有變量name。但在Person構造函數(shù)外部,沒有任何方法訪問name。由于這兩個方法是在構造函數(shù)內(nèi)部定義的,它們作為閉包能夠通過作用域鏈訪問name。
靜態(tài)私有變量
全局作用域
拋開全局變量會成為window對象的屬性不談,定義全局變量與在window對象上直接定義屬相還是有一點差別:全局變量不能通過delete屬性操作符刪除,而直接在window對象上的定義的屬性可以。
var age = 29; window.color = "red"; delete window.age; // 不會報錯 delete window.color // 不會報錯 返回true var newValue = oldValue; // 會拋出錯誤,因為oldValue未定義 var newValue = window.oldValue; // 不會報錯,因為這是一次屬性查詢
窗口關系及框架
了解frameset和frame
窗口位置
下列代碼可以跨瀏覽器取得窗口左邊和上邊的位置
Opera支持screenX,screenY。其他瀏覽器支持screenLeft,screenTop
var leftPops = (typeof window.screenLeft === "number") ? window.screenLeft : window.screenX; var topPops = (typeof window.screenTop === "number") ? window.screenLeft : window.screenY;localtion對象
locatoin對象的屬性
replace方法替換當前瀏覽窗口,reload方法刷新瀏覽器窗口
navigator對象
識別瀏覽器的信息
DOM是針對HTML和XML文檔的一個API。DOM描繪了一個層次的節(jié)點樹。節(jié)點層次
NODE類型
每個節(jié)點都有一個nodeType屬性,用于表明節(jié)點的類型。
Node.ELEMENT_NODE(1)
Node.ATTRIBUTE_NODE(2)
Node.TEXT_NODE(3)
Node.CDATA_SECTION_NODE(4)
Node.ENTITY_REFERENCE_NODE(5)
Node.ENTITY_NODE(6)
Node.PROCESSING_INSTRUCTION_NODE(7)
Node.COMMENT_NODE(8)
Node.DOCUMENT_NODE(9)
Node.DOCUMENT_TYPE_NODE(10)
Node.DOCUMENT_FRAGMENT_NODE(11)
Node.NOTATION_NODE(12)
if (someNode.nodeType == 1) { console.log("Node is an element"); }
nodeName和nodeValue屬性
nodeName返回節(jié)點的標簽名,如p,div,span等
nodeValue的值始終是null
節(jié)點關系
操作節(jié)點
appendChild():向childNodes列表的末尾添加一個節(jié)點
insertBefore():向childNodes列表某個特定位置添加一個節(jié)點。該方法接收兩個參數(shù):要插入的節(jié)點和作為參照的節(jié)點,并返回要插入的節(jié)點,如果參照節(jié)點是null,則和appendChild()執(zhí)行相同的操作
replaceChild():替換節(jié)點。接收要插入的節(jié)點和要替換的節(jié)點兩個參數(shù)。要替換的節(jié)點將被返回并從文檔書中被移除。
removeChild():移除節(jié)點。接收一個參數(shù),就是需要移除的節(jié)點
cloneNode():創(chuàng)建調(diào)用這個方法節(jié)點的一個完全相同的副本。接受一個布爾值參數(shù),表示是否執(zhí)行深復制
normalize()
createElement():創(chuàng)建元素
createTextNode():創(chuàng)建文本節(jié)點
createComment():創(chuàng)建注釋節(jié)點
8.DOM拓展 選擇符APIgetElementById()方法:通過id獲取
getElementsByName()方法:通過name屬性,一般使用它獲取表單元素,少用
getElementsByTagName()方法:通過標簽名獲取元素
getElementsByClassName()方法:通過類名獲取元素
querySelector()方法:接收一個CSS選擇符,返回與該模式匹配的第一個元素,沒有則返回null
querySelectorAll()方法:接收一個CSS選擇符,返回一個NodeList實例
macthsSelector()方法:接收一個CSS選擇符,如果調(diào)用元素與該選擇符匹配,返回true否則返回false
9.事件事件流
事件冒泡
IE的事件流叫做事件冒泡,即事件開始由最具體的元素接收,然后逐級向上傳播到較為不具體的節(jié)點
事件捕獲
Netscape的事件流叫事件捕獲,即不太具體的節(jié)點應該更早接收事件,而最具體的節(jié)點應該最后接收事件
DOM事件流
包括三個階段:事件捕獲階段。處于目標階段和事件冒泡階段
事件處理程序
DOM2級時間處理程序
addEventListener
removeEventListener
定義了兩個方法用于處理指定和刪除事件處理程序的操作。所有的DOM節(jié)點中都包含這兩個方法,接受三個參數(shù):事件名、事件處理程序和布爾值。最后這個布爾值如果是true,表示在捕獲階段調(diào)用事件處理程序;false表示在冒泡階段調(diào)用事件處理程序,默認是false。
通過addEventListener()添加的事件處理程序只能使用removeEventListener()來移除。如果通過addEventListener()添加的匿名函數(shù)將無法移除。傳入的函數(shù)要相同,否則無法移除
attachEvent
detachEvent
這兩個方法接受兩個參數(shù):事件名(帶on)和事件處理函數(shù)。
var btn = document.getElementById("myBtn");
var handler = function(){ console.log("clicked") };
btn.attachEvent("onclick", handler);
btn.detachEvent("onclick", handler); // 有效
事件對象
DOM的事件對象
事件類型
UI事件
load:當頁面完全加載后在window上面觸發(fā),img圖片加載完
unload:當頁面完全卸載
abort:當用戶停止下載過程
error:當發(fā)生JavaScript錯誤時在window觸發(fā)
select:當用戶選擇文本框中的一個或者多個觸發(fā)
resize:當窗口大小變化是觸發(fā)
scroll:用戶滾動時觸發(fā)
內(nèi)存和性能
事件委托利用了時間冒泡,指定一個事件處理程序,就可以管理某一個類型的所有事件
HTML5腳本編程
跨文檔消息傳遞
核心方法是postMessage()方法,接受兩個參數(shù):一條消息和一個表示消息接收方來自哪個域的字符串。
// 注意:所有支持XDM的瀏覽器也支持iframe的contentWindow屬性
var iframeWindow = document.getElementById("myframe").contentWindow; iframeWindow.postMessage("A secret", "http://www.wrox.com");
高級技巧
高級函數(shù)
安全的類型檢測
function isArray (value) { return Object.prototype.toString.call(value) === "[object Array]"; } function isFunction (value) { return Object.prototype.toString.call(value) === "[object Function]"; } function isRegExp (value) { return Object.prototype.toString.call(value) === "[object RegExp]"; }
作用域安全的構造函數(shù)
防止this指向window對象
function Person (name, age, job) { if (this instanceof Person) { this.name = name; this.age = age; this.job = job; } else { return new Person(name, age, jon); } } 惰性載入函數(shù) function createXHR(){ if (typeof XMLHttpRequest != "undefined"){ return new XMLHttpRequest(); } else if (typeof ActiveXObject != "undefined"){ if (typeof arguments.callee.activeXString != "string"){ var versions = ["MSXML2.XMLHttp.6.0", "MSXML2.XMLHttp.3.0", "MSXML2.XMLHttp"], i,len; for (i=0,len=versions.length; i < len; i++){ try { new ActiveXObject(versions[i]); arguments.callee.activeXString = versions[i]; break; } catch (ex){ //跳過 } } } return new ActiveXObject(arguments.callee.activeXString); } else { throw new Error("No XHR object available."); } }
第一種實現(xiàn)方法: function createXHR () { if (typeof XMLHttpRequest != "undefined") { createXHR = function () { return new XMLHttpRequest(); }; } else if (typeof ActiveXObjext != "undefined") { createXHR = function () { if (typeof arguments.callee.activeXString != "string") { var versions = ["MSXML2.XMLHttp.6.0", "MSXML2.XMLHttp.3.0", "MSXML2.XMLHttp"], i,len; for (i = 0, len = versions.length; i < len; i++) { try { new ActiveXObject(versions[i]); arguments.callee.activeXString = versions[i]; break; } catch (e) { // skip } } } return new ActiveXObject(arguments.callee.activeXString); }; } else { createXHR = function () { throw new Error("No XHR object available."); } } return createXHR(); } 第二種改法: var createXHR = (function () { if (typeof XMLHttpRequest != "undefined") { return function () { return new XMLHttpRequest(); }; } else if (typeof ActiveXObjext != "undefined") { return function () { if (typeof arguments.callee.activeXString != "string") { var versions = ["MSXML2.XMLHttp.6.0", "MSXML2.XMLHttp.3.0", "MSXML2.XMLHttp"], i,len; for (i = 0, len = versions.length; i < len; i++) { try { new ActiveXObject(versions[i]); arguments.callee.activeXString = versions[i]; break; } catch (e) { // skip } } } return new ActiveXObject(arguments.callee.activeXString); }; } else { return function () { throw new Error("No XHR object available."); } } })();
函數(shù)綁定
bind函數(shù): function bind (fn, context) { return function () { fn.call(context, arguments) } }
函數(shù)柯里化 function curry (fn) { var args = Array.prototype.slice.call(arguments, 1); return function () { var innerArgs = Array.prototype.slice.call(arguments) var finalArgs = args.concat(innerArgs) return fn.apply(null, finalArgs); } } function bind (fn, context) { var args = Array.prototype.slice.call(arguments, 2); return function () { var innerArgs = Array.prototype.slice.call(arguments) var finalArgs = args.concat(innerArgs) return fn.apply(context, finalArgs); } }
文章版權歸作者所有,未經(jīng)允許請勿轉(zhuǎn)載,若此文章存在違規(guī)行為,您可以聯(lián)系管理員刪除。
轉(zhuǎn)載請注明本文地址:http://specialneedsforspecialkids.com/yun/106478.html
摘要:接下來的文章更新以紅寶書章節(jié)更新,內(nèi)容過多分若干篇文章來寫,標題會清晰表明是哪一章節(jié),大家一起學習進步,謝謝大家的支持 1.函數(shù)參數(shù)的特性: function doAdd(num1, num2) { arguments[1] = 10; alert(arguments[0] + num2); } arguments對象中的值會自動反映到對應的命名參數(shù),所以修改 argu...
摘要:函數(shù)實際上是對象。所以需要消除這種緊耦合。函數(shù)內(nèi)部屬性引用的是函數(shù)據(jù)以執(zhí)行的環(huán)境對象或者也可以說是值函數(shù)的名字僅僅是一個包含指針的變量而已。因此,即使是在不同的環(huán)境中執(zhí)行,全局的函數(shù)與函數(shù)指向的仍然是同一個函數(shù)。 1.函數(shù)實際上是對象。每個函數(shù)都是 Function 類型的實例,而且都與其他引用類型一樣具有屬性和方法 2.由于函數(shù)名僅僅是指向函數(shù)的指針,因此函數(shù)名與包含對象指針的其他變...
摘要:在操作對象時,實際上是在操作對象的引用而不是實際的對象。為此,引用類型的值是按引用訪問的。標記清除是目前主流的垃圾收集算法,這種算法的思想是給當前不使用的值加上標記,然后再回收其內(nèi)存 1.在操作對象時,實際上是在操作對象的引用而不是實際的對象。為此,引用類型的值是按引用訪問的。 2.當從一個變量向另一個變量復制引用類型的值時,兩個變量實際上將引用同一個對象,因此,改變其中一個變量,就會...
摘要:與相乘,結(jié)果為與非數(shù)值相乘,結(jié)果為或者除以,結(jié)果為除以,結(jié)果為如果是非零的有限數(shù)被零除,則結(jié)果是或總的來說,得出的結(jié)果為不可預測的基本都為任何操作數(shù)與進行關系比較,結(jié)果都是。實際開發(fā)不建議使用語句,會造成調(diào)試的困難增加 1.負數(shù)二進制存儲使用的格式是二進制補碼,計算一個數(shù)值的二進制補碼步驟如下: (1)取該值的絕對值的二進制(2)取反碼(3)反碼+1,從而得出補碼 2.位操作: (...
閱讀 1354·2021-09-10 10:51
閱讀 2829·2019-08-30 15:54
閱讀 3367·2019-08-29 17:11
閱讀 926·2019-08-29 16:44
閱讀 1391·2019-08-29 13:47
閱讀 1086·2019-08-29 13:47
閱讀 1485·2019-08-29 12:23
閱讀 1038·2019-08-28 18:18