ES3和ES5中函数调用(function call) 的浏览器实现差异.
来源:互联网 发布:网络电话机终端 编辑:程序博客网 时间:2024/04/30 17:56
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
但是.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则恰恰相反.
参考
- ES3和ES5中函数调用(function call) 的浏览器实现差异.
- es5 bind和es3函数模拟的bind的区别
- JavaScript原型链以及ES3、ES5、ES6实现继承的不同方式
- 各浏览器中querySelector和querySelectorAll的实现差异
- 函数的调用机制_用递归实现栈(Function call machenism_Recursive calls stimulate stack)
- cdecl和stdcall等函数调用约定(function call convention)的区别与联系
- pure virtual function call--虚函数调用的错误
- 模拟实现ES5中原生的bind函数
- 函数调用栈(Function call stack)
- ES5和ES6中对于继承的实现方法
- ES6转换成ES5/ES3
- STL中调用函数对象和普通函数差异
- Shellcode中ret调用和call调用函数区别
- javascript 中函数的调用:直接调用函数和new function()区别
- ExecuteSQL函数 和 call 调用
- js中call和apply(函数的上下文调用模式)详解
- js中call和apply(函数的上下文调用模式)详解
- 纯虚函数调用 pure virtual function call 错误
- synchronize java
- WM_COMMAND
- Essential C++学习笔记------第五章
- 没有“temp”的swap
- mysql 基础 -mysqld_safe 启动执行流程
- ES3和ES5中函数调用(function call) 的浏览器实现差异.
- POJ-2226-Muddy Fields
- UVA465-溢出
- WM_NCCALCSIZE
- 字符设备 register_chrdev_region()、alloc_chrdev_region() 和 register_chrdev()
- LoadMenuIndirect
- synchronized java 详解2
- 阅读uboot源码的历程
- seam2.3+jboss7.1配置过程