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 相关文章推荐
Array的push与unshift方法性能比较分析
Mar 05 Javascript
Javascript 闭包引起的IE内存泄露分析
May 23 Javascript
js操作CheckBoxList实现全选/反选(在客服端完成)
Feb 02 Javascript
查看图片(前进后退)功能实现js代码
Apr 24 Javascript
form.submit()不能提交表单的原因分析
Oct 23 Javascript
JavaScript实现鼠标滑过图片变换效果的方法
Apr 16 Javascript
JavaScript实现图片自动加载的瀑布流效果
Apr 11 Javascript
性能优化之代码优化页面加载速度
Mar 01 Javascript
微信、QQ、微博、Safari中使用js唤起App
Jan 24 Javascript
koa源码中promise的解读
Nov 13 Javascript
Vue实现一个图片懒加载插件
Mar 11 Javascript
vue防止花括号{{}}闪烁v-text和v-html、v-cloak用法示例
Mar 13 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基于新浪IP库获取IP详细地址的方法
2017/05/04 PHP
可自定义速度的js图片无缝滚动示例分享
2014/01/20 Javascript
javascript中数组的多种定义方法和常用函数简介
2014/05/09 Javascript
jquery attr方法获取input的checked属性问题
2014/05/26 Javascript
Egret引擎开发指南之创建项目
2014/09/03 Javascript
jQuery内容过滤选择器用法分析
2015/02/10 Javascript
AngularJS快速入门
2015/04/02 Javascript
javascript中in运算符用法分析
2015/04/28 Javascript
BootStrap selectpicker
2016/06/20 Javascript
DIV+CSS+jQ实现省市联动可扩展
2016/06/22 Javascript
详解Vuejs2.0之异步跨域请求
2017/04/20 Javascript
javascript定时器取消定时器及优化方法
2017/07/08 Javascript
Kindeditor单独调用多图上传实例
2017/07/31 Javascript
jQuery选择器之表单元素选择器详解
2017/09/19 jQuery
一个简易时钟效果js实现代码
2020/03/25 Javascript
Vue 页面跳转不用router-link的实现代码
2018/04/12 Javascript
Vue.set()动态的新增与修改数据,触发视图更新的方法
2018/09/15 Javascript
微信小程序实现多选功能
2018/11/04 Javascript
angular使用md5,CryptoJS des加密的方法
2019/06/03 Javascript
浅谈python jieba分词模块的基本用法
2017/11/09 Python
Django实现学员管理系统
2019/02/26 Python
详解Matplotlib绘图之属性设置
2019/08/23 Python
Django实现基于类的分页功能
2019/10/31 Python
pytorch之ImageFolder使用详解
2020/01/06 Python
python rsa-oaep加密的示例代码
2020/09/23 Python
friso美素佳儿官方海外旗舰店:荷兰原产原罐
2017/07/03 全球购物
Under Armour安德玛德国官网:美国高端运动科技品牌
2019/03/09 全球购物
幼儿园教师培训制度
2014/01/16 职场文书
办公室主任先进事迹
2014/01/18 职场文书
公司请假条格式
2014/04/11 职场文书
作风建设年活动总结
2014/08/27 职场文书
大学生党性分析材料
2014/12/19 职场文书
2015安全保卫工作总结
2015/04/25 职场文书
大学生心理健康活动总结
2015/05/08 职场文书
2015年校医个人工作总结
2015/07/24 职场文书
mysql连接查询中and与where的区别浅析
2021/07/01 MySQL