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


Posted in Javascript onAugust 25, 2010

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

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

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

 

new

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

 

function A(){this.p = 1}
var a = new A()

会得到如下结果:

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

为什么用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步里的特殊情况:

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

果然。

 

对象的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吗?

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

不对,也是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关键字的玄机 以及其它

从图中可以看出,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,验证一下:

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

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

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

Javascript 相关文章推荐
jQuery AnythingSlider滑动效果插件
Feb 07 Javascript
JS函数验证总结(方便js客户端输入验证)
Oct 29 Javascript
iframe 异步加载技术及性能分析
Jul 19 Javascript
myEvent.js javascript跨浏览器事件框架
Oct 24 Javascript
jquery设置元素的readonly和disabled的写法
Sep 22 Javascript
解决JS中乘法的浮点错误的方法
Jan 03 Javascript
JavaScript模板引擎用法实例
Jul 10 Javascript
浅谈jQuery hover(over, out)事件函数
Dec 03 Javascript
vue使用vue-cli快速创建工程
Jul 28 Javascript
weex里Vuex state使用storage持久化详解
Sep 09 Javascript
使用DataTable插件实现异步加载数据
Nov 19 Javascript
ant-design-vue 时间选择器赋值默认时间的操作
Oct 27 Javascript
jquery下组织javascript代码(js函数化)
Aug 25 #Javascript
jquery实现居中弹出层代码
Aug 25 #Javascript
jquery下实现overlay遮罩层代码
Aug 25 #Javascript
在网页中使用document.write时遭遇的奇怪问题
Aug 24 #Javascript
javascript下string.format函数补充
Aug 24 #Javascript
javascript下利用arguments实现string.format函数
Aug 24 #Javascript
基于jQuery的淡入淡出可自动切换的幻灯插件
Aug 24 #Javascript
You might like
ajax缓存问题解决途径
2006/12/06 PHP
Zend Framework教程之Zend_Controller_Plugin插件用法详解
2016/03/07 PHP
PHP实现批量检测网站是否能够正常打开的方法
2016/08/23 PHP
thinkPHP框架实现生成条形码的方法示例
2018/06/06 PHP
jquery选择器-根据多个属性选择示例代码
2013/10/21 Javascript
多个js毫秒倒计时同时进行效果
2016/01/05 Javascript
深入理解Javascript中的自执行匿名函数
2016/06/03 Javascript
jQuery实现弹出带遮罩层的居中浮动窗口效果
2016/09/12 Javascript
浅谈Vuejs Prop基本用法
2017/08/17 Javascript
phantomjs导出html到pdf的方法总结
2017/10/19 Javascript
判断jQuery是否加载完成,没完成继续判断的解决方法
2017/12/06 jQuery
使用Vue.js开发微信小程序开源框架mpvue解析
2018/03/20 Javascript
使用async await 封装 axios的方法
2018/07/09 Javascript
详解babel升级到7.X采坑总结
2019/05/12 Javascript
javascript面向对象三大特征之封装实例详解
2019/07/24 Javascript
小程序如何获取多个formId实现详解
2019/09/20 Javascript
[47:12]TFT vs Secret Supermajor小组赛C组 BO3 第三场 6.3
2018/06/04 DOTA
python 正则式使用心得
2009/05/07 Python
python中os模块详解
2016/10/14 Python
Django的分页器实例(paginator)
2017/12/01 Python
python素数筛选法浅析
2018/03/19 Python
python自动发送邮件脚本
2018/06/20 Python
python3+pyqt5+itchat微信定时发送消息的方法
2019/02/20 Python
Python 使用指定的网卡发送HTTP请求的实例
2019/08/21 Python
python集合的创建、添加及删除操作示例
2019/10/08 Python
django使用F方法更新一个对象多个对象字段的实现
2020/03/28 Python
Python selenium文件上传下载功能代码实例
2020/04/13 Python
windows支持哪个版本的python
2020/07/03 Python
Expedia印度:您的一站式在线旅游网站
2017/08/24 全球购物
专升本个人自我评价
2013/12/22 职场文书
会议活动邀请函
2014/01/27 职场文书
2014学校庆三八妇女节活动总结
2014/03/01 职场文书
就业协议书怎么填
2014/09/15 职场文书
小学生2014国庆节演讲稿:祖国在我心中
2014/09/21 职场文书
关于运动会的广播稿50字
2014/10/17 职场文书
小学家长通知书评语
2014/12/31 职场文书