奇妙的Function和prototype

先来看一段代码

function fn() {};
Function.prototype.test = 'fn';
fn.prototype.test = 'aaa';
var fo = new fn();
alert(fo.test);

相信所有人都知道答案,ok,再来一段:

function fn() { return {}; };
Function.prototype.test = 'fn';
fn.prototype.test = 'aaa';
var fo = new fn();
alert(fo.test);

可能有一部分人被淘汰了,答案是undefined,再来一段:

function fn() { return fn; };
Function.prototype.test = 'fn';
fn.prototype.test = 'aaa';
var fo = new fn();
alert(fo.test);

是什么? 很不幸,'fn',又有一些被淘汰了,那我们继续往前:

function fn() { alert(this.test); return {test: 'bbb'}; };
fn.prototype.test = 'aaa';
var fo = new fn();

结果是'aaa'。很有一部分人冲到了最后,不过,有人能清楚的解释一下,这是为什么呢? 相信绝大多数同学黯然的低下了头。

正当我们为广大劳苦大众发愁的时候,一声春雷响,我们迎来了@richie同学的JavaScript对象模型-执行模型。该文洋洋洒洒,图文并茂的讲述了具体的执行机制,这年头,能如此较真的人还真不多,赞一个。

 

摘录精华如下:

对象创建过程:

是指形如new Fn(args)的过程

1. 创建一个build-in object对象obj并初始化
2. 如果Fn.prototype是Object类型,则将obj的内部[[Prototype]]设置为Fn.prototype,否则obj的[[Prototype]]将为其初始化值(即Object.prototype)
3. 将obj作为this,使用args参数调用Fn的内部[[Call]]方法
    3.1 内部[[Call]]方法创建当前执行上下文
    3.2 调用Fn的函数体
    3.3 销毁当前的执行上下文
    3.4 返回Fn函数体的返回值,如果F的函数体没有返回值则返回undefined
4. 如果[[Call]]的返回值是Object类型,则返回这个值,否则返回obj
注意步骤2中, prototype指对象显示的prototype属性,而[[Prototype]]则代表对象内部Prototype属性(隐式的)。

Firefox中,可以用__proto__获取[[Prototype]]。

 

函数对象创建过程:

 JavaScript代码中定义函数,或者调用Function创建函数时,最终都会以类似这样的形式调用Function函数:var newFun=Function(funArgs, funBody); 。创建函数对象的主要步骤如下:
1. 创建一个build-in object对象fn
2. 将fn的内部[[Prototype]]设为Function.prototype
3. 设置内部的[[Call]]属性,它是内部实现的一个方法,处理逻辑参考对象创建过程的步骤3
4. 设置内部的[[Construct]]属性,它是内部实现的一个方法,处理逻辑参考对象创建过程的步骤1,2,3,4
5. 设置fn.length为funArgs.length,如果函数没有参数,则将fn.length设置为0
6. 使用new Object()同样的逻辑创建一个Object对象fnProto
7. 将fnProto.constructor设为fn
8. 将fn.prototype设为fnProto
9. 返回fn

 

压轴的模型图:

红色虚线表示[[Prototype]]

2010011217132320.jpg

转载于:https://www.cnblogs.com/nozer0/archive/2010/02/22/1645294.html

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值