JS高级程序读书笔记(2)

复制
  • 基本类型:从一个变量向另一个变量复制基本类型的值,会创建这个值的一个副本。两个值是独立的。基本类型值在内存中占据固定大小的空间,因此被保存在栈内存中。

    1
    2
    3
    4
    5
    var num1 = 5
    var num2 = num1
    num1 ++
    num1 //6
    num2 //5
  • 引用类型:从一个变量向另一个变量复制引用类型的值时,新变量分配的空间中存放的副本是一个指针,这两个变量都指向存储在堆内存中的同一个对象。

执行环境&作用域
  • 执行环境有全局执行环境函数执行环境之分。全局执行环境(window对象)是最外围的一个执行环境,关闭网页或浏览器时全局执行环境被销毁

  • 每个函数都有自己的执行环境,当执行流进入一个函数时,函数的环境就会被推入一个环境栈中。而在函数执行之后,栈将其环境弹出,把控制权返回给之前的执行环境。

  • 每次进入一个新的执行环境,都会创建一个用于搜索变量和函数的作用域链。

    1
    当引用一个变量时,会从当前作用域开始搜索查询,然后逐级向上搜索,如果一直追溯到全局环境没找到这个变量,说明该变量尚未声明。
垃圾收集
  • JS具有自动垃圾收集机制,即找出那些不再使用的变量打上标记,然后释放其占用的内存空间。

    1
    最常用的垃圾收集方式是标记清除(mark-and-sweep),垃圾收集器在运行的时候会给存储在内存中的所有变量加上标记----> 去掉环境中的变量和被环境中变量引用的变量的标记 -----> 在此之后变量被打上标记视为准备删除的变量
  • 内存管理—解除引用:一旦数据不再有用,可将其设置为null

    1
    2
    3
    4
    5
    6
    7
    function fn(name){
    var localPerson = new Object()
    localPerson.name = name
    return localPerson
    }
    var globalPerson = fn('tom')
    globalPerson = null //对于全局变量而言,需要手动解除
对象的属性表示
  • person.name === person[“name”] ,使用方括号语法时,里面的属性是字符串的形式
  • person[“first name”],如果属性名中包含会导致语法错误的字符,或者属性名使用的是关键字或保留字,也可以使用方括号表示法
数组
  • 给数组添加新的项:var arr = [1, 2, 3, 4]

    • arr[arr.length] = 5 //[1, 2, 3, 4, 5]

    • arr.push(5,6) //返回数组长度6 ,原数组变为[1, 2, 3, 4, 5, 6]

      arr.pop()

      arr.unshift()

      arr.shift()

    • arr.splice(index, howmany, itmes)

  • 判断数组:Array.isArray(arr)

  • 重排序方法

    • arr.reverse()

    • arr.sort(value1,value2)

      1
      2
      3
      4
      var arr1 = [3,5,2,4,1]
      var arr2 = arr1.sort((value1,value2)=>{
      return value1 - value2
      })
  • arr.concat()

    • arr.slice(start,end)

    • 位置方法:arr.indexOf(searchElement,startIndex) :没有找到就返回-1

      string也有atr.indexOf() 方法(根据内容找index),str.charAt(index) (根据index找内容)

  • 迭代方法

    • forEach(item, index, array) :没有返回值

    • map(item, index, array) :返回数组

    • filter(item, index, array) :返回满足条件true的数组

    • every(item, index, array) :返回布尔值

    • some(item, index, array) :返回布尔值

  • 归并方法:reduce(preValue, currentValue, currentIndex, array, initialValue)

    1
    2
    3
    4
    5
    6
    #数组求和
    var arr = [1,2,3,4]
    var sum = arr.reduce((pre,cur){
    return pre+cur
    },7)
    sum // 17
Date

1970年1月1日午夜(零时)开始经过的毫秒数保存日期

  • Date.now():返回距离1970年1月1日的毫秒数

  • 指定生成日期new Date("Mar 18, 1992")或者 new Date(1992,2,18,17,03,55)

    1
    2
    3
    4
    new Date("Mar 18, 1992") 字符串格式
    ----------
    new Date(1992,2,18,17,03,55) 分别对应年,月(从0开始),日,时(0~23),分,秒
    //Wed Mar 18 1992 17:03:55 GMT+0800 (中国标准时间)
  • toString()toLocalString()valueOf()

    1
    2
    3
    4
    var a = New Date()
    a.toString() //"Fri Mar 30 2018 16:14:34 GMT+0800 (中国标准时间)"
    a.toLocalString() //"2018/3/30" 返回当地时间格式
    a.valueOf() //1522397674376 返回毫秒数
  • getFullYear():年份

    getMonth():月份,0表示1月

    getDate():天数

    getDay():返回星期几,0表示周日

    getHours():小时

    getMinutes():分钟

    getSeconds():秒

#####this

this引用的是函数执行时所在的环境对象(谁调用指向谁),es6的箭头函数体内的this引用的是函数定义时的环境对象

函数的属性和方法
  • 2个属性:

    • length:函数希望接收到参数的个数
    • prototype:保存所有实例方法的属性
  • 2个方法:每个函数都有两个非继承而来的方法,apply和call,他们的作用是在特定的作用域中调用函数,相当于设置函数体内this对象的值。

    • call():第一个参数是this(运行函数的作用域),其余的参数直接传递给函数(必须逐个列举出来)

    • apply():第一个参数是this,其余的参数可以是arguments对象,也可以是Array的实例

      1
      2
      3
      4
      5
      6
      7
      8
      9
      10
      11
      12
      13
      14
      15
      function sum(n1, n2){
      return n1 + n2
      }
      function callSum1(n1, n2){
      return sum.call(this, n1, n2) //必须逐个列举
      }
      function callSum2(n1, n2){
      return sum.supply(this, arguments) //传入arguments对象
      }
      function callSum3(n1, n2){
      return sum.apply(this, [n1, n2]) //传入数组
      }
      callSum1(10, 10) //20
      callSum2(10, 10) //20
      callSum3(10, 10) //20
    • bind():创建一个函数的实例(新函数),this值被绑定到传入bind()函数的第一个参数

      1
      2
      3
      4
      5
      6
      7
      8
      9
      var o = {color:"red"}
      var color = blue
      function fn(){
      console.log(this.color)
      }
      fn() //blue,这里this引用的是windows环境对象
      -----------
      var xxx = fn.bind(o)
      xxx() //red 即fn.bind(o)()
基本包装类型

每当读取一个基本类型值得时候,后台会创建一个对应的基本包装类型的对象,从而让我们能够调用一些方法来操作这些数据。有了基本包装类型, js中的基本类型值可以被当作对象来访问。三种基本包装类型有string,boolean,number

  • 每个包装类型都映射到同名的基本类型
  • 访问基本类型值时,会创建对应的基本包装类型对象,从而方便数据操作
  • 操作完毕后,立即销毁新创建的包装对象
1
2
3
4
5
6
var s1 = "heihei"
var s2 = s1.substr(3,2) //"hei" s1是基本类型不是对象,逻辑上不应该有方法
----------实际上执行到第二段代码时,后代自动完成下列处理
var s1 = new String("some text"); 创建String实例 s1 instanceof String //true
var s2 = s1.substring(2); 在实例上调用指定的方法
s1 = null; 销毁这个实例
1
2
3
4
# 引用类型与基本包装类型的主要区别就是对象的生存期。使用new 操作符创建的引用类型的实例,在执行流离开当前作用域之前都一直保存在内存中。而自动创建的基本包装类型的对象,则只存在于一行代码的执行瞬间,然后立即被销毁。这意味着我们不能在运行时为基本类型值添加属性和方法。
var s1 = "some text"; //与 new String("some text")是有区别的
s1.color = "red";
alert(s1.color); //undefined
String类型
  • str.charAt(index) :返回位置字符

  • str.charCodeAt(index) :返回字符编码

  • str.indexOf(content) :根据字符查找index

    str.lastIndexOf()

    str.search(RegExp) :找到首个匹配成功的index,没有返回-1(可以用正则)

  • str.concat(str2,str3) :拼接字符串

  • str.slice(start, end) :如果参数为负数,被str.length + 负数 看待

    str.substring(start, end) :会自动调整start和end,较小的数字在前。任意参数小于0或者为NaN,会被视为0

    str.substr(start, length) :length为0或者负数,返回空字符串””, start为负数,从末尾开始往右取值

    1
    2
    3
    4
    var stringValue = "hello world";
    alert(stringValue.slice(3, 7)); //"lo w"
    alert(stringValue.substring(3,7)); //"lo w"
    alert(stringValue.substr(3, 7)); //"lo worl"
  • str.trim() :除去字符串两端的空格

  • str.toLowerCase() && str.toUpperCase()

  • str.match(RegExp) : 返回满足条件的数组,如果正则不带g,与RegExp.exec(str)相同效果,返回第一个匹配到的元素数组,并带有index和input(原字符串)属性

  • str.replace(RegExp|str, newStr|function(match,index,str)

    1
    2
    3
    4
    交换两个字符串的位置
    var str = "Tom Jack"
    var reg = /(\w+)\s(\w+)/
    var newStr = str.replace(reg, "$2 $1") //$n表示第n个被捕获的内容
  • str.split([separator[, limit]])

Math对象
  • 四舍五入:

    • Math.floor(num) :往下舍入
    • Math.ceil(num) :往上舍入
    • Math.round(num) :四舍五入
  • Math.random(num)

    1
    2
    3
    4
    5
    #在某个整数范围内随机一个值
    值 = Math.floor(Math.random() * 可能值的总数 + 第一个可能的值)
    ---------
    取2~10的随机整数
    var random = Math.floor(Math.random * 10 + 2)
  • Math.abs(num) :绝对值