亚洲中字慕日产2020,大陆极品少妇内射AAAAAA,无码av大香线蕉伊人久久,久久精品国产亚洲av麻豆网站

資訊專欄INFORMATION COLUMN

紅寶書筆記

Tonny / 1839人閱讀

摘要:紅寶書筆記在中使用加載外部腳本文件,通知瀏覽器立即下載,異步執(zhí)行腳本可以延遲到文檔完全被解析和顯示之后在執(zhí)行瀏覽器不支持腳本。對(duì)數(shù)組中的每一項(xiàng)運(yùn)行給定函數(shù),返回該函數(shù)會(huì)返回的項(xiàng)組成的數(shù)組。

紅寶書筆記 1.在HTML中使用JavaScript

async:加載外部腳本文件,通知瀏覽器立即下載,異步執(zhí)行

defer:腳本可以延遲到文檔完全被解析和顯示之后在執(zhí)行

noscript:
瀏覽器不支持腳本。
瀏覽器支持腳本,但是腳本被禁用

2.變量、作用域和內(nèi)存問題

復(fù)制變量值

復(fù)制基本類型值,這兩個(gè)變量相互獨(dú)立,互不影響。

復(fù)制引用類型(對(duì)象),值引用是一個(gè)指針,改變其中一個(gè)對(duì)象,會(huì)影響另一個(gè)對(duì)象。

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í),這個(gè)變量引用就是一個(gè)局部對(duì)象。而這個(gè)對(duì)象會(huì)在函數(shù)執(zhí)行完畢后立即被銷毀。

檢測類型

使用typeof檢測基本數(shù)據(jù)類型,但是在檢測引用類型的值是,這個(gè)操作符的用處不大,因?yàn)槭褂胻ypeof無法知道它是什么類型的對(duì)象。為此,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語句

垃圾回收

標(biāo)記清除

垃圾收集器在運(yùn)行的時(shí)候會(huì)給存儲(chǔ)在內(nèi)存中的所有變量都加上標(biāo)記

引用計(jì)數(shù)

當(dāng)它們被賦值為指向某個(gè)對(duì)象時(shí),要給它們?cè)境钟械囊盟赶虻膶?duì)象的引用計(jì)數(shù)減1,然后給它們新指向的對(duì)象的引用計(jì)數(shù)加1。當(dāng)它們的生命期結(jié)束的時(shí)候,要給它們所指向的對(duì)象的引用計(jì)數(shù)減1,當(dāng)引用計(jì)數(shù)為0時(shí),則可以將其占用的內(nèi)存空間進(jìn)行回收

3.引用類型 Array類型

檢測數(shù)組

value instanceof Array
Array.isArray(value)

棧方法(后進(jìn)先出)

push:將參數(shù)逐個(gè)添加到數(shù)據(jù)末尾

pop:從數(shù)組末尾移除最后一項(xiàng)

隊(duì)列方法(先進(jìn)先出)

shift:刪除數(shù)組的第一項(xiàng)并返回該項(xiàng)

unshift:向數(shù)組前添加任意個(gè)項(xiàng)并返回新數(shù)組的長度

重排序方法

reverse:反轉(zhuǎn)數(shù)組

sort:按升序排列數(shù)組

操作方法

concat:將參數(shù)添加到數(shù)組的末尾,并返回新的數(shù)組

slice:基于當(dāng)前數(shù)組中的一或多個(gè)項(xiàng)創(chuàng)建一個(gè)新數(shù)組,slice()方法可以接受一或者兩個(gè)參數(shù),即要返回項(xiàng)的起始和結(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ù)組,能夠刪除、插入和替換多個(gè)項(xiàng)

var colors = ["red", "green", "blue"];
var removed = colors.splice(0,1); // 刪除第一項(xiàng)
alert(colors); // green,blue
alert(removed); // red,返回的數(shù)組中只包含一項(xiàng)
removed = colors.splice(1, 0, "yellow", "orange"); // 從位置1 開始插入兩項(xiàng)
alert(colors); // green,yellow,orange,blue
alert(removed); // 返回的是一個(gè)空數(shù)組
removed = colors.splice(1, 1, "red", "purple"); // 插入兩項(xiàng),刪除一項(xiàng)
alert(colors); // green,red,purple,orange,blue
alert(removed); // yellow,返回的數(shù)組中只包含一項(xiàng)

位置方法

indexOf:從數(shù)組開頭開始向后查找位置

lastIndexOf:從數(shù)組末尾開始向前查找

迭代方法

every(): 對(duì)數(shù)組中的每一項(xiàng)運(yùn)行給定函數(shù),如果該函數(shù)對(duì)每一項(xiàng)都返回true,則返回true。

filter(): 對(duì)數(shù)組中的每一項(xiàng)運(yùn)行給定函數(shù),返回該函數(shù)會(huì)返回true 的項(xiàng)組成的數(shù)組。

forEach(): 對(duì)數(shù)組中的每一項(xiàng)運(yùn)行給定函數(shù)。這個(gè)方法沒有返回值。

map(): 對(duì)數(shù)組中的每一項(xiàng)運(yùn)行給定函數(shù),返回每次函數(shù)調(diào)用的結(jié)果組成的數(shù)組。

some(): 對(duì)數(shù)組中的每一項(xiàng)運(yùn)行給定函數(shù),如果該函數(shù)對(duì)任一項(xiàng)返回true,則返回true。

縮小方法

reduce():遍歷數(shù)組所有項(xiàng),并返回最終的值,從第一項(xiàng)開始,逐個(gè)遍歷到最后

reduceRight():從最后一項(xiàng)開始,逐個(gè)遍歷到第一項(xiàng)

var values = [1, 2, 3, 4, 5];
var sum = values.reduce((prev, cur, index, array) => {
    return prev + cur;
});
console.log(sum); // 15
Function類型

函數(shù)內(nèi)部屬性

函數(shù)內(nèi)部有兩個(gè)特殊的對(duì)象:argumens和this

屬性和方法

每個(gè)函數(shù)都包含兩個(gè)屬性

length: 表示函數(shù)希望接收的命名參數(shù)的個(gè)數(shù)

prototype: 保存實(shí)例方法

每個(gè)函數(shù)都包含兩個(gè)非繼承而來的方法

call()和apply()這兩個(gè)方法的用途都是在特定的作用域中調(diào)用函數(shù),實(shí)際上等于設(shè)置函數(shù)體內(nèi)this對(duì)象的值

apply()接收兩個(gè)參數(shù):一個(gè)是在其中運(yùn)行的函數(shù)作用域,另一個(gè)是參數(shù)數(shù)組

call()接收的參數(shù),第一個(gè)參數(shù)是this值沒有變化,變化的是其余參數(shù)都直接傳遞給函數(shù)

bind()方法會(huì)創(chuàng)建一個(gè)實(shí)例,其this值會(huì)被綁定到傳給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)置對(duì)象

Global對(duì)象

encodeURI()和encodeURIComponet()方法可以對(duì)URI進(jìn)行編碼,以便發(fā)送給瀏覽器

encodeURI()編碼后的結(jié)果是除了空格之外的其他字符都原封不動(dòng),只有空格被替換成了%20,對(duì)應(yīng)decodeURI()方法

encodeURIComponet()方法則會(huì)使用對(duì)應(yīng)的編碼替換所有非字母數(shù)字字符,這也正式可以對(duì)整個(gè)URL使用encodeURI(),而只能對(duì)附加在現(xiàn)有URL后面的字符串使用encodeURIComponet()的原因所在。對(duì)應(yīng)decodeURIComponet()方法

4.面向?qū)ο蟮某绦蛟O(shè)計(jì) 理解對(duì)象

屬性類型

ECMAScript中有兩種屬性:數(shù)據(jù)屬性和訪問器屬性

數(shù)據(jù)屬性

[[Configurable]]:表示能否通過delete刪除屬性從而重新定義屬性,能否修改屬性的特性,或者能否把屬性修改為訪問器屬性,默認(rèn)值為true

[[Enumerable]]:表示能否通過for-in循環(huán)返回屬性。默認(rèn)值為true

[[Writable]]:表示能否修改屬性的值。默認(rèn)值為true

[[Value]]:包含這個(gè)屬性的數(shù)據(jù)值,默認(rèn)值為undefined

要修改屬性默認(rèn)的特性,必須使用Object.defineProperty()方法。這個(gè)方法接收三個(gè)參數(shù):屬性所在對(duì)象、屬性的名字和一個(gè)描述符對(duì)象。其中,描述符對(duì)象的屬性必須是:configurabel、enumerable、writable、和value。設(shè)置其中的一個(gè)或多個(gè)值。
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()方法會(huì)對(duì)configurable為false的屬性修改做限制

訪問器屬性

[[Configurable]]:表示能否通過delete刪除屬性從而重新定義屬性,能否修改屬性的特性,或者能否把屬性修改為數(shù)據(jù)屬性。默認(rèn)值為true

[[Enumerable]]:表示能否通過for-in循環(huán)返回屬性。默認(rèn)值為true

[[Get]]:在讀取屬性時(shí)調(diào)用的函數(shù)。默認(rèn)值為undefined

[[Set]]:在寫入屬性時(shí)調(diào)用的函數(shù)。默認(rèn)值為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

定義多個(gè)屬性

ECMAScript5定義了一個(gè)Object.defineProperties()方法。利用這個(gè)方法可以通過描述符一次定義多個(gè)屬性。這個(gè)方法接收兩個(gè)對(duì)象參數(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)建對(duì)象

工廠模式

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");

構(gòu)造函數(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");

原型模式

理解原型對(duì)象

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();

在默認(rèn)情況下,所有原型對(duì)象都會(huì)自動(dòng)獲得一個(gè)constructor(構(gòu)造函數(shù))屬性,這個(gè)屬性包含一個(gè)指向一個(gè)prototype屬性所在函數(shù)的指針。例如,Person.prototype.constructor指向Person

我們可以通過isPrototypeof()方法來確定對(duì)象之間是否存在原型關(guān)系。從本質(zhì)上講,如果[[Prototype]]指向調(diào)用isPrototypeof()方法的對(duì)象(Person.prototye),那么這個(gè)方法就返回true。

console.log(Person.prototype.isPrototypeOf(person1)); // true
console.log(Person.prototype.isPrototypeOf(person2)); // true

ECMAScript5增加了一個(gè)新方法,叫Object.getPrototypeOf(),在所有支持的實(shí)現(xiàn)中,這個(gè)方法返回[[Prototype]]的值。例如:

console.log(Object.getPrototypeOf(person1) === Person.prototype); // true

雖然可以通過對(duì)象實(shí)例訪問保存在原型中的值,但卻不能通過對(duì)象實(shí)例重寫原型中的值。如果我們?cè)趯?shí)例中添加了一個(gè)屬性,而該屬性與實(shí)例原型中的一個(gè)屬性同名,那我們就在實(shí)例中創(chuàng)建該屬性,該屬性將會(huì)屏蔽原型中的那個(gè)屬性。

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" — 來自實(shí)例
delete person1.name;
console.log(person1.name); //"Nicholas" — 來自原型

通過delete操作符刪除實(shí)例的屬性,就恢復(fù)了對(duì)原型中name屬性的連接。因此接下來再調(diào)用person1.name是,就返回了原型中name屬性的值了。
Object.hasOwnProperty()方法可以檢測一個(gè)屬性是否存在于實(shí)例中,還是存在于原型中。

原型與in操作符

in操作符只要通過對(duì)象能夠訪問到屬性就返回true,Object.hasOwnProperty()只在屬性存在于實(shí)例中才返回true,因此只要in操作符返回true而Object.hasOwnProperty()返回false,就可以確定屬性是原型中的屬性。

function hasPrototypeProperty (object, name) {
    if (name in object) {
         return object.hasOwnProperty(name) // true:屬性在實(shí)例中,false:屬性在對(duì)象中
    } else {
        console.log("沒有該屬性");
    }
}

要取得對(duì)象上所有可枚舉的實(shí)例屬性,可以使用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設(shè)置為一個(gè)新的對(duì)象,本質(zhì)上是完全重寫了默認(rèn)的prototype對(duì)象。但是這樣有一個(gè)例外,constructor屬性不再指向Person了,而是指向Object。所以我們需要將他的constructor屬性設(shè)置成Person

function Person () {}
Person.prototype = {
    constructor: Person,
    name: "Nicholas",
    age: 29,
    job: "Software Engineer",
    sayName: function () {
        console.log(this.name);
    }
}

但是這種方式重設(shè)constructor屬性會(huì)導(dǎo)致它的[[Enumerable]]的特性被設(shè)置為true,默認(rèn)情況下,原生的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
});

原型的動(dòng)態(tài)性

重寫整個(gè)原型對(duì)象會(huì)切斷構(gòu)造函數(shù)與最初原型之間的聯(lián)系。記住:實(shí)例中的指針僅指向原型,而不指向構(gòu)造函數(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

原生對(duì)象的原型

原型模式的重要性不僅體現(xiàn)在創(chuàng)建自定義類型方面,就連所有的原生的引用類型,都是采用這種模式創(chuàng)建的。所有原生引用類型(Object、Array、String,等等)都在其構(gòu)造函數(shù)的原型上定義了方法。

原型對(duì)象的問題
原型模式的所有實(shí)例在默認(rèn)情況下都將取得相同的屬性值,最大的問題是其共享的本性所導(dǎo)致的。

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"]

組合使用構(gòu)造函數(shù)和原型模式

創(chuàng)建自定義類型的最常見的方式,構(gòu)造函數(shù)模式用于定義實(shí)例屬性,而原型模式用于定義方法和共享的屬性。

每個(gè)實(shí)例都會(huì)有自己的一份實(shí)例屬性的副本,但同事又共享著對(duì)方法的引用,最大的節(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"]

動(dòng)態(tài)原型模式
通過在構(gòu)造函數(shù)中初始化原型(僅在必要的情況下),又保持同時(shí)使用構(gòu)造函數(shù)和原型模式的優(yōu)點(diǎn)。換句話說,可以通過檢查某個(gè)應(yīng)該存在的方法是否有效,來決定是否需要初始化原型。

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);
        };
    }
}
繼承

原型鏈

構(gòu)造函數(shù)、原型和實(shí)例的關(guān)系:每個(gè)構(gòu)造函數(shù)都有一個(gè)原型對(duì)象,原型對(duì)象都包含一個(gè)指向構(gòu)造函數(shù)的指針,而實(shí)例都包含一個(gè)指向原型對(duì)象的內(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

別忘記默認(rèn)原型

所用引用類型默認(rèn)都繼承Object,而這個(gè)繼承也是通過原型鏈實(shí)現(xiàn)的。所有函數(shù)的默認(rèn)原型都是Object的實(shí)例,因此默認(rèn)原型都會(huì)包含一個(gè)內(nèi)部指針,指向Object.prototype。

確定原型與實(shí)例的關(guān)系

instanceof操作符

console.log(instance instanceof Object); // true
console.log(instance instanceof SuperType); // true
console.log(instance instanceof SubType); // true

isPrototypeOf()方法,只要是原型鏈中出現(xiàn)過的原型,都可以說是該原型鏈所派生的實(shí)例的原型

console.log(Object.isPrototypeOf(instance)); // true
console.log(SuperType.isPrototypeOf(instance)); // true
console.log(SubType.isPrototypeOf(instance)); // true

謹(jǐn)慎的定義方法

子類型有時(shí)需要重寫超類型中的某個(gè)方法,或者需要添加超類型中不存在的某個(gè)方法。但不管怎樣,給原型添加方法的代碼一定要放在替換原型語句之后。

原型鏈的問題

通過原型來實(shí)現(xiàn)繼承時(shí),原型實(shí)際上會(huì)變成另一個(gè)類型的實(shí)例,包含引用類型值的原型屬性會(huì)被所有實(shí)例共享。

在創(chuàng)建子類型的實(shí)例時(shí),不能向超類型的構(gòu)造函數(shù)中傳遞參數(shù)。

借用構(gòu)造函數(shù)

在解決原型中包含引用類型值所帶來問題的過程中,開始使用借用構(gòu)造函數(shù)的技術(shù)。即在子類型構(gòu)造函數(shù)的內(nèi)部調(diào)用超類型構(gòu)造函數(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ù)

相對(duì)于原型鏈而言,借用構(gòu)造函數(shù)有一個(gè)很大的優(yōu)勢,既可以在子類型構(gòu)造函數(shù)中向超類型構(gòu)造函數(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

借用構(gòu)造函數(shù)的問題

方法都在構(gòu)造函數(shù)中定義,因?yàn)楹瘮?shù)復(fù)用就無從談起

組合繼承

既能通過在原型上定義方法實(shí)現(xiàn)了函數(shù)復(fù)用,又能保證每個(gè)實(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(); // 27
5.函數(shù)表達(dá)式
定義函數(shù)的方式有兩種:一種是函數(shù)聲明,另一種是函數(shù)表達(dá)式。
函數(shù)聲明的特征是函數(shù)聲明提升,意思是在執(zhí)行代碼之前會(huì)先讀取函數(shù)聲明。
閉包

函數(shù)作用域鏈

當(dāng)某個(gè)函數(shù)第一次被調(diào)用時(shí),會(huì)創(chuàng)建一個(gè)執(zhí)行環(huán)境及相應(yīng)的作用域鏈,并把作用域鏈賦值給一個(gè)特殊的內(nèi)部屬性(即[[Scope]])。然后,使用this.arguments和其他命名參數(shù)的值來初始化函數(shù)的活動(dòng)對(duì)象。但在作用域鏈中,外部函數(shù)的活動(dòng)對(duì)象始終處于第二位,外部函數(shù)的外部函數(shù)的活動(dòng)對(duì)象始終處于第三位,......直至作為作用域鏈終點(diǎn)的全局執(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;
}

關(guān)于this對(duì)象

this對(duì)象是在運(yùn)行中基于函數(shù)的執(zhí)行環(huán)境綁定的:在全局函數(shù)中,this等于window,而當(dāng)函數(shù)被作為某個(gè)對(duì)象的方法調(diào)用時(shí),this等于那個(gè)對(duì)象。不過匿名函數(shù)的執(zhí)行環(huán)境具有全局性,因此其this對(duì)象通常指向window。當(dāng)然,再通過call()和apply()改變執(zhí)行函數(shù)執(zhí)行環(huán)境的情況下,this就會(huì)指向其他對(duì)象

var name = "The Window";
var object = {
    name: "My Object",
    getNameFunc: function () {
        return function () {
            return this.name
        }
    }
}
console.log(object.getNameFunc()()); // "The Window"

模仿塊級(jí)作用域

匿名函數(shù)可以用來模仿塊級(jí)作用域并避免這個(gè)問題。用塊級(jí)作用域(通常稱為私有作用域)的匿名函數(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"

以上代碼的構(gòu)造函數(shù)中定義了兩個(gè)特權(quán)方法:getName()和setName()。這兩個(gè)方法都可以在構(gòu)造函數(shù)外部使用,而且都有權(quán)訪問私有變量name。但在Person構(gòu)造函數(shù)外部,沒有任何方法訪問name。由于這兩個(gè)方法是在構(gòu)造函數(shù)內(nèi)部定義的,它們作為閉包能夠通過作用域鏈訪問name。
靜態(tài)私有變量

6.BOM window對(duì)象

全局作用域

拋開全局變量會(huì)成為window對(duì)象的屬性不談,定義全局變量與在window對(duì)象上直接定義屬相還是有一點(diǎn)差別:全局變量不能通過delete屬性操作符刪除,而直接在window對(duì)象上的定義的屬性可以。

var age = 29;
window.color = "red";
delete window.age; // 不會(huì)報(bào)錯(cuò)
delete window.color // 不會(huì)報(bào)錯(cuò) 返回true
var newValue = oldValue; // 會(huì)拋出錯(cuò)誤,因?yàn)閛ldValue未定義
var newValue = window.oldValue; // 不會(huì)報(bào)錯(cuò),因?yàn)檫@是一次屬性查詢

窗口關(guān)系及框架

了解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對(duì)象

locatoin對(duì)象的屬性

replace方法替換當(dāng)前瀏覽窗口,reload方法刷新瀏覽器窗口

navigator對(duì)象
識(shí)別瀏覽器的信息

7.DOM
DOM是針對(duì)HTML和XML文檔的一個(gè)API。DOM描繪了一個(gè)層次的節(jié)點(diǎn)樹。
節(jié)點(diǎn)層次

NODE類型

每個(gè)節(jié)點(diǎn)都有一個(gè)nodeType屬性,用于表明節(jié)點(diǎn)的類型。

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é)點(diǎn)的標(biāo)簽名,如p,div,span等
nodeValue的值始終是null

節(jié)點(diǎn)關(guān)系

操作節(jié)點(diǎn)

appendChild():向childNodes列表的末尾添加一個(gè)節(jié)點(diǎn)

insertBefore():向childNodes列表某個(gè)特定位置添加一個(gè)節(jié)點(diǎn)。該方法接收兩個(gè)參數(shù):要插入的節(jié)點(diǎn)和作為參照的節(jié)點(diǎn),并返回要插入的節(jié)點(diǎn),如果參照節(jié)點(diǎn)是null,則和appendChild()執(zhí)行相同的操作

replaceChild():替換節(jié)點(diǎn)。接收要插入的節(jié)點(diǎn)和要替換的節(jié)點(diǎn)兩個(gè)參數(shù)。要替換的節(jié)點(diǎn)將被返回并從文檔書中被移除。

removeChild():移除節(jié)點(diǎn)。接收一個(gè)參數(shù),就是需要移除的節(jié)點(diǎn)

cloneNode():創(chuàng)建調(diào)用這個(gè)方法節(jié)點(diǎn)的一個(gè)完全相同的副本。接受一個(gè)布爾值參數(shù),表示是否執(zhí)行深復(fù)制

normalize()

createElement():創(chuàng)建元素

createTextNode():創(chuàng)建文本節(jié)點(diǎn)

createComment():創(chuàng)建注釋節(jié)點(diǎn)

8.DOM拓展 選擇符API

getElementById()方法:通過id獲取

getElementsByName()方法:通過name屬性,一般使用它獲取表單元素,少用

getElementsByTagName()方法:通過標(biāo)簽名獲取元素

getElementsByClassName()方法:通過類名獲取元素

querySelector()方法:接收一個(gè)CSS選擇符,返回與該模式匹配的第一個(gè)元素,沒有則返回null

querySelectorAll()方法:接收一個(gè)CSS選擇符,返回一個(gè)NodeList實(shí)例

macthsSelector()方法:接收一個(gè)CSS選擇符,如果調(diào)用元素與該選擇符匹配,返回true否則返回false

9.事件

事件流

事件冒泡
IE的事件流叫做事件冒泡,即事件開始由最具體的元素接收,然后逐級(jí)向上傳播到較為不具體的節(jié)點(diǎn)
事件捕獲
Netscape的事件流叫事件捕獲,即不太具體的節(jié)點(diǎn)應(yīng)該更早接收事件,而最具體的節(jié)點(diǎn)應(yīng)該最后接收事件
DOM事件流
包括三個(gè)階段:事件捕獲階段。處于目標(biāo)階段和事件冒泡階段

事件處理程序

DOM2級(jí)時(shí)間處理程序
addEventListener
removeEventListener
定義了兩個(gè)方法用于處理指定和刪除事件處理程序的操作。所有的DOM節(jié)點(diǎn)中都包含這兩個(gè)方法,接受三個(gè)參數(shù):事件名、事件處理程序和布爾值。最后這個(gè)布爾值如果是true,表示在捕獲階段調(diào)用事件處理程序;false表示在冒泡階段調(diào)用事件處理程序,默認(rèn)是false。
通過addEventListener()添加的事件處理程序只能使用removeEventListener()來移除。如果通過addEventListener()添加的匿名函數(shù)將無法移除。傳入的函數(shù)要相同,否則無法移除
attachEvent
detachEvent
這兩個(gè)方法接受兩個(gè)參數(shù):事件名(帶on)和事件處理函數(shù)。
var btn = document.getElementById("myBtn");
var handler = function(){ console.log("clicked") };
btn.attachEvent("onclick", handler);
btn.detachEvent("onclick", handler); // 有效

事件對(duì)象

DOM的事件對(duì)象

事件類型

UI事件
load:當(dāng)頁面完全加載后在window上面觸發(fā),img圖片加載完
unload:當(dāng)頁面完全卸載
abort:當(dāng)用戶停止下載過程
error:當(dāng)發(fā)生JavaScript錯(cuò)誤時(shí)在window觸發(fā)
select:當(dāng)用戶選擇文本框中的一個(gè)或者多個(gè)觸發(fā)
resize:當(dāng)窗口大小變化是觸發(fā)
scroll:用戶滾動(dòng)時(shí)觸發(fā)

內(nèi)存和性能
事件委托利用了時(shí)間冒泡,指定一個(gè)事件處理程序,就可以管理某一個(gè)類型的所有事件

HTML5腳本編程

跨文檔消息傳遞
核心方法是postMessage()方法,接受兩個(gè)參數(shù):一條消息和一個(gè)表示消息接收方來自哪個(gè)域的字符串。
// 注意:所有支持XDM的瀏覽器也支持iframe的contentWindow屬性

var iframeWindow = document.getElementById("myframe").contentWindow;
iframeWindow.postMessage("A secret", "http://www.wrox.com");

高級(jí)技巧

高級(jí)函數(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]";
}

作用域安全的構(gòu)造函數(shù)
防止this指向window對(duì)象

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.");
    }
}
第一種實(shí)現(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);
    }
}

文章版權(quán)歸作者所有,未經(jīng)允許請(qǐng)勿轉(zhuǎn)載,若此文章存在違規(guī)行為,您可以聯(lián)系管理員刪除。

轉(zhuǎn)載請(qǐng)注明本文地址:http://www.ezyhdfw.cn/yun/106478.html

相關(guān)文章

  • JavaScript寶書筆記(三)---函數(shù)特性

    摘要:接下來的文章更新以紅寶書章節(jié)更新,內(nèi)容過多分若干篇文章來寫,標(biāo)題會(huì)清晰表明是哪一章節(jié),大家一起學(xué)習(xí)進(jìn)步,謝謝大家的支持 1.函數(shù)參數(shù)的特性: function doAdd(num1, num2) { arguments[1] = 10; alert(arguments[0] + num2); } arguments對(duì)象中的值會(huì)自動(dòng)反映到對(duì)應(yīng)的命名參數(shù),所以修改 argu...

    沈建明 評(píng)論0 收藏0
  • JavaScript寶書筆記(七)---Function類型

    摘要:函數(shù)實(shí)際上是對(duì)象。所以需要消除這種緊耦合。函數(shù)內(nèi)部屬性引用的是函數(shù)據(jù)以執(zhí)行的環(huán)境對(duì)象或者也可以說是值函數(shù)的名字僅僅是一個(gè)包含指針的變量而已。因此,即使是在不同的環(huán)境中執(zhí)行,全局的函數(shù)與函數(shù)指向的仍然是同一個(gè)函數(shù)。 1.函數(shù)實(shí)際上是對(duì)象。每個(gè)函數(shù)都是 Function 類型的實(shí)例,而且都與其他引用類型一樣具有屬性和方法 2.由于函數(shù)名僅僅是指向函數(shù)的指針,因此函數(shù)名與包含對(duì)象指針的其他變...

    cyrils 評(píng)論0 收藏0
  • 寶書筆記-第3章-基本概念

    showImg(https://segmentfault.com/img/bVbwbVl?w=1649&h=2769);

    _ivan 評(píng)論0 收藏0
  • JavaScript寶書筆記(四)---變量、作用域和內(nèi)存問題

    摘要:在操作對(duì)象時(shí),實(shí)際上是在操作對(duì)象的引用而不是實(shí)際的對(duì)象。為此,引用類型的值是按引用訪問的。標(biāo)記清除是目前主流的垃圾收集算法,這種算法的思想是給當(dāng)前不使用的值加上標(biāo)記,然后再回收其內(nèi)存 1.在操作對(duì)象時(shí),實(shí)際上是在操作對(duì)象的引用而不是實(shí)際的對(duì)象。為此,引用類型的值是按引用訪問的。 2.當(dāng)從一個(gè)變量向另一個(gè)變量復(fù)制引用類型的值時(shí),兩個(gè)變量實(shí)際上將引用同一個(gè)對(duì)象,因此,改變其中一個(gè)變量,就會(huì)...

    imtianx 評(píng)論0 收藏0
  • JavaScript寶書筆記(二)---操作符及語句

    摘要:與相乘,結(jié)果為與非數(shù)值相乘,結(jié)果為或者除以,結(jié)果為除以,結(jié)果為如果是非零的有限數(shù)被零除,則結(jié)果是或總的來說,得出的結(jié)果為不可預(yù)測的基本都為任何操作數(shù)與進(jìn)行關(guān)系比較,結(jié)果都是。實(shí)際開發(fā)不建議使用語句,會(huì)造成調(diào)試的困難增加 1.負(fù)數(shù)二進(jìn)制存儲(chǔ)使用的格式是二進(jìn)制補(bǔ)碼,計(jì)算一個(gè)數(shù)值的二進(jìn)制補(bǔ)碼步驟如下: (1)取該值的絕對(duì)值的二進(jìn)制(2)取反碼(3)反碼+1,從而得出補(bǔ)碼 2.位操作: (...

    AlphaWatch 評(píng)論0 收藏0
  • 寶書筆記-第5章-引用類型

    showImg(https://segmentfault.com/img/bVbwihz?w=1558&h=6145);

    ZoomQuiet 評(píng)論0 收藏0

發(fā)表評(píng)論

0條評(píng)論

最新活動(dòng)
閱讀需要支付1元查看
<