嵌套函数声明.没有标准的方法在局部块里声明函数,但可以在另一个函数的顶部嵌套函数声明. function f(){return "global"} function test(x){ var result=[]; function f(){return "local";}//block-local if(x){ result.push(f()); } result.push(f()); return result; } test(true);//["loc…
js函数有一个非凡的特性,即将其源代码重现为字符串的能力. (function(x){ return x+1 }).toString();//"function (x){ return x+1}" 反射获取函数源代码的功能很强大,使用函数对象的toString方法有严重的局限性.toString方法的局限性ECMAScript标准对函数对象的toString方法的返回结果(即该字符串)并没有任何要求.这意味着不同的js引擎将产生不同的字符串,甚至产生的字符串与该函数并不相关. 如果函数…
js有5种原始值类型:布尔值.数字.字符串.null和undefined. 用typeof检测一下: typeof true; //"boolean" typeof 2; //"number" typeof “s”;//"string" typeof null;//"object":ECMAScript把null描述为独特的类型,但返回值却是对象类型,有点困惑. 可以使用Object.prototype.toString.ca…
“1.0e0”=={valueOf:function(){return true;}} 是值是多少? 这两个完全不同的值使用==运算符是相等的.为什么呢?请看<[Effective JavaScript笔记]第3条:当心隐式的强制转换> 因为这个会在比较之前对两个值都进行隐式转换.字符串“1.0e0”被解析成1,而{valueOf:function(){return true;}}会通过调用自身的valueOf进行转化得到true,然后再转化为数字,得到1; 很容易使用强制转换完成一些工作.如…
函数是一种将代码作为数据结构存储的便利方式,代码之后可以被执行.这使得富有表现力的高阶函数抽象如map和forEach成为可能.它也是js异步I/O方法的核心.与此同时,也可以将代码表示为字符串的形式传递给eval函数以达到同样的功能.程序员面临一个选择:应该将代码表示为函数还是字符串?毫无疑问,应该将代码表示为函数.字符串表示代码不够灵活的一个重要原因是:它们不是闭包. 闭包回顾 看下面这个图 js的函数值包含了比调用它们时执行所需要的代码还要多的信息.而且js函数值还在内部存储它们可能会引用…
第63条建议使用工具函数downloadAllAsync接收一个URL数组并下载所有文件,结果返回一个存储了文件内容的数组,每个URL对应一个字符串.downloadAllAsync并不只有清理嵌套回调函数的好处,其主要好处是并行下载文件.我们可以在同一个事件循环中一次启动所有文件的下载,而不用等待每个文件完成下载.并行逻辑是微妙的,很容易出错.下面有实现有一个隐藏的缺陷. function downloadAllAsync(urls,onsuccess,onerror){ var result…
js中的eval函数是一个强大.灵活的工具.强大的工具容易被滥用,所以了解是值得的.(本人只用过它来处理json数据).错误使用eval函数的方式一:允许它干扰作用域.调用eval函数会将其参数作为js程序进行解释.该程序运行于调用者的局部作用域中,嵌入到程序的全局变量会被创建为调用程序的局部变量.此var声明语句与将其直接放置在函数体中的行为是不同的.直接放入的变量声明,会有变量声明的提升.通过eval放入的,只有当eval函数被调用时此var声明语句才会被调用.变量才会加入到作用域.基于作用…
前面有几条都讲过关于Array.prototype的标准方法.这些标准方法被设计成其他对象可复用的方法,即使这些对象并没有继承Array. arguments对象 在22条中提到的函数arguments对象.它是一个类数组对象,并不是一个标准的数组,所以无法使用数组原型中的方法,因此无法使用arguments.forEach这样的形式来遍历每一个参数.这里我们必须使用call方法来对使用forEach方法. function highlight(){ [].forEach.call(argume…
function wrapElements(a){ var res=[],i,n; for(i=0,n=a.length;i<n;i++){ res[i]=function(){return a[i]}; } return res; } var wrapped=wrapElements([10,20,30,40,50]); var f=wrapped[0]; f();//undefined 这个可以由之前的闭包来讲,res里的每个函数都是一个闭包,它们都可以访问上一个函数的作用域内的变量,所以每…
管理异步编程的一个是错误处理.同步代码中只要使用try语句块包装一段代码很容易一下子处理所有的错误. try{ f(); g(); h(); } catch(e){ //这里用来下得出现的错误 } try语句块 但对于异步的代码,多步的处理通常会被分隔到事件队列的单独轮次中,因此,不可能将它们包装在一个try语句块中.事实上异步的API甚至根本不可能抛出异常,因为,当一个异步的错误发生时,没有一个明显的执行上下文来抛出异常!相反,异步的API倾向于将错误表示为回调函数的特定参数,或使用一个附加的…