JavaScript高級(jí)程序設(shè)計(jì)(第三版)學(xué)習(xí)筆記6、7章
第6章,面向?qū)ο蟮某绦蛟O(shè)計(jì)
對(duì)象:
1、數(shù)據(jù)屬性
configurable,表示能否通過delete刪除屬性從而重新定義屬性,能否修改屬性的特性,或能否把屬性修改為訪問器屬性,默認(rèn)為true
enumerbale,表示能否通過for-in訪問屬性,默認(rèn)true
writable,表示能否修改屬性值,默認(rèn)true
value,數(shù)據(jù)存儲(chǔ)位置,默認(rèn)undefined
修改默認(rèn)屬性特性:Object.defineProperty(),接收三個(gè)參數(shù):屬性所在對(duì)象,屬性名,描述符對(duì)象,描述符對(duì)象屬性必須是:configurable、enumerable、writable、value
例:
var obj = {};
Object.defineProperty(obj,”name”,{
writable:true,
value:”nihao”
});
2、訪問器屬性
configurable,表示能否通過delete刪除屬性從而重新定義屬性,能否修改屬性的特性,或能否把屬性修改為訪問器屬性,默認(rèn)為true
enumerbale,表示能否通過for-in訪問屬性,默認(rèn)true
get,讀取屬性時(shí)調(diào)用,默認(rèn)undefined
set,寫入屬性時(shí)調(diào)用,默認(rèn)undefined
修改必須通過Object.defineProperty()
例:
var obj = {
_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;
alert(book.edition); //2
定義多個(gè)屬性:Object.defineProperties(),接收兩個(gè)對(duì)象,一是要修改和添加屬性的兌現(xiàn),第二個(gè)對(duì)象屬性與第一個(gè)對(duì)象要修改或添加的屬性一一對(duì)應(yīng),支持的瀏覽器:IE9+,F(xiàn)ireFox4+,Safari5+,Opera12+,chrome
讀取屬性:Object.getOwnPropertyDescriptor(),接收兩個(gè)參數(shù),屬性所在對(duì)象,要讀取描述符的屬性名稱,支持的瀏覽器:IE9+,F(xiàn)ireFox4+,Safari5+,Opera12+,chrome
創(chuàng)建對(duì)象:
工廠模式:
function createPerson(name,age){
var o = new Object();
o.name = name;
o.age = age;
o.sayName = function(){
alert(this.name);
};
return o;
}
var person1 = createPerson(“g”,29);
構(gòu)造函數(shù)模式:
function Person(name,age){
this.name = name;
this.age = age;
this.sayName() = function(){
alert(this.name);
};
}
var person = new Person(“g”,28);
兩種模式區(qū)別:
構(gòu)造函數(shù)模式中不需要顯示創(chuàng)建對(duì)象,對(duì)this直接賦值,沒有返回語句
構(gòu)造函數(shù)名首字母必須大寫,必須使用new操作符創(chuàng)建新實(shí)例
原型模式
創(chuàng)建的每個(gè)函數(shù)都有一個(gè)prototype(原型)屬性,這個(gè)屬性是一個(gè)指針,指向一個(gè)對(duì)象,這個(gè)對(duì)象的用途是包含可以由特定類型的所有實(shí)例共享的屬性和方法,換句話就是,prototype就是通過函數(shù)創(chuàng)建的對(duì)象的原型對(duì)象,好處在于可以是所有實(shí)例共享相同的屬性和方法。
isPrototypeOf(),個(gè)人理解就是可以用以判斷某個(gè)實(shí)例的原型是否與當(dāng)前原型相同
例:
Person.prototype.isPrototypeOf(person1); //true
Object.getPrototypeOf(),可以返回某個(gè)實(shí)例的原型,支持的瀏覽器IE9+,F(xiàn)irefox3.5+,Safari5+,Opera12+,chrome
注:訪問對(duì)象屬性名時(shí)會(huì)進(jìn)行一次搜索,先在實(shí)例對(duì)象搜索,不存在則到當(dāng)前對(duì)象的原型對(duì)象去搜索。
注:實(shí)例中的屬性若與原型對(duì)象中的屬性一樣,則會(huì)屏蔽原型對(duì)象的屬性,與上一條剛好可以對(duì)的上
hasOwnProperty()方法可以確定某個(gè)屬性是否來自實(shí)例,不是來自實(shí)例,則返回false,否則返回true
在實(shí)例上調(diào)用delete時(shí),只會(huì)刪除實(shí)例上的屬性名,并不會(huì)刪除原型的屬性
例:
function Person(){
}
Person.prototype.name = "Nicholas";
Person.prototype.age = 29;
Person.prototype.sayName = function(){
alert(this.name);
}
var per1 = new Person();
var per2 = new Person();
per1.name = "Greg";
alert(per1.name); //"Greg" 來自實(shí)例
alert(per2.name); //"Nicholas"
delete per1.name;
alert(per1.name); //"Nicholas" 來自原型
delete per1.name;
alert(per1.name); //"Nicholas"
注:Object.getOwnPropertyDescriptor()方法只能用于實(shí)例屬性,要取得原型屬性描述符,必須直接在原型對(duì)象上調(diào)用本方法
in操作符:只有當(dāng)屬性在實(shí)例對(duì)象中或者在原型對(duì)象中時(shí),返回true
例:
alert(“name” in Person); //true alert(“name” in per1); //true
同時(shí)使用in和hasOwnProperty可以確定該屬性是存在原型中,還是實(shí)例中
Object.keys()方法:接收一個(gè)對(duì)象作為參數(shù),返回所有可枚舉的屬性組成的字符串?dāng)?shù)組
Object.getOwnPropertyNames()方法:接收一個(gè)對(duì)象,返回所有屬性組成的字符串?dāng)?shù)組,無論是否可枚舉
更簡(jiǎn)單的原型語法:
使用上述方法實(shí)在太麻煩了,更經(jīng)常使用的是以下方法:使用對(duì)象字面量
Person.prototype = {
name : “Nicholas”,
age : 29
sayName = function(){
alert(this.name);
}
}
不過,此方法,相當(dāng)于重寫了整個(gè)prototype對(duì)象,將導(dǎo)致constructor屬性不再指向Person而是指向Object,雖然instanceof還是會(huì)返回正確的結(jié)果,但通過constructor已經(jīng)不能確定對(duì)象類型了。
var per = new Person(); alert(per instanceof Object); //true alert(per instanceof Person); //true alert(per constructor Object); //true alert(per constructor Person); //false
若constructor真的很重要,可以如下設(shè)置
Person.prototype = {
constructor:Person,
name : “Nicholas”,
age : 29
sayName = function(){
alert(this.name);
}
}
以上寫法會(huì)使constructor的enumerable特性被設(shè)置為true,默認(rèn)情況下原生的是false的,在兼容ECMAScript5的瀏覽器可以使用Object.defineProperty()進(jìn)行設(shè)置
Object.defineProperty(Person.prototype,”constructor”,{
enumerable:false,
value:Person
});
注:重寫原型對(duì)象,將會(huì)切斷現(xiàn)有原型與任何之前已經(jīng)存在的對(duì)象實(shí)例之間的聯(lián)系
繼承(難度較大,需再仔細(xì)研究)
使用原型鏈來實(shí)現(xiàn)
子類型要覆蓋超類的方法,應(yīng)該將給原型添加方法的代碼放在替換原型之后,
注:通過原型鏈實(shí)現(xiàn)繼承時(shí),不能使用對(duì)象字面量創(chuàng)建原型方法,否則會(huì)重寫原型鏈
借用構(gòu)造函數(shù)
組合繼承
原型式繼承,Object.creat();接收兩個(gè)參數(shù):一是用作新對(duì)象原型的對(duì)象和(可選的)一個(gè)為新對(duì)象定義額外屬性的對(duì)象
例:Object.creat(person,{name:{value:”greg”}});
寄生式繼承
寄生組合式繼承
第7章,函數(shù)表達(dá)式
創(chuàng)建方式:
1、函數(shù)聲明,可以函數(shù)聲明提升,就是可以把使用函數(shù)的語句放在函數(shù)聲明之前
function funName(arg0,arg1){
//函數(shù)體
}
2、函數(shù)表達(dá)式,不能進(jìn)行函數(shù)提升,也就是無法在函數(shù)創(chuàng)建前使用函數(shù),在這種情況下創(chuàng)建的函數(shù)稱為匿名函數(shù),有時(shí)也叫拉姆達(dá)函數(shù)
var funName = function(arg0,arg1){
//函數(shù)體
}
嚴(yán)格模式下無法使用arguments.callee來實(shí)現(xiàn)遞歸,可以使用如下方式實(shí)現(xiàn)遞歸:
var factorial = (function f(num){
if(num <= 1){
return 1;
}else{
return num * f(num - 1);
}
});
閉包(難度也不?。?/strong>
閉包指有權(quán)訪問另一個(gè)函數(shù)作用域中的變量的函數(shù),閉包,也是一個(gè)函數(shù)
創(chuàng)建閉包的常見方式是在一個(gè)函數(shù)內(nèi)部創(chuàng)建另一個(gè)函數(shù)
閉包只能取得包含函數(shù)即外部函數(shù)中任何變量的最后一個(gè)值。下例可以清晰說明問題
例:
function createFuncrions(){
var result = new Array();
for(var i = 0;i < 10;i++){
result[i] = function(){
return i;
}
}
return result;
}
var re = createFuncrions();
alert(re[1](2));
每個(gè)函數(shù)返回的都將是10,而不是如預(yù)期般返回對(duì)應(yīng)的索引值,因?yàn)閏reateFuncrions函數(shù)最后返回時(shí)I = 10,此時(shí)每個(gè)函數(shù)都引用保存著變量i的同一個(gè)對(duì)象,所以在每個(gè)函數(shù)內(nèi)部i都是10,可以使用如下方法強(qiáng)制閉包返回預(yù)期效果:
function createFuncrions(){
var result = new Array();
for(var i = 0;i < 10;i++){
result[i] = function(num){
return function(){
return num;
};
}(i);
}
return result;
}
var re = createFuncrions();
alert(re[2]());
每一個(gè)都會(huì)返回各自的索引值
模仿塊級(jí)作用域
使用匿名函數(shù)可以模仿塊級(jí)作用域:
(function(){
alert("test"); //塊級(jí)作用域,沒有使用圓括號(hào)將function包起來將會(huì)出錯(cuò)
})();
使用閉包和私有變量的明顯不足之處在于,會(huì)在作用域鏈中多查找一個(gè)層次,在一定程度上影響查找速度
函數(shù)中定義的變量可以在一定程度上稱為私有變量,通過函數(shù)可以模擬出私有變量,靜態(tài)私有變量
增強(qiáng)模塊模式:
var singleton = function(){
//private arg and private method
var privateVariable = 10;
function privateFunction(){
return false;
}
//create obj
var obj = new Object();
obj.publicProperty = true;
obj.publicFunction = function(){
privateVariable ++;
return privateFunction();
};
return obj;
}();
alert(typeof singleton);
alert(singleton.publicProperty);
alert(singleton.publicFunction());
以上內(nèi)容是小編給大家介紹的JavaScript高級(jí)程序設(shè)計(jì)(第三版)學(xué)習(xí)筆記6、7章,希望對(duì)大家有所幫助!
- JavaScript高級(jí)程序設(shè)計(jì) DOM學(xué)習(xí)筆記
- JavaScript高級(jí)程序設(shè)計(jì) XML、Ajax 學(xué)習(xí)筆記
- JavaScript高級(jí)程序設(shè)計(jì) 事件學(xué)習(xí)筆記
- JavaScript高級(jí)程序設(shè)計(jì)(第3版)學(xué)習(xí)筆記 概述
- JavaScript高級(jí)程序設(shè)計(jì)(第3版)學(xué)習(xí)筆記2 js基礎(chǔ)語法
- JavaScript高級(jí)程序設(shè)計(jì)(第3版)學(xué)習(xí)筆記3 js簡(jiǎn)單數(shù)據(jù)類型
相關(guān)文章
javascript排序函數(shù)實(shí)現(xiàn)數(shù)字排序
這篇文章主要介紹了javascript排序函數(shù)實(shí)現(xiàn)數(shù)字排序的相關(guān)資料,附上示例,需要的朋友可以參考下2015-06-06
淺談js控制li標(biāo)簽排序問題 js調(diào)用php函數(shù)的方法
下面小編就為大家?guī)硪黄獪\談js控制li標(biāo)簽排序問題 js調(diào)用php函數(shù)的方法。小編覺得挺不錯(cuò)的,現(xiàn)在就分享給大家,也給大家做個(gè)參考。一起跟隨小編過來看看吧2016-10-10
Bootstrap Table服務(wù)器分頁與在線編輯應(yīng)用總結(jié)
這篇文章主要介紹了Bootstrap Table服務(wù)器分頁與在線編輯應(yīng)用總結(jié) 的相關(guān)資料,非常不錯(cuò),具有參考借鑒價(jià)值,需要的朋友可以參考下2016-08-08
JS的鼠標(biāo)監(jiān)聽mouseup鼠標(biāo)抬起失效原因及解決
這篇文章主要為大家介紹了JS的鼠標(biāo)監(jiān)聽mouseup鼠標(biāo)抬起失效原因及解決示例,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪2023-05-05
詳解如何準(zhǔn)確判斷JavaScript中的數(shù)據(jù)類型
JavaScript中,我們經(jīng)常需要判斷數(shù)據(jù)類型以便于正確地處理數(shù)據(jù),本文將介紹JavaScript中的數(shù)據(jù)類型判斷技術(shù),包括typeof操作符、instanceof操作符、Object.prototype.toString方法以及ES6新增的一些數(shù)據(jù)類型判斷方法,需要的朋友可以參考下2023-08-08
uniapp 仿微信的右邊下拉選擇彈出框的實(shí)現(xiàn)代碼
這篇文章主要介紹了uniapp 仿微信的右邊下拉選擇彈出框的實(shí)現(xiàn)代碼,文中通過示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧2020-07-07
《JavaScript DOM 編程藝術(shù)》讀書筆記之JavaScript 圖片庫
這篇文章主要介紹了《JavaScript DOM 編程藝術(shù)》讀書筆記之JavaScript 圖片庫,需要的朋友可以參考下2015-01-01

