亚洲乱码中文字幕综合,中国熟女仑乱hd,亚洲精品乱拍国产一区二区三区,一本大道卡一卡二卡三乱码全集资源,又粗又黄又硬又爽的免费视频

理解Javascript_06_理解對(duì)象的創(chuàng)建過程

 更新時(shí)間:2010年10月15日 23:21:37   作者:  
在《理解Javascript_05_原型繼承原理》一文中已經(jīng)詳細(xì)的講解了原型鏈的實(shí)現(xiàn)原理,大家都知道原型鏈?zhǔn)腔趯?duì)象創(chuàng)建的(沒有對(duì)象,哪來原型),那么今天就來解析一下對(duì)象的創(chuàng)建過程。
簡單的代碼
我們先來看一段簡單的代碼:
復(fù)制代碼 代碼如下:

function HumanCloning(){
}
HumanCloning.prototype ={
name:'笨蛋的座右銘'
}
var clone01 = new HumanCloning();
alert(clone01.name);//'笨蛋的座右銘'
alert(clone01 instanceof HumanCloning);//true
HumanCloning.prototype = {};
alert(clone01.name);//'笨蛋的座右銘'
alert(clone01 instanceof HumanCloning);//false
var clone02 = new HumanCloning();
alert(clone02.name);//undefined
alert(clone02 instanceof HumanCloning);//true

復(fù)雜的理論
JS中只有函數(shù)對(duì)象(函數(shù))具備類的概念,因此創(chuàng)建一個(gè)對(duì)象,必須使用函數(shù)對(duì)象。函數(shù)對(duì)象內(nèi)部有[[Construct]]方法和[[Call]]方法,[[Construct]]用于構(gòu)造對(duì)象,[[Call]]用于函數(shù)調(diào)用,只有使用new操作符時(shí)才觸發(fā)[[Construct]]邏輯。注:在本例中HumanCloning這個(gè)自定義函數(shù)是一個(gè)函數(shù)對(duì)象,那么請(qǐng)問Object,String,Number等本地對(duì)象是函數(shù)對(duì)象嗎?答案是肯定的,這是因?yàn)楸镜貙?duì)象都可以看作是函數(shù)的派生類型,在這個(gè)意義上,可以將它們跟用戶定義的函數(shù)等同看待。(與《理解Javascript_04_數(shù)據(jù)模型》中"內(nèi)置數(shù)據(jù)類型"一節(jié)相呼應(yīng))
var obj=new Object(); 是使用內(nèi)置的Object這個(gè)函數(shù)對(duì)象創(chuàng)建實(shí)例化對(duì)象obj。var obj={};和var obj=[];這種代碼將由JS引擎觸發(fā)Object和Array的構(gòu)造過程。function fn(){}; var myObj=new fn();是使用用戶定義的類型創(chuàng)建實(shí)例化對(duì)象。
注:關(guān)于函數(shù)對(duì)象的具體概念會(huì)在后續(xù)的文章中講解,現(xiàn)在可以將"函數(shù)對(duì)象"簡單的理解為"函數(shù)"的概念及可.

內(nèi)部的實(shí)現(xiàn)
結(jié)合本例,函數(shù)對(duì)象為HumanCloning,函數(shù)對(duì)象創(chuàng)建的對(duì)象實(shí)例為clone01和clone02. 現(xiàn)在我們來看一下var clone01 = new HumanCloning();的實(shí)現(xiàn)細(xì)節(jié)(注:函數(shù)對(duì)象的[[Construct]]方法處理邏輯來負(fù)責(zé)實(shí)現(xiàn)對(duì)象的創(chuàng)建):
1. 創(chuàng)建一個(gè)build-in object對(duì)象obj并初始化
2. 如果HumanCloning.prototype是Object類型,則將clone01的內(nèi)部[[Prototype]]設(shè)置為HumanCloning.prototype,否則clone01的[[Prototype]]將為其初始化值(即Object.prototype)
3. 將clone01作為this,使用args參數(shù)調(diào)用HumanCloning的內(nèi)部[[Call]]方法
3.1 內(nèi)部[[Call]]方法創(chuàng)建當(dāng)前執(zhí)行上下文(注:關(guān)于執(zhí)行上下文,將在后續(xù)博文中講解,在《Javascript提速_01_引用變量優(yōu)化》一文中已有部分講解》)
3.2 調(diào)用HumanCloning的函數(shù)體
3.3 銷毀當(dāng)前的執(zhí)行上下文
3.4 返回HumanCloning函數(shù)體的返回值,如果HumanCloning的函數(shù)體沒有返回值則返回undefined
4. 如果[[Call]]的返回值是Object類型,則返回這個(gè)值,否則返回obj
注意,如下代碼為步驟1,步驟2和步驟3的代碼解釋:
復(fù)制代碼 代碼如下:

var clone01 = {};
//程序外部是無法訪問[[prototype]]的,僅用于理解
//clone01.[[prototype]] = HumanCloning.prototype;
HumanCloning.call(clone01);

注意步驟2中, prototype指對(duì)象顯示的prototype屬性,而[[Prototype]]則代表對(duì)象內(nèi)部Prototype屬性(隱式的)。構(gòu)成對(duì)象Prototype鏈的是內(nèi)部隱式的[[Prototype]],而并非對(duì)象顯示的prototype屬性。顯示的prototype只有在函數(shù)對(duì)象上才有意義,從上面的創(chuàng)建過程可以看到,函數(shù)的prototype被賦給派生對(duì)象隱式[[Prototype]]屬性,這樣根據(jù)Prototype規(guī)則,派生對(duì)象和函數(shù)的prototype對(duì)象之間才存在屬性、方法的繼承/共享關(guān)系。(即原型繼承實(shí)現(xiàn)原理,正是《理解Javascript_05_原型繼承原理》的內(nèi)容)
注意步驟3.4中描述,讓我們來看一個(gè)來自于懌飛的問題:

我想,現(xiàn)在回答這個(gè)問題,應(yīng)該是易如反掌吧。

注:原文地址http://www.planabc.net/2008/02/20/javascript_new_function/

內(nèi)存分析

一張簡易的內(nèi)存圖,并引入的函數(shù)對(duì)象的概念,同樣也解釋了上面代碼(相對(duì)來說圖不是很嚴(yán)謹(jǐn),但易于理解)。在此也引出了一個(gè)問題,instanceof的實(shí)現(xiàn)原理,想必大家也看出了一些苗頭,instanceof的判斷依賴于原型鏈,具體實(shí)現(xiàn)細(xì)節(jié),請(qǐng)參見后續(xù)博文。
本地屬性與繼承屬性
對(duì)象通過隱式Prototype鏈能夠?qū)崿F(xiàn)屬性和方法的繼承,但prototype也是一個(gè)普通對(duì)象,就是說它是一個(gè)普通的實(shí)例化的對(duì)象,而不是純粹抽象的數(shù)據(jù)結(jié)構(gòu)描述。所以就有了這個(gè)本地屬性與繼承屬性的問題。
首先看一下設(shè)置對(duì)象屬性時(shí)的處理過程。JS定義了一組attribute,用來描述對(duì)象的屬性property,以表明屬性property是否可以在JavaScript代碼中設(shè)值、被for in枚舉等。
obj.propName=value的賦值語句處理步驟如下:
1. 如果propName的attribute設(shè)置為不能設(shè)值,則返回
2. 如果obj.propName不存在,則為obj創(chuàng)建一個(gè)屬性,名稱為propName
3. 將obj.propName的值設(shè)為value
可以看到,設(shè)值過程并不會(huì)考慮Prototype鏈,道理很明顯,obj的內(nèi)部[[Prototype]]是一個(gè)實(shí)例化的對(duì)象,它不僅僅向obj共享屬性,還可能向其它對(duì)象共享屬性,修改它可能影響其它對(duì)象。
我們來看一個(gè)示例:

復(fù)制代碼 代碼如下:

function HumanCloning(){
}
HumanCloning.prototype ={
name:'笨蛋的座右銘'
}
var clone01 = new HumanCloning();
clone01.name = 'jxl';
alert(clone01.name);//jxl
var clone02 = new HumanCloning();
alert(clone02.name);//笨蛋的座右銘

結(jié)果很明確,對(duì)象的屬性無法修改其原型中的同名屬性,而只會(huì)自身創(chuàng)建一個(gè)同名屬性并為其賦值。
參考。
http://chabaoo.cn/article/25008.htm

相關(guān)文章

最新評(píng)論