• 高级函数


    高级函数

    安全的类型检测

    • js内置的类型检测并非完全可靠,typeof操作符难以判断某个值是否为函数
    • instanceof在多个frame的情况下,会出现问题。 
      例如:var isArray = value instance of Array ; 
      会由于存在多个window,而value与Array不属于同个window的情况而导致出错

    对于这样的问题,最好的解决方法是通过调用Object的toString方法,例如:

    1 function isArray(){
    2     return Object.prototype.toString.call(value) == "[object Array]";
    3 }

    注意,这个技巧前提是Object.prototype.toString方法未被修改过

    作用域安全的构造函数

    调用构造函数的时候,如果忘记写new的话,构造函数中对this的赋值,则可能会赋值到window上成为全局变量,导致其他错误。 
    可以在构造函数增加判断来避免这种错误,如下:

    复制代码
    1 function Person(name){
    2     if(this instanceof Person){
    3         this.name = name;
    4     }else{
    5         return new Person(name)
    6     }
    7 }
    复制代码

    惰性载入函数

    在程序中 ,类似对浏览器的检测等,进行一次检测过后,只要在当前环境下,其检测结果都不会改变。所以,我们的函数中 if 语句只需要判断一次就可以了,而不需要每次都执行。 
    对这种情况的解决方案便称为惰性载入。 
    惰性载入表示函数执行的分支仅会发生一次。

    惰性载入两种实现方法:
    • 替换真正执行的方法,伪代码如下:
    1. 复制代码
      1 function foo(){
      2     if(someCheck){
      3         foo =function(){doSomeThing()};
      4     }else{
      5         foo =function(){doAnotherSomeThing()};
      6     }
      7 }
      复制代码
    • 声明函数时就指定适当的函数。通过匿名自执行函数
    • 复制代码
      1 var foo =function(){
      2     if(someCheck){
      3         returnfunction(){doSomeThing()};
      4     }else{
      5         returnfunction(){doAnotherSomeThing()};
      6     }
      7 }();
      复制代码

    这样,在代码首次载入的时候,就已经得到对应的值了

    函数绑定

    先看一个例子:

    复制代码
     1 var handler ={
     2     message:"handler message",
     3     handlerClick:function(event){
     4         console.log(this.message);
     5     }
     6 }
     7 //用于将某个函数绑定到指定环境
     8 var bind =function(fn, context){
     9     returnfunction(){
    10         fn.apply(context, arguments);
    11     }
    12 };
    13 var nomalBtn = document.getElementById("nomalBtn");
    14 var bindBtn = document.getElementById("bindBtn");
    15 nomalBtn.addEventListener("click", handler.handlerClick,false);//点击时候会打印 undefined
    16 bindBtn.addEventListener("click", bind(handler.handlerClick,handler),false);//点击按钮会打印 handler.message的值
    复制代码

    在上面的例子中,我们需要对象中的方法作为事件处理程序。但是,当事件触发时,this的指向却不是handler而是按钮本身。 
    解决方法可以使用匿名函数,但是,过多的匿名函数会令代码变的难于理解与调试,因此,推荐使用bind方法。

    ES5 为函数定义了一个原生的bind方法,也就是说,你不必自己实现bind方法,只需要直接在函数上调用即可handler.handlerClick.bind(handler) ;

    函数科里化

    函数科里化是用于创建已经设置好一个或多个参数的函数。缩小了函数的适用范围,但提高函数的适性。 
    例如:

      

    复制代码
    1 //普通的add版本
    2 function add(num1, num2){
    3     return num1 + num2;
    4 }
    5 //第一个参数为5的add版本
    6 function curriedAdd5(num2){
    7     return add(5, num2)
    8 }
    复制代码

    上面只是一个展示柯里化概念的例子。创建柯里化函数有一个通用方式:

    复制代码
    1 function curry(fn, context){
    2 //截取调用curry时候,除了fn,context,之后的所有参数
    3     var args =[].slice.call(arguments,2);
    4     returnfunction(){
    5 //获取调用fn的所有参数
    6         var totalArgs = args.concat([].slice.call(arguments));
    7         return fn.apply(context, totalArgs);
    8     }
    9 }
    复制代码

    这样,上面的例子中curriedAdd5可以用另一个方法来创建 var curriedAdd5 = curry(add, null, 5)

    javascript中的柯里化函数和bind函数提供了强大的动态函数创建功能,但是两者都不应该滥用,因为每个函数都带来额外的开销

  • 相关阅读:
    linux 常用命令行
    二叉搜索树(BST)
    pytorch Gradient Clipping
    python 读写文件
    我终于可以毕业啦!
    为什么有可执行文件还需要库文件
    java常识
    *args、*kwargs
    win终端命令
    import_module
  • 原文地址:https://www.cnblogs.com/214829qw/p/5537509.html
Copyright © 2020-2023  润新知