Javascript中new关键字的玄机
时间:2010-08-31 来源:缘分星空
What the heck is that? 简直是luan lun。
new
抛开上面的图,先看看上篇文章留下的第二个问题,让我们在构造器的函数体内加点东西,看会发生什么。
function A(){this.p = 1}
var a = new A()
会得到如下结果:
为什么用new关键字构造出来的a,会获得p这个属性?new A()这行代码做了什么事情?根据上篇文章中Function的创建过程第4步,A这个对象会有一个Construct属性(注意不是constructor,Consturct是ECMAScript标准里的属性,好像对外不可见),该属性的值是个函数,new A()即会调用A的这个Construct函数。那么这个Construct函数会做些啥呢?
1, 创建一个object,假设叫x。
2, 如果A.prototype是个object(一般都是),则把A.prototype赋给x.__proto__;否则(不常见),请大老板Object出马,把Object.prototype赋给x.__proto__。
3, 调用A.call(x),第一个参数传入我们刚刚创建的x。这就妥了,A的函数体里this.p = 1,这个this,就成了x。因此x就有了p这个属性,并且x.p = 1。
4, 一般情况下,就返回x了,这时a就是x了。但也有特殊情况,如果A的函数体里返回的东西,它的类型(typeof)是个object。那么a就不是指向x了,而是指向A函数返回的东西。
伪代码如下:
var x = new Object(); //事实上不一定用new来创建,我也不清楚。
x.__proto__ = A.prototype
var result = A.call(x)
if (typeof(result) == "object"){
return result;
}
return x;
在我们的例子里,A函数返回undefined(因为没有return字眼),所以a就是x。但我们举个例子,验证下上面第4步里的特殊情况:
果然。
对象的constructor属性
再看看上篇文章留下的第一个问题
function Base(){}
Base.prototype.a = 1
var base = new Base();
function Derived(){}
Derived.prototype = base;
var d = new Derived()
执行完上面的代码,mybase.constructor很容易猜到是Base,那么d.constructor呢?是Derived吗?
不对,也是Base,怎么回事?很简单,复习下上篇的内容就知道:由于d本身没有constructor属性,所以会到d.__proto__上去找,d.__proto__就是Derived.prototype,也就是base这个对象,base也没constructor属性,于是再往上,到base.__proto__上找,也就是Base.prototype。它是有constructor属性的,就是Base本身。事实上,就我目前所知,只有构造器(function类型的object)的prototype,才真正自己拥有constructor属性的对象,且“构造器.prototype.constructor === 构造器”。
Instanceof
那么,instanceof怎么样?
从图中可以看出,d是Base、Derived和Object的实例。很合理,但这是怎么判断的呢?是这样的:对于x instanceof constructor的表达式,如果constructor.prototype在x的原型(__proto__)链里,那么就返回true。很显然,d的__proto__链往上依次是:Derived.prototype, Base.prototype, Object.prototype,得到图中结果就毫无疑问了。所以,instanceof跟对象的constructor属性无关。
Function and Object
最后解答一下文章开头的图。
Function和Object本身也是function类型的对象,因此可以说都是Function()构造出来的东西(自己构造自己,我不知道具体是不是这样,但就这么认为,挺合理的。)
也就是说,可以设想如下代码:
var Function = new Function()
var Object = new Function()
根据上篇文章的规律,会有Function.__proto__ === Function.prototype,以及Object.__proto__ === Function.prototype,验证一下:
Function instanceof Object,这是显然为true的,万物归Object管,Function的__proto__链依次指向:Function.prototype,Object.prototype。
Object instanceof Function,因为Function.prototype在Object的__proto__链中,所以也为true。
待续。
Gucci Aviatrix Large Boston in Black Gucci-186232-04 HandbagsLV N41529 Louis Vuitton LV Handbags Speedy 25chanel Handbags Noe Hobo - Blue Chanel-cc690LV M03822 Louis Vuitton Handbags YarangaGucci Medium Backpack Black 190278 190278-black HandbagsChanel Shoulder Pochette - White chanel-cambon360 HandbagsLouis Vuitton Suhali Leather Le Radieux Taupe M95625 HandbagsChanel Classical Matte Alligator Bag 36001 - Coffee 36001coffee HandbagsLouis Vuitton Monogram Denim Mini Pleaty Raye Customise M95332 HandbagsLouis Vuitton Monogram Canvas Etoile GM Bag M56372 HandbagsGucci BOTTLE CARRIER BROWN GUBOTTBLK-1 gucci-GUBOTTBLK-1 Handbagschanel Handbags Chanel 2008 summer Clutch 2223 - black chanel-2223--blackGucci race top Handbags Black Gucci-177091-06Louis Vuitton Monogram Canvas Pochette Marly M51825 HandbagsLouis Vuitton Damier Graphite Canvas Thomas N58028 HandbagsGUCCI 170010 New tote G170010-01 Handbags09 CHANEL PARIS MOSCOW *ROMANOV IVORY 2.55* WOOL FLAP BAG 36015 - RED 36015red HandbagsLouis Vuitton Multicolore Beverly GM M40201 HandbagsLouis Vuitton Monogram Vernis Melrose Avenue Violette LV M93757P M93757PL HandbagsLouis Vuitton Mahina Handbags M95717 LV M52222BL Louis Vuitton LV Handbags Soufflot - Toledo BlueLouis Vuitton Multicolor Aurelia GM White M40100 HandbagsLouis Vuitton Multicolor Trouville Black M92662 HandbagsLouis Vuitton Multicolor Pochette White M92649 HandbagsLouis Vuitton Show Fall Winter 2009 Stephone Sprouse Graffiti Collection Drawstring Bag Black M95099 HandbagsLouis Vuitton Epi Leather Pochette Homme Black M52522 HandbagsLouis Vuitton Monogram Vernis Wilshire Boulevard White LV M93642 M93642WT HandbagsLouis Vuitton Monogram Canvas Neverfull MM M40156 HandbagsLouis Vuitton Epi Leather Passy Bag GM Orange Sunset M59252 HandbagsLouis Vuitton Damier Canvas Belem MM N51174 HandbagsGucci GG Fabric Handbagss G209600 Gucci-209600-01Louis Vuitton Monogram Canvas Trouville M42228 HandbagsLV M51157 Louis Vuitton LV Handbags Marelle MMGucci wallet-Patent blak Gucci-3350 HandbagsLouis Vuitton Monogram Canvas Danube 21 M45266 HandbagsGucci 183691 large shoulder bag-Red Gucci-183691-03 HandbagsGucci GG Fabric Handbagss G190282 Gucci-190282Louis Vuitton Monogram Vernis Sobe Clutch Pomme D'Amour LV M9372 M93727RD HandbagsChanel Large 2.55 Double Flap Bag 35997 - Green 35997green HandbagsShopping Bag GM - Black chanel-cc130 HandbagsLV N51195 Louis Vuitton LV Handbags JornLouis Vuitton Monogram Canvas GM Shoudler Bag M56383 HandbagsLouis Vuitton Cruise 06 Collection Cabas MM Yellow M95113 HandbagsLouis Vuitton Embossed Leather Whisper PM Coffee M95827 M95827-coffee HandbagsLouis Vuitton Damier Geant Canvas Yack Black M93082 HandbagsLouis Vuitton 1:1 Grade Leather Boston Bag with Beads and Dangled Tassels - Coffee HandbagsLouis Vuitton Monogram Mini Lin Danube M95228 HandbagsGucci GG Fabric Handbagss G201480 Gucci-201480-04Louis Vuitton Monogram Vernis Cosmetic Pouch Dark Coffee M93564 HandbagsLouis Vuitton Damier Geant Canvas Citadin Black M93042 Handbags