惯性聚合 高效追踪和阅读你感兴趣的博客、新闻、科技资讯
阅读原文 在惯性聚合中打开

推荐订阅源

U
Unit 42
K
Kaspersky official blog
L
LangChain Blog
有赞技术团队
有赞技术团队
V
Visual Studio Blog
T
The Blog of Author Tim Ferriss
Microsoft Azure Blog
Microsoft Azure Blog
Stack Overflow Blog
Stack Overflow Blog
美团技术团队
Vercel News
Vercel News
CTFtime.org: upcoming CTF events
CTFtime.org: upcoming CTF events
G
Google Developers Blog
宝玉的分享
宝玉的分享
月光博客
月光博客
爱范儿
爱范儿
The Register - Security
The Register - Security
S
SegmentFault 最新的问题
M
MIT News - Artificial intelligence
F
Full Disclosure
Engineering at Meta
Engineering at Meta
阮一峰的网络日志
阮一峰的网络日志
Hugging Face - Blog
Hugging Face - Blog
A
About on SuperTechFans
WordPress大学
WordPress大学
D
Docker
Y
Y Combinator Blog
N
News and Events Feed by Topic
P
Proofpoint News Feed
Apple Machine Learning Research
Apple Machine Learning Research
Threat Intelligence Blog | Flashpoint
Threat Intelligence Blog | Flashpoint
Recorded Future
Recorded Future
IT之家
IT之家
C
CXSECURITY Database RSS Feed - CXSecurity.com
Security Latest
Security Latest
Spread Privacy
Spread Privacy
D
Darknet – Hacking Tools, Hacker News & Cyber Security
F
Fortinet All Blogs
AWS News Blog
AWS News Blog
C
Cyber Attacks, Cyber Crime and Cyber Security
P
Proofpoint News Feed
C
CERT Recently Published Vulnerability Notes
D
DataBreaches.Net
Recent Announcements
Recent Announcements
博客园 - Franky
Google DeepMind News
Google DeepMind News
小众软件
小众软件
B
Blog RSS Feed
I
InfoQ
Attack and Defense Labs
Attack and Defense Labs
云风的 BLOG
云风的 BLOG

博客园 - Franky

从ES5 的 函数声明与函数表达式说起. manifest 和 application cache 一套有趣的 javascript题. URL 中,查询字符串与HTML实体冲突,可能带来的问题. 从 null >= 0 说起 深入剖析,什么是eval的直接调用. 凑凑热闹,给eval做个科普. 浏览器静态资源的版本控制新思路.强制更新指定资源缓存.的探讨 IE6 与 GZIP, BUG汇总 你应该了解的 一些web缓存相关的概念. html5 performance 的应用尝试. HTML5 performance API 草案. Object.defineProperty 接口浏览器实现的bug.和疑惑 window.open 浏览器差异. Chrome v8引擎 对多行注释,做词法分析时的bug. IE9的特性变化,(收集贴) 关于p3p 简洁策略,以及浏览器的支持情况. 心神不宁啊... UI线程的阻塞.
ES3和ES5中函数调用(function call) 的浏览器实现差异.
Franky · 2011-12-02 · via 博客园 - Franky

正美今天扔出来的类似下面的代码:

参考代码:

var o = {
    test: function () {alert('origin')}
};
o.test(o.test = function(){ alert('changed'); });

这段代码,我们直觉,觉得打印 origin 才是合理的.  至少我个人是这样认为的.

但是.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则恰恰相反.  

那么我们从纵观历史的角度来看问题. 孰对孰错呢?

.Firefox4才开始真正的按照ES5标准来实现引擎.那么Firefox 3.6-的浏览器,就并没有遵守当时的ES3现行标准.

.Opera11.6开始比较完善的按照ES5实现.所以Opera11.5-的浏览器.同FF3.6-一样.并没有遵守ES3. 

.Safari3-5 也是如此.在Safari5.11仍然对ES5支持度十分底下的前提下,居然始终不曾遵守过ES3.

.Chrome 从5开始部分支持ES5的API,并在版本11开始,比较完善的按照ES5实现. 但是一直到版本17.居然仍然是按照ES3的实现. 很明显是不对的.

那么对这里 从历史角度来看,最好的居然是IE系列.  IE系从9开始按照ES5实现jscript引擎。结果其表现在这一点上就十分完美.  IE8-按照ES3实现.IE9+ 按ES5实现.

这一次,IE值得表扬!奖小红花一朵 。


最后说说ES3的这处奇怪的设定.

对于new NewExpression

就完全没有这个问题.也与ES5是一致的.

即 先 evalute newExpression,然后对其getValue, 然后才去 evalute Arguments

参考代码:

var cons = function () {this.name = 1;};
var obj = new cons(cons = function () {this.name = 2;});
alert(obj.name)

所有浏览器的实现都不会有差异,因为ES3,5之间没有差异.那为什么function call 会这样奇怪呢? 我暂时还想不出当初这样设计的理由.....先记一下吧.