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 相关文章推荐
document.getElementById的简写方式(获取id对象的简略写法)
Sep 10 Javascript
jquery中ajax学习笔记3
Oct 16 Javascript
Ajax搜索结果页面下方的分页按钮的生成
Apr 05 Javascript
使用AngularJS中的SCE来防止XSS攻击的方法
Jun 18 Javascript
JavaScript基于ajax编辑信息用法实例
Jul 15 Javascript
jQuery实现MSN中文网滑动Tab菜单效果代码
Sep 09 Javascript
javascript+css3 实现动态按钮菜单特效
Feb 06 Javascript
jquery easyui DataGrid简单示例
Jan 23 Javascript
React中如何引入Angular组件详解
Aug 09 Javascript
javascript中join方法实例讲解
Feb 21 Javascript
Vue的click事件防抖和节流处理详解
Nov 13 Javascript
vue 内联样式style中的background用法说明
Aug 05 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
php intval的测试代码发现问题
2008/07/27 PHP
PHP Cookie的使用教程详解
2013/06/03 PHP
用Json实现PHP与JavaScript间数据交换的方法详解
2013/06/20 PHP
php旋转图片90度的方法
2013/11/07 PHP
PHP中redis的用法深入解析
2014/02/20 PHP
php脚本守护进程原理与实现方法详解
2017/07/20 PHP
解决Laravel blade模板转义html标签的问题
2019/09/03 PHP
PHP7变量处理机制修改
2021/03/09 PHP
javascript textContent与innerText的异同分析
2010/10/22 Javascript
Ext中下拉列表ComboBox组件store数据格式用法介绍
2013/07/15 Javascript
Ubuntu中搭建Nodejs开发环境过程分享
2014/06/01 NodeJs
网页中表单按回车就自动提交的问题的解决方案
2014/11/03 Javascript
js实现仿Windows风格选项卡和按钮效果实例
2015/05/13 Javascript
JS实现自动变换的菜单效果代码
2015/09/09 Javascript
JavaScript 链式结构序列化详解
2016/09/30 Javascript
laravel5.3 vue 实现收藏夹功能实例详解
2018/01/21 Javascript
微信小程序数据分析之自定义分析的实现
2018/08/17 Javascript
element-ui表格合并span-method的实现方法
2019/05/21 Javascript
深入解析Python的Tornado框架中内置的模板引擎
2016/07/11 Python
一个基于flask的web应用诞生(1)
2017/04/11 Python
Python连接phoenix的方法示例
2017/09/29 Python
详解python之协程gevent模块
2018/06/14 Python
keras做CNN的训练误差loss的下降操作
2020/06/22 Python
澳大利亚和新西兰最大的在线旅行社之一:Aunt Betty
2019/08/07 全球购物
波兰化妆品和护肤品购物网站:eKobieca
2019/08/30 全球购物
北京捷通华声语音技术有限公司Java软件工程师笔试题
2012/04/10 面试题
求职简历中自我评价
2014/01/28 职场文书
开展党的群众路线教育实践活动方案
2014/02/05 职场文书
计算机大学生职业生涯规划书范文
2014/02/19 职场文书
产品推广策划方案
2014/05/10 职场文书
增员口号大全
2014/06/18 职场文书
2014医学院领导班子对照检查材料思想汇报
2014/09/19 职场文书
毕业赠语大全
2015/06/23 职场文书
三好学生主要事迹怎么写
2015/11/03 职场文书
python调试工具Birdseye的使用教程
2021/05/25 Python
Redis实现短信验证码登录的示例代码
2022/06/14 Redis