JavaScript高級(jí)程序設(shè)計(jì)(第三版)學(xué)習(xí)筆記6、7章
第6章,面向?qū)ο蟮某绦蛟O(shè)計(jì)
對(duì)象:
1、數(shù)據(jù)屬性
configurable,表示能否通過(guò)delete刪除屬性從而重新定義屬性,能否修改屬性的特性,或能否把屬性修改為訪問(wèn)器屬性,默認(rèn)為true
enumerbale,表示能否通過(guò)for-in訪問(wèn)屬性,默認(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、訪問(wèn)器屬性
configurable,表示能否通過(guò)delete刪除屬性從而重新定義屬性,能否修改屬性的特性,或能否把屬性修改為訪問(wèn)器屬性,默認(rèn)為true
enumerbale,表示能否通過(guò)for-in訪問(wèn)屬性,默認(rèn)true
get,讀取屬性時(shí)調(diào)用,默認(rèn)undefined
set,寫(xiě)入屬性時(shí)調(diào)用,默認(rèn)undefined
修改必須通過(guò)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ì)象,要讀取描述符的屬性名稱(chēng),支持的瀏覽器: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直接賦值,沒(méi)有返回語(yǔ)句
構(gòu)造函數(shù)名首字母必須大寫(xiě),必須使用new操作符創(chuàng)建新實(shí)例
原型模式
創(chuàng)建的每個(gè)函數(shù)都有一個(gè)prototype(原型)屬性,這個(gè)屬性是一個(gè)指針,指向一個(gè)對(duì)象,這個(gè)對(duì)象的用途是包含可以由特定類(lèi)型的所有實(shí)例共享的屬性和方法,換句話就是,prototype就是通過(guò)函數(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
注:訪問(wèn)對(duì)象屬性名時(shí)會(huì)進(jìn)行一次搜索,先在實(shí)例對(duì)象搜索,不存在則到當(dāng)前對(duì)象的原型對(duì)象去搜索。
注:實(shí)例中的屬性若與原型對(duì)象中的屬性一樣,則會(huì)屏蔽原型對(duì)象的屬性,與上一條剛好可以對(duì)的上
hasOwnProperty()方法可以確定某個(gè)屬性是否來(lái)自實(shí)例,不是來(lái)自實(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" 來(lái)自實(shí)例 alert(per2.name); //"Nicholas" delete per1.name; alert(per1.name); //"Nicholas" 來(lái)自原型 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ù)組,無(wú)論是否可枚舉
更簡(jiǎn)單的原型語(yǔ)法:
使用上述方法實(shí)在太麻煩了,更經(jīng)常使用的是以下方法:使用對(duì)象字面量
Person.prototype = { name : “Nicholas”, age : 29 sayName = function(){ alert(this.name); } }
不過(guò),此方法,相當(dāng)于重寫(xiě)了整個(gè)prototype對(duì)象,將導(dǎo)致constructor屬性不再指向Person而是指向Object,雖然instanceof還是會(huì)返回正確的結(jié)果,但通過(guò)constructor已經(jīng)不能確定對(duì)象類(lèi)型了。
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); } }
以上寫(xiě)法會(huì)使constructor的enumerable特性被設(shè)置為true,默認(rèn)情況下原生的是false的,在兼容ECMAScript5的瀏覽器可以使用Object.defineProperty()進(jìn)行設(shè)置
Object.defineProperty(Person.prototype,”constructor”,{ enumerable:false, value:Person });
注:重寫(xiě)原型對(duì)象,將會(huì)切斷現(xiàn)有原型與任何之前已經(jīng)存在的對(duì)象實(shí)例之間的聯(lián)系
繼承(難度較大,需再仔細(xì)研究)
使用原型鏈來(lái)實(shí)現(xiàn)
子類(lèi)型要覆蓋超類(lèi)的方法,應(yīng)該將給原型添加方法的代碼放在替換原型之后,
注:通過(guò)原型鏈實(shí)現(xiàn)繼承時(shí),不能使用對(duì)象字面量創(chuàng)建原型方法,否則會(huì)重寫(xiě)原型鏈
借用構(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ù)的語(yǔ)句放在函數(shù)聲明之前
function funName(arg0,arg1){ //函數(shù)體 }
2、函數(shù)表達(dá)式,不能進(jìn)行函數(shù)提升,也就是無(wú)法在函數(shù)創(chuàng)建前使用函數(shù),在這種情況下創(chuàng)建的函數(shù)稱(chēng)為匿名函數(shù),有時(shí)也叫拉姆達(dá)函數(shù)
var funName = function(arg0,arg1){ //函數(shù)體 }
嚴(yán)格模式下無(wú)法使用arguments.callee來(lái)實(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)訪問(wèn)另一個(gè)函數(shù)作用域中的變量的函數(shù),閉包,也是一個(gè)函數(shù)
創(chuàng)建閉包的常見(jiàn)方式是在一個(gè)函數(shù)內(nèi)部創(chuàng)建另一個(gè)函數(shù)
閉包只能取得包含函數(shù)即外部函數(shù)中任何變量的最后一個(gè)值。下例可以清晰說(shuō)明問(wèn)題
例:
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í)作用域,沒(méi)有使用圓括號(hào)將function包起來(lái)將會(huì)出錯(cuò) })();
使用閉包和私有變量的明顯不足之處在于,會(huì)在作用域鏈中多查找一個(gè)層次,在一定程度上影響查找速度
函數(shù)中定義的變量可以在一定程度上稱(chēng)為私有變量,通過(guò)函數(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ǔ)語(yǔ)法
- JavaScript高級(jí)程序設(shè)計(jì)(第3版)學(xué)習(xí)筆記3 js簡(jiǎn)單數(shù)據(jù)類(lèi)型
相關(guān)文章
JS實(shí)現(xiàn)超簡(jiǎn)單的仿QQ折疊菜單效果
這篇文章主要介紹了JS實(shí)現(xiàn)超簡(jiǎn)單的仿QQ折疊菜單效果,可實(shí)現(xiàn)鼠標(biāo)滑過(guò)列表展開(kāi)的QQ折疊菜單效果,非常簡(jiǎn)單實(shí)用,需要的朋友可以參考下2015-09-09分享我對(duì)JS插件開(kāi)發(fā)的一些感想和心得
這篇文章主要給大家分享我對(duì)JS插件開(kāi)發(fā)的一些感想和心得的相關(guān)資料,需要的朋友可以參考下2016-02-02微信小程序個(gè)人中心的列表控件實(shí)現(xiàn)代碼
這篇文章主要介紹了微信小程序個(gè)人中心的列表控件實(shí)現(xiàn)代碼,本文通過(guò)實(shí)例代碼給大家介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或工作具有一定的參考借鑒價(jià)值,需要的朋友可以參考下2020-04-04javascript 從if else 到 switch case 再到抽象
大家覺(jué)得在接手遺留代碼時(shí),見(jiàn)到什么東東是最讓人感到不耐煩的?復(fù)雜無(wú)比的 UML ?我覺(jué)得不是。2010-07-07

javascript對(duì)JSON數(shù)據(jù)排序的3個(gè)例子