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 相关文章推荐
JS 退出系统并跳转到登录界面的实现代码
Jun 29 Javascript
node.js中的http.request.end方法使用说明
Dec 10 Javascript
jQuery实现简单的图片查看器
Sep 11 Javascript
使用plupload自定义参数实现多文件上传
Jul 19 Javascript
ajax 提交数据到后台jsp页面及页面跳转问题
Jan 19 Javascript
详解VueJs中的V-bind指令
May 03 Javascript
使用vuex缓存数据并优化自己的vuex-cache
May 30 Javascript
vscode下vue项目中eslint的使用方法
Jan 13 Javascript
使用Vue实现简单计算器
Feb 25 Javascript
jquery实现轮播图特效
Apr 12 jQuery
JavaScript编写开发动态时钟
Jul 29 Javascript
jquery插件实现悬浮的菜单
Apr 24 jQuery
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通过array_push()函数添加多个变量到数组末尾的方法
2015/03/18 PHP
通过 Dom 方法提高 innerHTML 性能
2008/03/26 Javascript
jQuery formValidator表单验证插件开源了 含API帮助、源码、示例
2008/08/14 Javascript
使用jquery实现select添加实现后台权限添加的效果
2011/05/28 Javascript
JavaScript 大数据相加的问题
2011/08/03 Javascript
Ext JS 4官方文档之三 -- 类体系概述与实践
2012/12/16 Javascript
jQuery插件实现屏蔽单个元素使用户无法点击
2013/04/12 Javascript
解析img图片没找到onerror事件 Stack overflow at line: 0
2013/12/23 Javascript
JQuery弹出炫丽对话框的同时让背景变灰色
2014/05/22 Javascript
使用focus方法让光标默认停留在INPUT框
2014/07/29 Javascript
当前流行的JavaScript代码风格指南
2014/09/10 Javascript
使用jquery动态加载js文件的方法
2014/12/24 Javascript
Bootstrap框架下下拉框select搜索功能
2020/03/26 Javascript
three.js实现围绕某物体旋转
2017/01/25 Javascript
nodejs前端自动化构建环境的搭建
2017/07/26 NodeJs
深入解析Vue源码实例挂载与编译流程实现思路详解
2019/05/05 Javascript
react实现复选框全选和反选组件效果
2020/08/25 Javascript
[06:24]DOTA2亚洲邀请赛小组赛第三日 TOP10精彩集锦
2015/02/01 DOTA
Web服务器框架 Tornado简介
2014/07/16 Python
详解Python 数据库 (sqlite3)应用
2016/12/07 Python
Python 列表理解及使用方法
2017/10/27 Python
python异步实现定时任务和周期任务的方法
2019/06/29 Python
Python MongoDB 插入数据时已存在则不执行,不存在则插入的解决方法
2019/09/24 Python
使用TensorBoard进行超参数优化的实现
2020/07/06 Python
python中strip(),lstrip(),rstrip()函数的使用讲解
2020/11/17 Python
5分钟快速掌握Python定时任务框架的实现
2021/01/26 Python
美国领先的家居装饰和礼品商店:Kirkland’s
2017/01/30 全球购物
英国美术用品购物网站:Cass Art
2019/10/08 全球购物
简述Linux文件系统通过i节点把文件的逻辑结构和物理结构转换的工作过程
2012/04/17 面试题
应届生求职信写作技巧
2013/10/24 职场文书
商务专员岗位职责
2013/11/23 职场文书
财务部副经理岗位职责
2014/03/14 职场文书
2015年档案管理工作总结
2015/04/08 职场文书
2015年售票员工作总结
2015/04/29 职场文书
使用Postman测试需要授权的接口问题
2022/06/21 Java/Android
Win10此设备不支持接收Miracast无法投影的解决方法
2022/07/07 数码科技