首页 > web前端 > js教程 > 正文

Javascript new关键字的玄机 以及其它_javascript技巧

php中文网
发布: 2016-05-16 18:20:46
原创
1280人浏览过

接上)先看张对老手不新鲜但对菜鸟很有趣的图:

    Javascript new关键字的玄机 以及其它_javascript技巧

What the heck is that? 简直是luan lun。

 

new

抛开上面的图,先看看上篇文章留下的第二个问题,让我们在构造器的函数体内加点东西,看会发生什么。

 

<DIV><!--<br /><br />Code highlighting produced by Actipro CodeHighlighter (freeware)<br />http://www.CodeHighlighter.com/<br /><br />--><SPAN style="COLOR: #0000ff">function</SPAN><SPAN style="COLOR: #000000"> A(){</SPAN><SPAN style="COLOR: #0000ff">this</SPAN><SPAN style="COLOR: #000000">.p </SPAN><SPAN style="COLOR: #000000">=</SPAN><SPAN style="COLOR: #000000"> </SPAN><SPAN style="COLOR: #000000">1</SPAN><SPAN style="COLOR: #000000">}<BR></SPAN><SPAN style="COLOR: #0000ff">var</SPAN><SPAN style="COLOR: #000000"> a </SPAN><SPAN style="COLOR: #000000">=</SPAN><SPAN style="COLOR: #000000"> </SPAN><SPAN style="COLOR: #0000ff">new</SPAN><SPAN style="COLOR: #000000"> A()</SPAN></DIV>
登录后复制

会得到如下结果:

    Javascript new关键字的玄机 以及其它_javascript技巧

为什么用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函数返回的东西。

伪代码如下:

 

<DIV><!--<br /><br />Code highlighting produced by Actipro CodeHighlighter (freeware)<br />http://www.CodeHighlighter.com/<br /><br />--><SPAN style="COLOR: #0000ff">var</SPAN><SPAN style="COLOR: #000000"> x </SPAN><SPAN style="COLOR: #000000">=</SPAN><SPAN style="COLOR: #000000"> </SPAN><SPAN style="COLOR: #0000ff">new</SPAN><SPAN style="COLOR: #000000"> Object(); </SPAN><SPAN style="COLOR: #008000">//</SPAN><SPAN style="COLOR: #008000">事实上不一定用new来创建,我也不清楚。</SPAN><SPAN style="COLOR: #008000"><BR></SPAN><SPAN style="COLOR: #000000">x.__proto__ </SPAN><SPAN style="COLOR: #000000">=</SPAN><SPAN style="COLOR: #000000"> A.prototype <BR></SPAN><SPAN style="COLOR: #0000ff">var</SPAN><SPAN style="COLOR: #000000"> result </SPAN><SPAN style="COLOR: #000000">=</SPAN><SPAN style="COLOR: #000000"> A.call(x)<BR></SPAN><SPAN style="COLOR: #0000ff">if</SPAN><SPAN style="COLOR: #000000"> (</SPAN><SPAN style="COLOR: #0000ff">typeof</SPAN><SPAN style="COLOR: #000000">(result) </SPAN><SPAN style="COLOR: #000000">==</SPAN><SPAN style="COLOR: #000000"> </SPAN><SPAN style="COLOR: #000000">"</SPAN><SPAN style="COLOR: #000000">object</SPAN><SPAN style="COLOR: #000000">"</SPAN><SPAN style="COLOR: #000000">){<BR>  </SPAN><SPAN style="COLOR: #0000ff">return</SPAN><SPAN style="COLOR: #000000"> result;<BR>}<BR></SPAN><SPAN style="COLOR: #0000ff">return</SPAN><SPAN style="COLOR: #000000"> x;<BR></SPAN></DIV>
登录后复制

 

 

 

在我们的例子里,A函数返回undefined(因为没有return字眼),所以a就是x。但我们举个例子,验证下上面第4步里的特殊情况:

    Javascript new关键字的玄机 以及其它_javascript技巧

果然。

 

对象的constructor属性

再看看上篇文章留下的第一个问题

Hour One
Hour One

AI文字到视频生成

Hour One 37
查看详情 Hour One

 

<DIV><SPAN>function</SPAN><SPAN> Base(){}<BR>Base.prototype.a </SPAN><SPAN>=</SPAN><SPAN> </SPAN><SPAN>1</SPAN><SPAN><BR></SPAN><SPAN>var</SPAN><SPAN> base </SPAN><SPAN>=</SPAN><SPAN> </SPAN><SPAN>new</SPAN><SPAN> Base();<br><br></SPAN><SPAN>function</SPAN><SPAN> Derived(){}<BR>Derived.prototype </SPAN><SPAN>=</SPAN><SPAN> base;<BR></SPAN><SPAN>var</SPAN><SPAN> d </SPAN><SPAN>=</SPAN><SPAN> </SPAN><SPAN>new</SPAN><SPAN> Derived()</SPAN></DIV>
登录后复制

 

 

执行完上面的代码,mybase.constructor很容易猜到是Base,那么d.constructor呢?是Derived吗?

     Javascript new关键字的玄机 以及其它_javascript技巧

不对,也是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怎么样?

    Javascript new关键字的玄机 以及其它_javascript技巧

从图中可以看出,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()构造出来的东西(自己构造自己,我不知道具体是不是这样,但就这么认为,挺合理的。)

也就是说,可以设想如下代码:

 

<DIV><!--<br /><br />Code highlighting produced by Actipro CodeHighlighter (freeware)<br />http://www.CodeHighlighter.com/<br /><br />--><SPAN style="COLOR: #0000ff">var</SPAN><SPAN style="COLOR: #000000"> Function </SPAN><SPAN style="COLOR: #000000">=</SPAN><SPAN style="COLOR: #000000"> </SPAN><SPAN style="COLOR: #0000ff">new</SPAN><SPAN style="COLOR: #000000"> Function()<BR></SPAN><SPAN style="COLOR: #0000ff">var</SPAN><SPAN style="COLOR: #000000"> Object </SPAN><SPAN style="COLOR: #000000">=</SPAN><SPAN style="COLOR: #000000"> </SPAN><SPAN style="COLOR: #0000ff">new</SPAN><SPAN style="COLOR: #000000"> Function() </SPAN></DIV>
登录后复制

 

 

根据上篇文章的规律,会有Function.__proto__ === Function.prototype,以及Object.__proto__ === Function.prototype,验证一下:

    Javascript new关键字的玄机 以及其它_javascript技巧

Function instanceof Object,这是显然为true的,万物归Object管,Function的__proto__链依次指向:Function.prototype,Object.prototype。

Object instanceof Function,因为Function.prototype在Object的__proto__链中,所以也为true。

java速学教程(入门到精通)
java速学教程(入门到精通)

java怎么学习?java怎么入门?java在哪学?java怎么学才快?不用担心,这里为大家提供了java速学教程(入门到精通),有需要的小伙伴保存下载就能学习啦!

下载
来源:php中文网
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系admin@php.cn
最新问题
开源免费商场系统广告
热门教程
更多>
最新下载
更多>
网站特效
网站源码
网站素材
前端模板
关于我们 免责申明 举报中心 意见反馈 讲师合作 广告合作 最新更新 English
php中文网:公益在线php培训,帮助PHP学习者快速成长!
关注服务号 技术交流群
PHP中文网订阅号
每天精选资源文章推送
PHP中文网APP
随时随地碎片化学习

Copyright 2014-2025 https://www.php.cn/ All Rights Reserved | php.cn | 湘ICP备2023035733号