ES3和ES5中函数调用(function call) 的浏览器实现差异.

1.var obj = {};
2.obj.foo( obj.foo = function(){ console.log("new func"); } );
3.obj.foo();//new func

有些浏览器执行到第二行处报错,有些继续执行打印出"new func"
执行到第二行时,
一种是先解析出obj.foo 对象,然后解析参数,再执行函数调用,显然,解析obj.foo时,foo不存在。
一种是先解析参数,然后解析obj.foo,最后执行函数调用。

ES 5中函数调用的顺序
1. Let ref be the result of evaluating MemberExpression.
 2. Let func be GetValue(ref).
 3. Let argList be the result of evaluating Arguments, producing an internal list of argument values
 4. If Type(func) is not Object, throw a TypeError exception.
 5. If IsCallable(func) is false, throw a TypeError exception.
 6. (snip)

So, func indicates shoud be Undefined and it should throw TypeError by step4.
因此报错


下面的例子按ES 5

1.var o = {
2.    test: function () {alert( 'origin' )}
3.};
4.o.test(o.test = function (){ alert( 'changed' ); });//origin
5.o.test();//changed

  


但是.Chrome17-, IE8- 第四行会打印changed .  而 Firefox0.8+,Safai3+, Opera9.2+,IE9+ 则第四行都打印origin.  

 

出现这个问题的根源,我们通过翻看 ES3和ES5,可以找到原因.  原来ES3和ES5,在此处是有冲突的. 道格拉斯认为ES3是不合理的. 所以更改了这里的逻辑.

ES3:

Function Calls
The production CallExpression : MemberExpression Arguments is evaluated as follows:
1. Evaluate MemberExpression.
2. Evaluate Arguments, producing an internal list of argument values (see 11.2.4).
3. Call GetValue(Result(1)).

 

ES5:

11.2.3 Function Calls
The production CallExpression : MemberExpression Arguments is evaluated as follows:

1. Let ref be the result of evaluating MemberExpression.
2. Let func be GetValue(ref).
3. Let argList be the result of evaluating Arguments, producing an internal list of argument values (see 11.2.4).

 

可见ES5 对MemberExpression 也就是这里的函数名部分的表达式所获取的引用,进行getValue运算是早于 对实参列表进行evalute的.

而ES3则恰恰相反.  

 参考

http://www.cnblogs.com/_franky/archive/2011/12/02/2271864.html
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值