函数及函数优化

1. 函数构造方法: js中所有函数的构造函数都是Function,包括Function本身,(Function是自己的实例,也是自己的构造函数)

证明:
 Function.prototype === Function.__proto__

1.1 函数声明: function 函数名(){}

1.2函数表达式: var 函数名 = function(){};

1.3构造函数: var 函数名 = new Function(参数1,参数2,函数体);

    1. 不传参数创建出来的是空函数.
    2. 一个参数:函数体(字符串).
    3. 传多个参数的情况:(字符串).
    例:简单的求两个数和:   
     var sum = new Function(‘a‘,‘b‘,‘return a + b‘);
        sum(1,2);
        注:传参数时候可以使用:拼接字符串或反引号(ES6方法)或者创建模板引擎

2. 访问函数的方法:

2.1. 函数调用模式: 函数名();

    this:指向window

2.2. 方法调用模式: 对象.函数名();

    this:谁调用就指向谁

2.3. 构造函数调用模式 :new 函数名();

    this:指向new出来的对象

2.4. 上下文调用模式 : 解决this作为左值不能赋值的问题

    左值(LValue):能正常的在等号左边被赋值的值
    右值(RValue):能正常的在等号右边赋值的值
* 语法:1 函数名.call(this指向,实参,实参)
    注意:  1当传入的第一个参数为undefined或Null时,指向的是window
           2当传入的第一个参数为简单数据类型时,this指向该数据的基本包装类型
* 语法:2 函数名.apply(this指向,数组或伪数组)
    注意:第一个参数与call语法相同,后面的数组参数中的元素拆解后传给函数

3. eval(符合js语法规范的字符串) 函数:

* 功能:将字符串转化为代码并执行;
*    1.eval与Function()的共同点:将字符串转化为代码;
    2.不同点:Function()转化成代码之后是函数,需要手动调用才能执行,eval()会直接执行
* Function与eval的问题
    1.需要预解析,执行效率问题
    2.安全性问题(如果别人输入的内容符合规范,可以进行跨站脚本攻击xss)
    3.eval会将json字符串中的{}当做代码段处理,所以会报错
        处理:在json字符串外面拼接小括号易形成一段完整的语句;
            把变量声明也写在eval参数中:
  var jsonStr = {"key":"value"};
  eval("var obj =" + jsonStr);

4. json2.js:引入解决IE7及以下版本JSON未定义问题。

json2.js提供了json的序列化和反序列化方法,可以将一个json对象转换成json字符串,也可以将一个json字符串转换成一个json对象。
源码地址:https://github.com/douglascrockford/JSON-js

4.1. json2.js使用基本模型:

//在页面中添加json2.js的引用。

<--引入json2.js文件-->

<script type="text/javascript" src="JS/json2.min.js"></script>  

   //序列化方法

   var jsonObj = { id: ‘01‘, name: ‘Tom‘ };
    JSON.stringify(jsonObj);
    //反序列化方法
    var jsonString = ‘{ "id": "01", "name": "Tom" }‘;
    JSON.parse(jsonString);

5. 函数对象的成员

* arguments
* caller    函数在哪个环境中调用的,就指向谁,如果函数是在全局环境下调用的,指向Null
* length    形参个数
* name    函数函数声明与函数表达式创建出的name为函数名,new Function()创建的函数name为‘anonymity‘

5.1. arguments对象:是一个函数内部的对象(执行环境在函数内部),是伪数组.

1  伪数组:有length属性(但是不会动态改变),可以被遍历,但没有数组的方法.
2  arguments对象:
    * 作用:当函数调用的时候会将所有实参一次存入伪数组中(无论形参与实参个数是否对应).
    * 应用场景:当时参数个数不确定的时候,就可以不用写形参直接用arguments    获取实参.
    * 属性:
        1.length    判断用户调用函数时输入的实参个数
        2.callee    指向    arguments对象 所在的这个    函数!

6. 重载:overload

重载:根据参数个数的不同,调用相同函数名函数不同的功能;
JavaScript没有重载!不过可以根据arguments属性的长度判断来模拟重载.

7. 静态成员与实例成员

7.1. 静态成员:通过构造函数去访问的成员

一般将工具方法,比如($.ajax)设置为静态成员

7.2. 实例成员:通过对象去访问的成员

一般将于对象相关的成员,比如(.css) 设置为实例成员

8. 作用域:

8.1. 词法作用域(静态作用域): 在代码写好的时候,根据代码的书写结构确定变量的作用域

8.2. 动态作用域: 根据代码的调用环境确定变量的作作用域. JavaScript没有动态作用域!!

作用域的意义:保护变量.

8.3. JavaScript代码执行顺序:

1 预解析阶段:会对变量的声明(变量只提升声明以及函数的声明提升到其当前作用域的顶部!    变量提升(hoisting)
    * 函数形参赋值的过程是在 函数与变量提升之前
    * 当两个函数同名的时候两个函数都会提升
    * 当函数与变量同名的时候,会忽略变量声明,只提升函数声明
    * 就算有多个script标签,全局作用域也只有一个,但声明提升是分段的
    * 条件式函数声明在变量提升的时候会将条件是函数声明当做函数表达式处理只会提升函数名)
    注:条件式函数声明:在条件语句中的函数声明
2 自上而下执行

9. 沙箱模式: JS中的沙箱模式通过函数去实现的

沙箱模式的基本模型:
   (function(window){
        //声明所有需要的变量
        //写主要的功能代码
        //如果需要,就通过window对象向外界暴露接口
    })(window)

9.1. 沙箱模式为什么要把window做为参数传进去?

    1. 有利于代码压缩,因为原生的内置对象无法被压缩,使用形参接收后,形参是可以被压缩的
    2. 实现隔离的思想,外界不直接去使用内部的东西,内部也不直接去访问外部的任何东西!
    3. 沙箱的参数不都是window,而是如果要在沙箱内部使用沙箱外部的东西就需要把该东西当做参数,传递进沙箱内部!

9.2. 沙箱模式应用在哪里?

    1. 框架
    2. 组件
    3. 插件

10. 递归

1 定义:在一个函数 通过名字直接或间接地调用自身
2 用递归解决问题的关键点:化归思想.
    例:    斐波那契数列第n项

   function fib(n){
        if(num <= 2) {
            return 1;
        } else {
            return fib(n - 1) + fib(n - 2);
        }
    }
    console.log(fib(6));

3   * 递归的问题:时间复杂度多,产生多次重复计算发生效率问题 ,
    * 解决方案:可以使用缓存容器解决;
    例:  斐波那契数列第n项

function recursive() {
       var arr = [];             //记录已经找到的项,作为缓存,免于递归重复计算
       return function(n) {
        if (!arr[n]) {         //判断数组中有没有这一项,有的话直接返回
               if (n <= 2) {
                   arr[n] = 1;
                } else {
                   arr[n] = outer(n - 1) + outer(n - 2);
               }
           }
        return arr[n];
    }
}
var fib = recursive();
console.log(fib(1000));


11. 闭包

11.1. 定义: 一个具有封闭的对外不公开的包裹结构, 或空间.(有权访问另一个函数作用域中的变量的函数)

11.2. 概念:可以访问独立数据的函数

11.3. 作用:

    * 1.保护数据
    如果直接将数据定义全局中,那么将对数据失去控制权
    使用闭包可以将数据保护起来,外界想要访问数据,必须通过指定的渠道,而制定渠道的方法,就是建立一个函数,在函数中建立校验机制以保证数据的合理性与安全性.
    * 2.可以给函数提供私有的变量

闭包的基本模型:

   function outer(){
        var a = 10;
        var inner = {                //将两个方法封装为一个对象
            getA:function(){        //获取数据
                return a;
            },
            setA:function(形参){    //通过传入参数,设置数据
                //可以在这建立校验机制以保证数据的合理性与安全性
                a = 形参;
              return a;                //也可以不返回,只是设置
            }
        }
        return inner;
    }
    var getFun = outer();            //先调用,再赋值,返回的是inner对象
    console.log(getFun.getA());        //获取a
    console.log(getFun.setA(实参));    //设置a
    console.log(getFun.getA());        //再次获取的为修改后的a            


实例:用延时定时器,逐个打印数字

 for (var i = 0; i < 10; i++) {
        function outer() {
             var j = i;
              function inner() {
                  console.log(j);
             }
            return inner;
        }
            setTimeout(outer(),1000*i);
 };

11.4. 闭包的问题:不合理的使用会造成内存泄露,,因为闭包的内存空间会常驻内存,造成资源损耗

12. JS是单线程的语言:

js中的任务: 在执行完主要任务之后才会执行次要任务

    *主要任务(主逻辑代码)
    *次要任务(例如setTimeout()与setInterval())

13. 缓存:将数据临时存储起来,避免重复计算,以提高用户访问效率

13.1. 浏览器缓存:

将网站资源在浏览器端进行保存,用户在请求服务器的时候,这些被保运的资源直接从本地读取而不必去服务区读取,从而提高用户访问速度;

13.2. CDN:

* CDN系统能够实时地根据网络流量和各节点的连接、负载状况以及到用户的距离和响应时间等综合信息将用户的请求重新导向离用户最近的服务节点上。使用户可就近取得所需内容,解决 Internet网络拥挤的状况,提高用户访问网站的响应速度。CDN的关键技术主要有内容存储和分发技术。
* 实现原理:CDN广泛采用各种缓存服务器,在用户访问网站时,利用全局负载技术将用户的访问指向距离最近的缓存服务器上,由缓存服务器直接响应用户请求。

13.3. 数据库缓存:

静态的网站的内容都是些简单的静态网页直接存储在服务器上,可以非常容易地达到非常惊人的访问量。但是动态网站因为是动态的,也就是说每次用户访问一个页面,服务器要执行数据库查询,启动模板,执行业务逻辑到最终生成一个你所看到的网页,这一切都是动态即时生成的。从处理器资源的角度来看,这是比较昂贵的。
对于大多数网络应用来说,过载并不是大问题。但是对于中等至大规模流量的站点来说,尽可能地解决过载问题是非常必要的。

13.4. 硬件缓存:

这是另一个领域的问题,这里暂时不做具体研究,有机会深入接触后再作补充

转自.cnblogs.com/canday/p/6220697
时间: 2024-10-04 01:13:00

函数及函数优化的相关文章

函数的调用优化

函数的调用优化 在类中有四大成员函数,构造函数,拷贝构造函数,赋值函数和析构函数,在类外进行实例化时,若调用函数的方法不当则会产生时间和空间的浪费. 以下,将用几个小栗子来说明函数的调用优化的常见办法 类: class Test { public: Test(int d = 0) : _data(d) { cout << "Create Test Object:"<<this << endl; } Test(const Test&x) :_d

Lua function函数,可变参数, 局部函数,尾递归优化

在Lua中,函数是作为"第一类值"(First-Class Value),这表示函数可以存储在变量中,可以通过参数传递给其他函数,或者作为函数的返回值(类比C/C++中的函数指针),这种特性使Lua具有极大的灵活性. Lua对函数式编程提供了良好的支持,可以支持嵌套函数. 另外,Lua既可以调用Lua编写的函数,还可以调用C语言编写的函数(Lua所有的标准库都是C语言写的). 定义一个函数 function hello() print('hello') end hello函数不接收参数

写日志函数和持续优化

首先看下面的函数 <span style="font-size:18px;">void writelog(char* file, char* msg) { FILE*fp=NULL; int nDataLen = strlen(msg); fp=fopen(file,"ab+");//只供读取 if(fp!=NULL) { fwrite(msg, nDataLen, 1, fp); } fclose(fp);//关闭文件 }</span> 这

FFmpeg av_probe_input_buffer函数剖析以及优化

函数调用关系av_probe_input_buffer调用av_probe_input_buffer2进行整一个码流格式的分析过程.其中调用avio_read进行码流数据的读取,将缓存数据保存在AVProbeData定义的buf里面,然后调用av_probe_input_format2(AVProbeData *pd, int is_opened, int *score_max)函数去猜测码流格式,其中包裹最终的调用函数av_probe_input_format3. 优化方向如果知道AVInpu

第17课-数据库开发及ado.net 聚合函数,模糊查询like,通配符.空值处理.order by排序.分组group by-having.类型转换-cast,Convert.union all; Select 列 into 新表;字符串函数;日期函数

第17课-数据库开发及ado.net 聚合函数,模糊查询like,通配符.空值处理.order by排序.分组group by-having.类型转换-cast,Convert.union all;  Select 列 into 新表;字符串函数;日期函数 SQL聚合函数 MAX(最大值).MIN(最小值).AVG(平均值).SUM(和).COUNT(数量:记录的条数) 聚合函数对null不计算.如果一行数据都是null,count(*)包含对空值行.重复行的统计. --聚合函数演示 selec

JavaScript中的匿名函数及函数的闭包以及作用域

1. ? 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85

函数和函数的作用域问题,arguments

this的值:在函数执行时,this关键字并不会指向正在运行的函数本身,而是指向调用该函数的对象.所以,如果你想在函数内部获取函数自身的引用,只能使用函数名或者使用argument.callee属性(严格模式下不可用),如果该函数是一个匿名函数,则你只能使用后者. 1.定义函数 三种方式: 1)函数声明 (function语句) function name([param[, param[, ... param]]]) { statements } name函数名. param函数的参数的名称,一

逆向知识十一讲,识别函数的调用约定,函数参数,函数返回值.

逆向知识十一讲,识别函数的调用约定,函数参数,函数返回值. 在反汇编中,我们常常的会看到各种的函数调用,或者通过逆向的手段,单独的使用这个函数,那么此时,我们就需要认识一下怎么识别函数了. 一丶识别__cdecl 函数(俗称C Call),函数参数,函数返回值 首先写一个C Call的函数 1.返回值 int类型, 参数int 类型 高级代码: int __cdecl MyAdd(int a,int b) { return a + b; } int main(int argc, char* ar

MySQL高级查询函数(单行函数)

函数的分类:1,单行函数:对每一条记录输入值进行计算,得到相应的计算结果,返回给用户,也就是说,每条记录作为一个输入参数,经过函数计算得到每条记录的计算结果.2,多行函数:对多条记录输入值进行计算,得到多条记录对应的单个结果. 单行函数: ①:字符串函数(用户处理单行的字符数据,比如大小写转换,字符串截取,拼装等) a.LOWER/UPPER(LOWER(str):返回字符串str变为小写字母的字符串.UPPER(str):返回字符串str变为大写字母的字符串) SELECT UPPER(nam