美文网首页
js常见知识漏洞整理

js常见知识漏洞整理

作者: Robin90 | 来源:发表于2018-06-24 12:19 被阅读8次

    前言

    本文主要摘录《js高级程序设计》,也就是我们常说的红宝书,其中一些比较少见的知识点,处理技巧。

    知识点列表

    理解内存回收机制要点 (gc)

    • 浏览器的gc机制并不是实时回收的,而是定时回收的,只是间隔时间很短。
    • 回收的原理是:每次去检查定义好的变量包括基本变量以及函数、对象,如果发现未被引用,就会回收。
    • 手动回收内存:当你不需要某变量时,从优化内存的角度,可以将其定义为null
    • 当你定义一个定时器或者逻辑死循环时,这部分是非常耗费内存的,甚至会导致页面崩溃,需要尽量避免

    为什么说eval是性能低下的

    因为默认的js是运行于浏览器的,而且其是在浏览器端编译后运行的,而不是和java一样编译好之后直接用class文件,所以为了解决这个性,我们只要处理自己时区的时间就可以,数据库存取的也是固定的一种时间,但是有些时候前端在读取以及新建今天或者某些非精准日期对象的时候,会因为数据库时间与当前客户端时间不一致导致各种问题。那么在解决这个问题之前,我们需要先了解下如何获取当前时间的时区。

    .getTimezoneOffset()能问题,js的解析器会进行语法优化,包括对你的词法分析,逻辑分析等,然后会进行一些优化,包括我们熟知的变量申明提前、重复语法声明等。

    而eval我们知道的是会自己创建解析环境,所以js解析器不会对其进行解析优化,所以其是低效的。

    document.domain

    • domain 属性可返回下载当前文档的服务器域名,domain 属性可以解决因同源安全策略带来的不同文档的属性共享问题。
    • domain只能设置为其当前域名或者其父级域名,不能设置为子级域名

    函数参数是为了使用方便

    我们知道一般定义函数的时候都会定义几个函数需要的形参,然后就在函数体内部就可以使用这个参数。但是呢,可能大多数人并不知道,即使我们不写形参,也可以通过arguments[index]的方式拿到对应位置的参数,如果这个参数没有传入,那么直接调用,其会是undefined.比如我们写一个加法函数:

    function add(){
    
    }
    

    时间对象的时区问题

    一般情况下,我们只要处理自己时区的时间就可以,数据库存取的也是固定的一种时间,但是有些时候前端在读取以及新建今天或者某些非精准日期对象的时候,会因为数据库时间与当前客户端时间不一致导致各种问题。那么在解决这个问题之前,我们需要先了解下如何获取当前时间的时区。
    date.getTimezoneOffset()/60,这个函数会返回当前时区的一个整形数字,然后我们可以根据当前的时间,以及数据库的时区,做转换以及对应关系,避免时区误差。

    作为常识,大家要知道北京的时区是-8区,那么对应的策略是什么呢?
    首先,对应的问题有哪些呢?
    1 产品需要确定数据库存储的时间时区是否是服务器所在时区的,还是存储的是用户所在时区的。如果是,又该如何显示,如何给用户解释这种时区误差。
    2 用户端在新建或者操作时间的时候,是否在源头控制时间,控制的话,让其输入的是本地时间还是服务器时间。
    3 服务器以及用户端对应的时区辨别要正确,精准,如果出现误差,其误差策略是什么。

    String 的substring()与substr() 方法区别

    一般情况下,我们很少会用到substr的方法,但是作为常识还是要清楚的知道两个的用途以及区别。

    substring(index1,index2) 可以得到从第一个指针到第二个指针的截取字符串,如果第二个比第一个小,两个指针会换顺序,如果第二个是负数,其会换成0,然后和前面的换位置。(不包括尾指针;如果超出尾部指针,最多截取到尾部)

    而subbstr(index,num)指的是从某个指针开始截取num的字符串。如果num为负数,肯定不返回的。

    Array的sort匿名方法

    一般情况下数组的简单排序我们可以通过默认的sort无参方法直接排序(如果省略,则根据每个元素的字符串转换,根据每个字符的Unicode代码点值对数组进行排序。),但是有时候如果我们想排序的内容 是字符串性质的数字和数字都有的,其会按照字母的编码排序,从而不能得到我们想要的结果。这个适合就需要在sort方法里,传入我们需要的排序函数。

    比如数组的从大到小(内容是数字或者数字的字符串),那么我们的sort匿名函数是这样写的:

    let arr = ['30',15,'100','92']
    let arr2 = arr.sort(function(a,b){
    return a-b
    })
    console.log(arr2)//从小到大排序
    //如果我们希望是其他的排序规则 比如说偶数在前 奇数在后
    
    

    其中排序的具体规则是这样的:

    如果compareFunction(a, b)小于0,则排序a到低于的索引b,即排a在第一位。
    如果compareFunction(a, b)返回0,离开a,并b相对于彼此不变,但对于所有不同的元素进行排序。注意:ECMAscript标准不保证这种行为,因此并非所有浏览器(例如,至少可以追溯到2003年的Mozilla版本)都尊重这一点。
    如果compareFunction(a, b)大于0,则排序b到低于的索引a,即b先到达。
    compareFunction(a, b)当给定一对特定的元素a和b作为其两个参数时,必须始终返回相同的值。如果返回不一致的结果,那么排序顺序是未定义的。

    再写一个案例 ,按照字符串的长短

    let arr = ['30',15,'100','92']
    let arr2 = arr.sort(function(a,b){
     let len = a.toString().length-b.toString().length
      if(len=0){
      return len
      }else {
      return a-b
      }
    })
    console.log(arr2)//字符串长度排序,从短到长;一样长度的用大小排序
    

    备注与拓展:在自定义函数中可以随便定义自己想要的排序规则,包括自己想对比的是属性还是方法,对比的原则是什么,都可以进行排序,这比我们进行自己写方法然后再空数组中push我们排序的部分要简洁、专业。

    switch 执行逻辑

    作为常识,大家都知道switch作为分支语句,其每个条件的运行结果是不一样的,并且在每个执行条件之后,都会写break,以提高代码的执行效率,那么如果没有break,程序会如何执行呢?我们写个例子测试下。

    其执行结果也许稍微和我们想的有点差异,首先其没有执行case 1的可以理解,但是不能理解的也许是其虽然不符合case 3,但是会执行其之后的switch分支语句的。

    let switchFn = function(i) {
      let result = 0 ;
      switch(i){
        case 1 :result = result + i;
        case 2 :result = result + 2*i;
        case 3 :result = result + 3*i; 
      }
      return result
    } 
    
    console.log(switchFn(2))//10
    

    关于option预检请求(preflight)

    一般情况下这个预检请求是发生在跨域的大前提下,浏览器对跨域下的请求分为两大类:分别为简单请求和非简单请求。那么不符合以下两个条件的就都是复杂请求,对于复杂请求,浏览器会发送一次option预检请求,如果服务器允许,那么再发送正常的请求。

    那么,简单请求的要求是 :

    一 请求方法是以下三种方法之一:
    HEAD
    GET
    POST
    二 HTTP的头信息不超出以下几种字段:
    Accept
    Accept-Language
    Content-Language
    Last-Event-ID
    Content-Type:只限于三个值application/x-www-form-urlencoded、multipart/form-data、text/plain

    相关文章

      网友评论

          本文标题:js常见知识漏洞整理

          本文链接:https://www.haomeiwen.com/subject/jeijyftx.html