- 浏览: 1460440 次
- 性别:
- 来自: 上海
文章分类
最新评论
-
luhouxiang:
写的很不错,学习了
Extjs 模块化动态加载js实践 -
kingkongtown:
如果想改成淘宝后台那样,可以在编辑器批量上传图片呢?
kissy editor 阶段体会 -
317966578:
兄弟我最近也在整jquery和caja 开放一些接口。在git ...
caja 原理 : 前端 -
liuweihug:
Javascript引擎单线程机制及setTimeout执行原 ...
setTimeout ,xhr,event 线程问题 -
辽主临轩:
怎么能让浏览器不进入 文档模式的quirks模式,进入标准的
浏览器模式与文本模式
条件函数定义与异常作用域
好像以前没记录过,罕有情景 firefox 被ie 系列(<=8)以及chrome v8,safari,opera 孤立了:
经典如:
if(true){ function god(){ } }else{ function god(){ alert("what the hell!"); } } alert(god);
不常见如:
alert(typeof z); try{ var x=1; }catch(e){ function z(){} } alert(typeof z);
总结:
函数声明在非firefox下是神,无视障碍会穿越(最后声明的就是事实)!哪个是标准?
updated 2010-10 :
标准与实现
ie,chrome 中函数都会根据 ecma 规范被提前申明,例如:
if(false) { function f(){..} }
等价于
function f(){..} if(false){}
但是 ie 对于具名函数表达式处理有差异。ie 中
if(false){ var f=function f(){ .... }; }
相当于:
function f(){ ... } if(false) { var f=function(){...} }
chrome 最符合标准,具名表达式中的名字只能用于该函数内部递归调用,而不能在当前作用域起作用,则相当于:
if(false){ var f=function(){...}; }
firefox 由于自 javascript1.5 引入了 Conditional function declarations ,则函数申明也可以条件化( firefox 把这种不叫做声明,而叫做表达式 )
if(false){ function f(){..} }
相当于:
if(false){ //不一定是window,只是在当前作用域动态定义 window.f=function(){...} }
详细可见这里的讨论 以及针对jscript的实验 。(相等比较部分看这里 。)
updated 2011-03-04 :
引擎实现
根据 Narcissus 的实现(基于 firefox ),函数定义可分为三种方式:
DECALRED_FORM :
function t(){}
STATEMENT_FORM :
{ function t(){ } }
EXPRESSED_FORM :
var x = function t(){}
而对于 DECALRED_FORM 各个浏览器自然没有疑问。这次主要看看 firefox 的整体函数实现:
switch (n.type) { case FUNCTION: if (n.functionForm != DECLARED_FORM) { /* function(){} 或 { function t(){ } } */ if (!n.name || n.functionForm == STATEMENT_FORM) { v = new FunctionObject(n, x.scope); //如果是有名字,则在当前作用域中加入名字 if (n.functionForm == STATEMENT_FORM) x.scope.object[n.name] = v; } /** var x=function t(){}; **/ else { //新生成一个作用域,里面只有名字 t ,当前作用域引不到 x.scope = {object: {}, parent: x.scope}; try { //只能在函数中引到本函数的名字 t v = new FunctionObject(n, x.scope); // t 加入到新的作用域 x.scope.object[n.name] = v; } finally { //恢复 x.scope = x.scope.parent; } } } break;
update 2011-08-16
function and function scope
细读 function and function scope @ mdc :
function x(){}
相当于函数名为 x ,并且在当前 scope 加了一个变量 x 指向函数 x.
看起来和函数表达式情况类似:
var x=function x(){}
明显了除了解析阶段不同,还有一个微小的差别:
函数声明不会绑定函数名到函数体作用域,而函数表达式则会将将函数名绑定到函数体作用域,而函数名是不可变的,可变的只是那个在当前作用域指向函数的变量:
函数声明没有绑定函数名到函数体:
(function () { function x(zz) { if (zz == 2) { alert("o"); return; } x(2); } var z = x; x = 1; z(); })();
函数表达式绑定了函数名到函数体:
(function () { var x = function x(zz) { if (zz == 2) { alert("o"); return; } x(2); } var z = x; x = 1; z(); })();
catch 内变量声明问题:
try{ var x=1; throw x; }catch(e){ var x=2; } alert(typeof e); alert(x);
除了 ie<9 ( ie9 e 也会 scope leak 到上一层作用域 )外其中 e 是没问题的,但是x就很奇怪了,根据ecma规范,catch 会新建一个词法环境,e以及在里面申明的变量不会和外边的混在一起的?catch退出后新的词法环境就消失了,怎么x会被修改呢?
The production Catch : catch ( Identifier ) Block is evaluated as follows:
1. Let C be the parameter that has been passed to this production.
2. Let oldEnv be the running execution context’s LexicalEnvironment.
3. Let catchEnv be the result of calling NewDeclarativeEnvironment passing oldEnv as the argument .
4. Call the CreateMutableBinding concrete method of catchEnv passing the Identifier String value as the
argument.
5. Call the SetMutableBinding concrete method of catchEnv passing the Identifier, C, and false as arguments. Note that the last argument is immaterial in this situation.
6. Set the running execution context’s LexicalEnvironment to catchEnv.
7. Let B be the result of evaluating Block.
8. Set the running execution context’s LexicalEnvironment to oldEnv.
9. Return B.
updated 2011-08-16:
异常 e 应该是插入到新建的申明作用域头,但这个声明作用域比较特殊,则其内声明的变量其实会声明在父作用域,这个新的作用域在查找时起作用,只有在这个作用域能够找到 e
Refer:
http://www.adequatelygood.com/2010/2/JavaScript-Scoping-and-Hoisting
http://www.dustindiaz.com/javascript-function-declaration-ambiguity/
发表评论
-
continuation, cps
2013-09-12 16:49 2791起 随着 nodejs 的兴起,异步编程成为一种潮流 ... -
一种基于匹配回朔的 css3 选择器引擎实现
2013-05-07 20:40 3401一种基于匹配回朔的 css3 选择器引擎实现 介绍 C ... -
cubic-bezier 模拟实现
2013-01-05 16:34 14089cubic-bezier 曲线是 css3 动画的一个重要基石 ... -
构建前端 DSL
2012-10-11 22:10 5359目前在传统的软件开 ... -
Get cursor position and coordinates from textarea
2012-04-10 20:50 5037最近需要从 textarea 中获 ... -
兼容 ie 的 transform
2012-02-23 14:00 6424css 2d transform 是 css3 引入的一个新的 ... -
promise api 与应用场景
2012-02-07 17:34 7375promise 是 commonjs 社区中提出的异步规范,其 ... -
closure compiler 代码优化实例
2012-01-08 03:23 2829closure compiler 可以进行不少有意思的优化 ... -
write html parser
2011-12-01 02:48 2916首先需要声明 html 不能用正则表达式来直接匹配进行内容抽取 ... -
获取剪贴板数据
2011-11-07 23:31 6447兼容性: 获取剪贴板数据这块各个浏览器间存在很大的 ... -
url 映射问题
2011-11-07 21:52 3221背景 url mapping 我最早知道是作为 j ... -
tip:如何原生播放声音
2011-10-19 12:45 2977如果不想考虑浏览器间 ... -
转载:瀑布流布局浅析
2011-09-29 19:02 2845简介 如果你经 ... -
cross domain request
2011-09-29 18:39 2846场景 跨域请求是随着 ... -
基于多继承的树设计
2011-09-18 03:42 2269分类 树是一种常见 ... -
caja 原理 : 前端
2011-09-01 16:48 7047作为前端开放的基础安全保证,caja 是目前比较合 ... -
tokenization of html
2011-08-29 22:38 2786html 符号解析问题 场景: 在页面上输出包 ... -
ie 下 cloneNode 导致的属性克隆
2011-08-24 16:10 2476这个还是很值得记下,一直存在的很大隐患终于解决,由于在 ie& ... -
循环引用下的深度克隆
2011-08-04 20:39 2306深度复制和浅度复制 是当初初学 c 遇到的第一批问题,似乎使 ... -
模块的静态与动态循环依赖
2011-07-25 03:43 3279场景: 循环依赖 我是不支持的,但现实中似乎又确实需 ...
相关推荐
function name does not match any function declaration(解决方案).md
unmatched function declaration(解决方案).md
invalid static member function declaration(解决方案).md
invalid declaration of function (解决方案).md
implicit declaration of function(解决方案).md
1. 如果没有潜在的利益冲突,作者会勾选"☒ The authors declare that they have no known competing financial interests or personal relationships that could have appeared to influence the work reported in ...
- **输入声明**: `input_declaration`用于声明函数的输入参数及其位宽和类型。函数定义中至少应包含一个输入端口。 - **函数体**: 由`begin`和`end`关键字或者使用分号`;`定义的语句序列组成。在函数体内部,通常...
_ ByVal wFlags As Integer) 'Play Sound Function declaration Declare Function sndPlaySound Lib _ "winmm.dll" Alias "sndPlaySoundA" _ (ByVal lpszSoundName As String, _ ByVal uFlags As Long) As Long ' ...
RzBorder.pas Number of elements differs from declaration TRzLEDCharacters 在装完Raize控件之后编译老是出如下错误: [Pascal Error] RzBorder.pas(1429): E2072 Number of elements (125) differs from ...
标题中提到的“西门子_CE DECLARATION of CONFORMITY.pdf”指的是西门子公司为某产品家族出具的符合性声明文件(CE Declaration of Conformity),这份文件表明了该产品家族符合欧洲共同体的相关指令,并且已经通过...
requirement analysis •conceptual database design •choice of the DBMS •data model mapping •physical design •implementation
在Android系统中,快捷方式(Shortcuts)是用户与应用交互的一种便捷方式,它允许用户在主屏幕上直接访问特定的功能或内容,而无需先打开应用。Android 7.1引入了对动态快捷方式的支持,这使得开发者能够创建更加...
施耐德电气 Twido可编程控制器产品认证——CE Manufacturer’s Declaration TWDpdf,施耐德电气 Twido可编程控制器产品认证——CE Manufacturer’s Declaration TWD
Files contained in apt-mirror-api-0.1.jar: META-INF/MANIFEST.MF META-INF/maven/com.moparisthebest.aptIn16/apt-mirror-api/pom.properties META-INF/maven/...
在TypeScript中,声明合并是一种核心特性,它允许开发者在同一作用域内合并多个相同名称的声明,从而构建更复杂的类型系统。这一特性尤其在处理现有的JavaScript库和模块时显得尤为重要,因为它能帮助编译器理解那些...
这种行为有时被称为“函数声明提升”(Function Declaration Hoisting)。 现在,让我们转到第二种方式,即使用变量赋值定义函数,例如: ```javascript var foo = function() { // ... }; ``` 这种方式实际上定义...
SqList_Declaration.h
"FPGA常见问题解答" FPGA(Field-Programmable Gate Array)是一种可编程逻辑器件,广泛应用于数字电路设计和实现中。然而,在使用FPGA时,常常会遇到一些问题和困惑,本资源旨在解决这些问题,总结常见的FPGA问题...
智能科学专业本科生学习智能技术课程的参考书,计算机视觉方向
Hadoop in Practice collects 85 Hadoop examples and presents them in a problem/solution format. Each technique addresses a specific task you'll face, like querying big data using Pig or writing a log ...