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 相关文章推荐
Javascript Math ceil()、floor()、round()三个函数的区别
Mar 09 Javascript
AngularJS入门知识之MVW类框架的编程思想探讨
Dec 08 Javascript
JS/Jquery判断对象为空的方法
Jun 11 Javascript
zepto中使用swipe.js制作轮播图附swipeUp,swipeDown不起效果问题
Aug 27 Javascript
快速掌握jQuery插件WebUploader文件上传
Nov 07 Javascript
解析AngularJS中get请求URL出现的跨域问题
Dec 01 Javascript
JavaScript基于DOM操作实现简单的数学运算功能示例
Jan 16 Javascript
详解用node-images 打造简易图片服务器
May 08 Javascript
vue 动态改变静态图片以及请求网络图片的实现方法
Feb 07 Javascript
使用Node.js写一个代码生成器的方法步骤
May 10 Javascript
聊聊鉴权那些事(推荐)
Aug 22 Javascript
vue使用canvas实现移动端手写签名
Sep 22 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
FleaPHP的安全设置方法
2008/09/15 PHP
thinkPHP的Html模板标签使用方法
2012/11/13 PHP
PHP生成迅雷、快车、旋风等软件的下载链接代码实例
2014/05/12 PHP
通过代码实例解析PHP session工作原理
2020/12/11 PHP
一步一步教你写一个jQuery的插件教程(Plugin)
2009/09/03 Javascript
javascript 24小时弹出一次的代码(利用cookies)
2009/09/03 Javascript
jQuery1.5.1 animate方法源码阅读
2011/04/05 Javascript
javascript学习笔记(五)正则表达式
2011/04/08 Javascript
利用json获取字符出现次数的代码
2012/03/22 Javascript
关于JavaScript的面向对象和继承有利新手学习
2013/01/11 Javascript
Javascript 中 null、NaN和undefined的区别总结
2013/04/10 Javascript
js中document.write使用过程中的一点疑问解答
2014/03/20 Javascript
angularjs表格分页功能详解
2016/01/21 Javascript
js 求时间差的实现代码
2016/04/26 Javascript
JS实现隔行换色的表格排序
2017/03/27 Javascript
vue-cli 3.0 自定义vue.config.js文件,多页构建的方法
2018/09/19 Javascript
详解nodejs解压版安装和配置(带有搭建前端项目脚手架)
2018/12/06 NodeJs
Angular8引入百度Echarts进行图表分析的实现代码
2019/11/27 Javascript
如何利用nodejs实现命令行游戏
2020/11/24 NodeJs
浅析python 中__name__ = '__main__' 的作用
2014/07/05 Python
Python和perl实现批量对目录下电子书文件重命名的代码分享
2014/11/21 Python
python操作mysql数据库
2017/03/05 Python
Python通过matplotlib绘制动画简单实例
2017/12/13 Python
Python实现邮件发送的详细设置方法(遇到问题)
2021/01/18 Python
纯css3实现图片翻牌特效
2015/03/10 HTML / CSS
国际象棋商店:The Chess Store
2018/07/09 全球购物
现代化办公人员工作的自我评价
2013/10/16 职场文书
环境科学专业个人求职信
2013/12/15 职场文书
初中生期末考试的自我评价
2013/12/17 职场文书
金融行业职业生涯规划范文
2014/01/17 职场文书
群众路线教育实践活动方案
2014/02/02 职场文书
《手指教学》反思
2014/02/14 职场文书
人事专员的岗位职责
2014/03/01 职场文书
计算机系统管理员求职信
2014/06/20 职场文书
保研导师推荐信
2015/03/25 职场文书
Pycharm远程调试和MySQL数据库授权问题
2022/03/18 MySQL