总结篇(一) -- 基础知识

移动端适配

  1. 使用 <meta> 标签

    1
    <meta name='viewport' content=' width=device-width user-scalable=no initial-scale=1.0 maximun-scale=1.0 minimum=1.0 ' >

    这个标签主要作用是网页宽度默认等于屏幕宽度,用户不可以缩放,缩放比例1。

  2. 使用 Media Query(媒体查询) 模块
    通过媒体查询,从而判断采用的样式
    主要是有两种方式:

    • 元素中的媒体查询

      1
      <link rel='stylesheet' href='./css/style.css' media='(min-width: 800px) and (max-width: 1400px)' >

      这个标签表示只有 width 在 800px-1400px 时才采用 style.css 这个样式表

    • 样式表中的媒体查询
      在样式表中书写媒体查询

      1
      2
      3
      4
      5
      @media (max-width: 414px){
      .button{
      display: block;
      }
      }

      上述代码表示:当宽度小于 414px 的时候,button 元素显示在页面中

  3. 动态rem
    一切以宽度为基准。
    rem是根元素(html)的 font-size 的值,我们可以使用 JS 实现将 html 的 font-size 设置为屏幕宽度,之后 rem 就和屏幕宽度有一定的映射,当然也可以设置为屏幕宽度的 1/2 ,之后使用 rem 实现元素的宽高 margin padding 等需求。

  4. 在做移动端适配的时候还要注意一些小问题

    • 移动端没有 hover 事件,但是有 touch 事件
    • 移动端没有 resize 事件,没有滚动条
    • rem 单位可以和其他单位混用,例如:border: 1px solid red

闭包

  1. 闭包指一个函数或函数的引用与一个引用环境绑定在一起,这个引用环境是一个存储该函数每个自由变量的表。简单的说就是自由变量和引用这个自由变量的函数就是闭包。闭包可以读取其上作用域链中的值。

    1
    2
    3
    4
    5
    var a = 1
    function fn(){
    console.log(a)
    }
    fn.call(undefined) // 调用之后,会打印出1

    上述的变量 a 和函数 fn 即是闭包

  2. 当我们在写代码的时候,会在无形之中就使用到了闭包。

  • 用途一:读取其上作用域链中的值。例如在全局作用域中定义了 a 和函数 fn,在 fn 中并没有定义 a ,但是却可以使用全局变量 a。参照上面例子。

  • 用途二:让自由变量保存在内存中,即封装变量
    在全局代码执行的时候,会产生一个全局执行上下文环境(Execution Context)。调用函数的时候,会产生一个函数执行上下文环境(Execution Context)。当函数调用结束后,函数执行上下文环境和其中的数据将被消除,重新回到全局执行上下文环境。但是当在函数执行上下文的环境中存在闭包,那么即使这个函数调用完成,其执行上下文环境也不会被消除,因为还有闭包被引用着。

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    function fn1(){
    var a = 1
    addA = function(){ // 此处不用 var 声明,从而创建一个全局变量,但是其可以引用局部变量 a
    a++
    }
    function fn2(){
    console.log(a)
    }
    return fn2
    }
    result = fn1.call(undefined)
    result() // 打印出 1
    addA()
    result() // 打印出 1

    当调用完 fn1 之后,局部变量 a 并不能被垃圾回收,因为 fn1 返回的函数仍然调用局部变量 a ,此时的局部变量 a 就被保存在内存中

    在函数内部定义局部变量,外部不能访问,但是闭包仍能访问到这个局部变量,外部如果要访问局部变量,只能通过函数 return 出来的接口。

call、apply、bind

这三个方法都挂载在 Function.prototype 上,都是函数的方法,可以调用函数

call()

  • 作用:
    切换上下文(this)
    操作参数

  • 当使用 call() 调用一个函数的时候,call() 的第一个参数是 this ,第二个参数是需要传递给函数的实参(arguments)。

    1
    fn.call( this , arguments )

apply()

  • 作用:

    切换上下文(this)
    操作参数

  • 当使用 apply() 调用一个函数的时候,apply() 的第一个参数是 this,第二个参数是一个数组,apply() 方法会将数组中的元素拆分依次传入到函数中。

    1
    fn.apply( this , [ 1,2,3 ] )

bind()

  • 作用:

    切换上下文(this)
    科里化,即部分求值,函数调用是可以传递参数,之后返回的函数(闭包)也可以接收参数

  • 当使用 bind() 调用一个函数的时候,bind() 方法会返回一个函数,他的第一个参数是 this ,第二个参数是需要传递给函数的实参

    1
    2
    let curryFn = fn.bind( this , param1 , param2 )
    curryFn( param3 , param4 )

HTTP POST 请求

1
2
3
4
5
6
7
8
1 POST /path HTTP/1.1
2 Host: passport.baidu.com
2 User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/62.0.3202.62 Safari/537.36
2 Accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,image/apng,*/*;q=0.8
2 Content-Length: 24
2 Content-Type: application/x-www-form-urlencoded
3
4 username=ff&password=123

数组去重

对象键值对法。遍历数组时看对象中是否有 key

1
2
3
4
5
6
7
8
9
10
11
function unique(arr){
var newArray = []
var obj = {}
for( var i = 0, len = arr.length; i < len; i++ ){
if( !obj[ arr[ i ] ] ){
obj[ arr[ i ] ] = 1
newArray.push( arr[ i ] )
}
}
return newArray
}

Set 对象

1
2
3
function unique(arr){
return newArr = Array.from(new Set(arr))
}

数组下标判断。遍历数组是看相应值的下标是否和索引相同

1
2
3
4
5
6
7
8
9
function unique(arr){
let newArray = []
arr.forEach( (value,index) => {
if( array.indexOf( value ) === index ){
newArray.push( value )
}
} )
return newArray
}

遍历数组法。遍历数组时看新数组中有没有该值

1
2
3
4
5
6
7
8
9
function unique(arr){
let newArray = []
arr.forEach( (value,index) => {
if( !newArray.includes( value ) ){
newArray.push( value )
}
} )
return newArray
}