javascript高级函数
2016-05-28 15:08
417 查看
高级函数
安全的类型检测
js内置的类型检测并非完全可靠,typeof操作符难以判断某个值是否为函数instanceof在多个frame的情况下,会出现问题。
例如:
var isArray = value instance of Array ;
会由于存在多个window,而value与Array不属于同个window的情况而导致出错
对于这样的问题,最好的解决方法是通过调用Object的toString方法,例如:
function isArray(){ return Object.prototype.toString.call(value) == "[object Array]"; }
注意,这个技巧前提是Object.prototype.toString方法未被修改过
作用域安全的构造函数
调用构造函数的时候,如果忘记写new的话,构造函数中对this的赋值,则可能会赋值到window上成为全局变量,导致其他错误。可以在构造函数增加判断来避免这种错误,如下:
function Person(name){ if(this instanceof Person){ this.name = name; }else{ return new Person(name) } }
惰性载入函数
在程序中 ,类似对浏览器的检测等,进行一次检测过后,只要在当前环境下,其检测结果都不会改变。所以,我们的函数中 if 语句只需要判断一次就可以了,而不需要每次都执行。对这种情况的解决方案便称为惰性载入。
惰性载入表示函数执行的分支仅会发生一次。
惰性载入两种实现方法:
替换真正执行的方法,伪代码如下:
function foo(){ if(someCheck){ foo =function(){doSomeThing()}; }else{ foo =function(){doAnotherSomeThing()}; } }
声明函数时就指定适当的函数。通过匿名自执行函数
var foo =function(){ if(someCheck){ returnfunction(){doSomeThing()}; }else{ returnfunction(){doAnotherSomeThing()}; } }();
这样,在代码首次载入的时候,就已经得到对应的值了
函数绑定
先看一个例子:var handler ={ message:"handler message", handlerClick:function(event){ console.log(this.message); } } //用于将某个函数绑定到指定环境 var bind =function(fn, context){ returnfunction(){ fn.apply(context, arguments); } }; var nomalBtn = document.getElementById("nomalBtn"); var bindBtn = document.getElementById("bindBtn"); nomalBtn.addEventListener("click", handler.handlerClick,false);//点击时候会打印 undefined bindBtn.addEventListener("click", bind(handler.handlerClick,handler),false);//点击按钮会打印 handler.message的值
在上面的例子中,我们需要对象中的方法作为事件处理程序。但是,当事件触发时,this的指向却不是handler而是按钮本身。
解决方法可以使用匿名函数,但是,过多的匿名函数会令代码变的难于理解与调试,因此,推荐使用bind方法。
ES5 为函数定义了一个原生的bind方法,也就是说,你不必自己实现bind方法,只需要直接在函数上调用即可
handler.handlerClick.bind(handler) ;
函数科里化
函数科里化是用于创建已经设置好一个或多个参数的函数。缩小了函数的适用范围,但提高函数的适性。例如:
//普通的add版本 function add(num1, num2){ return num1 + num2; } //第一个参数为5的add版本 function curriedAdd5(num2){ return add(5, num2) }
上面只是一个展示柯里化概念的例子。创建柯里化函数有一个通用方式:
function curry(fn, context){ //截取调用curry时候,除了fn,context,之后的所有参数 var args =[].slice.call(arguments,2); returnfunction(){ //获取调用fn的所有参数 var totalArgs = args.concat([].slice.call(arguments)); return fn.apply(context, totalArgs); } }
这样,上面的例子中curriedAdd5可以用另一个方法来创建
var curriedAdd5 = curry(add, null, 5)
javascript中的柯里化函数和bind函数提供了强大的动态函数创建功能,但是两者都不应该滥用,因为每个函数都带来额外的开销
相关文章推荐
- 借助 SublimeLinter 编写高质量的 JavaScript & CSS 代码
- JavaScript初学者难以知道的事(初级篇三)
- js常用操作
- JavaScript 函数中的值传递
- 理清JavaScript正则表达式--下篇
- JavaScript 字符串不变性
- 《Web开发过滤Javascript、HTML的方法》
- Js作用域与作用域链详解
- 用JS写Ajax的请求函数(1)
- 不同js异步函数同步的实现方法
- js获取键盘键值
- JSP---web.xml中设置前后台不同的头部和底部
- 4类 JavaScript 内存泄漏及如何避免
- javaScript取得当前元素的下一个元素
- js 给json添加新的字段,或者添加一组数据,在JS数组指定位置删除、插入、替换元素
- JSON基础学习
- js代码错误监控代码
- jstat命令
- JS设计模式之工厂模式
- 当返回不了json对象的时候