Skip to content

变量命名法则

  • 由数字、字母、下划线、$组成,不能以数字开头,可以以下划线、​ 美元符号开头
  • 不能和关键字、保留字同名

利用取余定义范围

  • 实现在一个范围之内取一个随机数

逻辑运算符细节

js
a = 5 && 8
  • 上面表达式的值为 8。
  • &&先判断左边是否为真,为真就把右边的值赋给逻辑表达式。左边为假就把左边的值赋给逻辑表达式
js
a = 0 || 100
  • 上面表达式的值为 100。
  • ||先判断左边的值是否为真,为真那么就取左边的值赋给逻辑表达式。如果左边为假那么就把右边的值赋给表达式

while 循环特点

  • 对比for循环可以实现更加复杂的循环体,适用于不确定循环次数时
  • 会弹出一个对话框,只有当输入你真好字符串时才会结束循环,不然会一直弹出对话框
js
var num = prompt('你真好')
while (num !== '你真好') {
  var num = prompt('你真好')
}
alert('你真好啊')
  • do while是先执行循环体再判断条件表达式
js
var num = 0
do {
  console.log(num)
  num++
} while (num <= 10)

强制类型转换

js
var a = '1'
a = Number(a)
  • 上面 a 的值最后是一个数值型的值。

  • **Number()**能强制转换数据为数值number类型,当传入的值为一个非数值类型的字符串会输出为NaN“name”转换的就是NaNNaN也属于数值类型

    • 当传入的是一个空值,那么结果会是0
    • 转化true为 1,false为 0
    • 转化undefinedNaN
    • 转化null为 0
  • **String()**能强制转换数据为字符串

    • 转化数字,原样变为字符串如1.234转化后为“1.234”
    • 转化布尔值如true变为“true”false转化为“false”
    • 转化undefined“undefined”,转化null“null”
  • **Boolean()**能强制转换数据为布尔类型

    • 除了0“”(空字符串)、undefinednullNaNfalse其他都是true
js
var a = '123.3aaa'
  • parseInt从字符串中提取整数。parseInt(a)结果是123
  • parseFloat从字符串中提取浮点数(小数)parseFloat(a)结果是123.3
js
var a = 'name123.3'
var b = 'name123.3name'
  • 这两种情况下parseIntparseFloat的结果都是NaN
  • parseIntparseFloat在转换时如果第一个字符不是数字那么就直接输出NaN
js
var a = '123na456me'
  • 这种情况下两个函数都输出123

基本数据运算

  • 同种数据类型比较和运算

    • 字符串和字符串

      • 一个字符串减去一个字符串结果是NaNNaN - NaN=NaN

      • 如果是比较大小时实际上是比较Unicode值,直接从第一个字符开始比较,谁Unicode值大那么这个字符串值大

      • js
        var a = 'abc'
        var b = 'b'
        console.log(a > b) //false
    • booleanboolean

      • false会转化为 0,true转化为 1 进行运算
      • 比较大小时也是将值转换为 0 或 1 比较
    • undefinedundefined

      • 转换后以NaN参与计算,结果也为NaN
      • 比较大小时将值转换NaN比较,NaN和谁都不相等,包括和NaN
    • nullnull

      • 转换为数字 0 参与计算
      • 比较大小时将值转换为0比较
  • 不同数据类型运算

    • 数字和字符串
      • 相加就是字符串拼接,其他的如果是数字类的字符串就是转化为数字再参与计算,如果不是数字类字符串就是NaN。空字符串转化为 0 参与计算
      • 比较时会把字符串转化为数字进行比较
    • 数字和boolean
      • 会把布尔值转化为 0 或 1 参与运算
      • 比较时会把布尔值转化为数字进行比较
    • 数字和undefined
      • undefined会转化为NaN参与运算
      • 比较时会把undefined转化为NaN进行比较
    • 数字和null
      • null会转化为 0 参与运算
      • 比较时会把null转化为0进行比较
      • 0 和null不相等
    • 字符串和boolean
      • 非数字类字符串相加就是字符串拼接,其他运算字符串会转换为NaN参与运算
      • 数字类字符串会转化为数字参与运算,布尔值也转化为数字。
      • 空字符串转化为 0 参与运算
      • 比较时如果是数字类字符串那么就转化为数字,boolean转化为 0 或 1 进行比较
      • 如果是非数字类字符串那么字符串就转化为NaN进行比较
      • 如果是空字符串那么字符串就转化为0进行比较
    • 字符串和undefined
      • 非数字类字符串相加就是字符串拼接,其他运算字符串会转换为NaN参与运算
      • 数字类字符串相加就是字符串拼接其他会转化为数字参与运算,undefined转化为NaN参与计算
      • 空字符串相加就是字符串拼接其他转化为 0 参与运算,undefined转化为NaN参与计算
      • 比较时undefined转化为NaN进行比较
    • 字符串和null
      • 非数字类字符串相加就是字符串拼接,其他运算字符串会转换为NaN参与运算
      • 数字类字符串相加就是字符串拼接其他会转化为数字参与运算,null转化为 0 参与计算
      • 空字符串相加就是字符串拼接其他转化为 0 参与运算,null转化为 0 参与计算
    • 比较时null转化为 0 进行比较
    • 空字符串和null不相等
    • booleanundefined
      • boolean转化为 0 或 1 参与与运算,undefined转化为NaN参与运算
      • 比较时boolean转化为 0 或 1 进行比较,undefined转化为NaN
    • booleannull
      • boolean转化为 0 或 1 参与与运算,null转化为0参与运算
      • falsenull不相等
    • undefinednull
      • undefined会转化为NaN参与运算
      • 比较时null转化为 0 进行比较,undefined转化为NaN
      • undefinednull相等

prompt 函数

  • 能在浏览器上弹出框,可输入数据
js
var a = prompt('请输入')
console.log(a)

字符串内置方法

  • ES5字符串方法返回的都是一个新串没和原来的字符串没关系
js
let str = 'zhangheng'
//ES5

//返回字符串第n个字符
console.log(str.charAt(8)) //g

//从指定范围抽取字符串(从2-5但不包含5)第二个参数可以是负数
console.log(str.slice(2, 5)) //ang

//把指定字符当成分隔线使原字符串切割为数组(这里以字符 g 为分割线)
console.log(str.split('g')) //["zhan", "hen", ""]

//返回指定字符在原字符串第一次出现的索引,第二个参数表示从第n个字符开始查找,如果没查到返回-1
console.log(str.indexOf('z')) //0

//从指定字符串中从后往前查找,第二个参数表示从第n个字符开始查找,如果没查到返回-1
console.log(str.lastIndexOf('z')) //0

//返回字符串的长度
console.log(str.length) //9

//把指定字符替换成另一个字符,可以使用正则表达式
console.log(str.replace('zh', '45')) //45angheng

//寻找正则匹配到的字符串所在位置
console.log(str.search(/zh/g)) //0

//正则匹配寻找子串,返回一个数组
console.log(str.match(/zh/g)) //[zh]

//往字符串末尾拼接另一个字符串
console.log(str.concat('123')) //zhangheng123
//返回字符串第n个字符的Unicode
console.log(str.charCodeAt(8)) //103

//ES6
let str = 'zhangheng'
//判断原字符串中是否包含指定字符,包含则返回true,反之则返回false
console.log(str.includes('xx')) //true

//判断原字符串是否是以指定字符开头,是则返回true,反之则返回false
console.log(str.startsWith('h')) //false

//判断原字符串是否是以指定字符结尾,是则返回true,反之则返回false
console.log(str.endsWith('ng')) //true

//重复字符串
console.log(str.repeat(2)) //zhanghengzhangheng

数组

  • 增加一个数据

    js
    var arr = [1, 2, 3, 4, 5]
    arr[arr.length] = 6 //在数组末尾添加一个数6
  • 数组内置方法

js
let str = [1, 2, 'p', 'i', 5, 9]
let str1 = ['s', 2, 'p', 'i']
let str2 = [11, 55, 0, 2, 1, 9]
//ES5
//从索引0开始删除2个元素,返回删除的元素,原数组改变
console.log(str.splice(0, 2)) //["p", "i", 5, 9]

//从索引2开始增加两个元素,返回一个空数组(没删除任何数据),原数组改变
console.log(str.splice(2, 0, 99, 66)) //[1, 2, 99, 66, "p", "i", 5, 9]

//从索引2开始更改数据,返回删除修改的数据,原数组改变
console.log(str.splice(2, 1, 99)) //[1, 2, 99, "i", 5, 9]

//在一个数组后拼接另一个数组,会返回一个新的数组,拼接的还可以是一个或多个数据,原数组不变
console.log(str.concat(str1)) //[1, 2, "p", "i", 5, 9, "s", 2, "p", "i"]

//把数组里的元素以指定符号拼接成字符串,原数组不变
console.log(str.join('+')) //1+2+p+i+5+9

//翻转数组的顺序,原数组改变
console.log(str.reverse()) //[9, 5, "i", "p", 2, 1]

//对数组进行排序,如果不传参数将会按照字符编码的顺序排列数组,原数组改变
console.log(
  str2.sort(function (a, b) {
    return a - b
  })
) //[0, 1, 2, 9, 11, 55]

//删除数组的最后一项,返回删除的元素,原数组改变
console.log(str.pop()) //[1, 2, "p", "i", 5]

//在数组末尾添加元素,返回添加后数组的长度,可以添加一个数组,原数组改变
console.log(str.push(2)) //[1, 2, "p", "i", 5, 9, 2]

//在数组开头添加元素,返回添加后数组的长度,可以添加一个数组,原数组改变
console.log(str.unshift(1)) //[1, 1, 2, "p", "i", 5, 9]

//删除数组的第一项,返回删除的元素,原数组改变
console.log(str.shift()) //[2, "p", "i", 5, 9]

//将数组元素转换为字符串,原数组不变
console.log(str.toString()) //1,2,p,i,5,9

//抽取数组的指定部分,这里是1-3不包含3,原数组不变
console.log(str.slice(1, 3)) //[2, "p"]

//通用方法,这些方法是定义到Array原型对象上的
let str3 = [11, 55, 11, 2, 1, 9]
//返回指定数据在数组里第一次出现的索引
console.log(str3.indexOf(11)) //0

//返回指定数据在数组里最后一次出现的索引,从后往前找
console.log(str3.lastIndexOf(11)) //2

//遍历数组,item是数组元素,index就是数组元素下标,原数组不变
str2.forEach(function (item, index) {
  console.log(item + ' ' + index)
})

//返回经过加工后的新数组,item是数组元素,index就是数组元素下标,原数组不变
console.log(
  str3.map(function (item, index) {
    return item * 2
  })
) //[22, 110, 22, 4, 2, 18]

//ES6
//遍历过滤出一个新的数组,返回条件为true的值,原数组不变
console.log(
  str3.filter(function (item, index) {
    return item < 10
  })
) //[2, 1, 9]

//将伪数组对象或可遍历对象转换为真数组,原数组不变
var srt4 = 'zhangheng'
console.log(Array.from(srt4)) //["z", "h", "a", "n", "g", "h", "e", "n", "g"]
  • 数组定义方式

  • 当此时只传入一个值时,修改的是数组的长度,并没有添加

js
let arr = new Array(3)
let arr2 = Array(3)
console.log(arr) //[empty × 3]
console.log(arr2) //[empty × 3]

数组练习(案例)

  • 输入任意一个数字能够按顺序插入到一个从小到大的数组中
js
var a = parseInt(prompt('请输入'))
var b = [10, 20, 30, 40, 50, 60]
var c = 0 //存储找出的索引
// 找出要插入数字的索引
for (var i = 0; i < b.length; i++) {
  if (b[i] <= a && b[i + 1] >= a) {
    c = i + 1
  }
}
if (!c) {
  //判断如果输入的数字大于数组最大值时
  b[b.length] = a
  console.log('输入的是' + a)
  console.log(b)
} else if (c <= b[0]) {
  //判断如果输入的数字小于数组最小值时
  b.unshift(a) //在数组开头添加数据
  console.log('输入的是' + a)
  console.log(b)
} else {
  // 根据索引改变数组数据位置
  for (var e = b.length - 1; e >= c; e--) {
    b[e + 1] = b[e]
  }
  b[c] = a //将数据插入数组
  console.log('输入的是' + a)
  console.log(b)
}
  • 数组冒泡排序

  • js
    var arr = [11, 55, 61, 0, 0, 4, 66, 2, 2, 8, 8, 6]
    var temp
    for (var j = 0; j < arr.length - 1; j++) {
      for (var i = 0; i < arr.length - 1 - j; i++) {
        if (arr[i] > arr[i + 1]) {
          temp = arr[i]
          arr[i] = arr[i + 1]
          arr[i + 1] = temp
        }
      }
    }
    console.log(arr) //[0, 0, 2, 2, 4, 6, 8, 8, 11, 55, 61, 66]

函数和作用域

  • 作用域:变量作用的范围
  • 作用域链:查找变量的过程
  • 当我们定义变量的时候,都会加一个var,但是如果不加var的时候:
    • 如果是在全局,没有定义的变量,不加var那么必须给这个变量赋值,相当于给这个变量加上var,变为全局变量。没有什么影响。
    • 如果是在局部(如函数体内)没有定义过的变量(没有参数就是它,也没有加var)定义这个变量不加var,首先要看外部全局是否定义过这个变量,如果全局定义过,那么这个变量就不是在初始化,而是在操作全局变量赋值。如果没有定义过,相当于在全局加var定义这个变量。
  • 下面案例输出的值为 4
js
var i = 0
function f1() {
  var i = 1
  function f2() {
    var i = 2
    function f3() {
      var i = 3
      function f4() {
        var i = 4
        console.log(i) //4
      }
      f4()
    }
    f3()
  }
  f2()
}
f1()
  • 局部能看到外层变量但外部看不到局部变量。如在函数f1里能看到全局里的变量但看不到函数f2里的变量。
  • 当局部找不到某一变量时会到它的外层找如果还没有就再找外一层直至找到全局。

程序执行

  1. 程序执行开始首先是创建全局环境,然后才是局部环境,并且这些环境都是在栈里进行管理的
  2. 创建完全局环境后会把程序当中的所有全局变量收集起来并且进行执行开辟空间
  3. 接着函数调用时才会创建函数环境,并且收集所有局部变量,执行开辟空间,当函数执行完后开辟的空间销毁
  4. 当整个程序执行结束以后,全局环境最后也会销毁释放占用的内存

预解析(变量提升)

  • 当程序开始执行时,会首先解析函数。发生同名时函数会覆盖
  • 然后收集所有的变量但不赋值且只收集带var的变量,发生同名时会忽略
  • 预解析函数的优先级高于变量
js
function f1() {} //这种写法函数整体会提升
var f1 = function () {} //这种写法只会提升var f1
  • 在函数内(局部)所有的带 var 的变量,以及使用字面量定的函数,都要提升到这个函数的局部环境的最上方

函数伪数组

js
var a = 10
var b = 5
function add() {
  console.log(arguments)
}
add(a, b)
  • 此时虽然函数add没有设置形参接收实参,但实际上实参已经被函数接收并存放到arguments这个伪数据中
  • arguments可以使用数组的方法,但实际上属于对象

回调函数

  • 如果一个函数被当做参数传递给另一个函数中那么这个函数叫回调函数

  • 回调函数三要素

    • 函数是我定义的
    • 我没有调用
    • 最终执行了
  • 事件、定时器、生命周期回调函数都是回调函数

对象

  • 无序:对象里面的值打印时会按首字母排序
  • 字面量定义
js
var obj = {
  name: 'iphoneX',
  color: 'black',
  call: function () {
    console.log('打电话')
  }
}
  • 构造函数定义这种方式和上面的方式定义出来的一样
js
var obj = new Object({ name: '杨幂', age: 33 })
  • 增加数据
js
var color = 'yanse'
var obj = {}
obj.name = '小黄'
obj.age = 1
obj['color'] = 'yellow' //和obj.color完全等价,但是中括号中的必须带引号,如果不加引号相当于中括号里是一个变量,然后会找这个变量如果没定义就会报错,这里相当于是把“yanse”当成键“yellow”当成值添加到对象中
  • 删除数据
js
var obj = {}
var sex = 'sex'
obj.name = '小黄'
obj.age = 1
obj.sex = 'man'
delete obj.name
delete obj['age'] //这两种都能删除数据
delete obj[sex] //不加引号会去找变量sex并回到对象里删除对应数据,在这里会删除obj里的sex键值对
  • 对象遍历
js
var obj = {
	name:"小黑",
	sex:"man",
	age:45w
}
for(var key in obj){
	console.log(key,obj[key]);
}

this 使用

  • this本质是一个对象,代表着调用这个函数或者方法的对象(执行者)
js
function add(a, b) {
  console.log(this) //window
  function add2() {
    console.log(this) //window
  }
  add2()
  return a + b
}
add(10, 20)
  • 在函数中,函数也可以叫做是window对象的方法,this永远代表window
  • 在事件当中,回调当中的this代表的是事件对象
  • 在对象的方法当中,this代表的是这个对象
js
obj{
    add:function(){
        console.log(this);//这时的this代表的是obj这个执行者
    }
}
  • 在构造函数当中,代表的是实例化出来的对象
  • 构造函数当做普通函数执行,那么this代表的是window,这时构造函数的意思就变为给window对象添加属性和方法
js
functino person(name,age,gender){
    this.name=name;//相当于window.name=name;
    this.age=age;//相当于window.age=age;
    this.gender=gender;//相当于window.gender=gender;
    this.eat=function(){
        console.log("吃饭");
    }
     console.log(this);//person名但是值时实例化per1的值
}
//person("zs",23,"male");
var result = person("zs",23,"male");
console.log(result);//undefined,因为person函数没有返回任何值所以是undefined
//构造函数通常是用来实例化对象用的,所以不会被当做普通函数执行
var per1 = new person("zs",23,"male");
console.log(per1);//person名但是值时实例化per1的值
  • 实例化两个对象
js
function Singer(name, sex, age) {
  this.name = name
  this.sex = sex
  this.age = age
  this.song = function () {
    console.log('实力派唱将:' + name)
  }
}
var singer = new Singer('邓紫棋', '女', 25)
console.log(singer.name)
console.log(singer.age)
singer.song()

var singer1 = new Singer('周杰伦', '男', 44)
console.log(singer1.name)
console.log(singer1.age)
singer1.song()
  • 上面代码执行过程

原型对象

  • 任何函数对象在定义的时候都会伴随着一个原型对象出现,原型对象默认是Object的实例对象
  • 只有函数对象才会有原型对象
  • 原型对象和隐式原型对象
  • 原型链
  • 对象查找属性的过程
  • 当把Singer构造函数里的song方法移到Singer的原型对象上,那么Singer的实例对象也可以调用song方法。此时实例上虽然没有该方法但会查找它指向的原型对象查找
  • 对象在调用方法或者属性时,首先会从自己对象的空间找,如果找到了就直接用没找到就去自己的原型对象空间找(自己构造函数的原型对象),如果找到了就用,如果没有就继续向上,直到找到 Object 的原型对象位置,找到就用找不到就报错,我们把这个对象找属性的过程描述为原型链。
js
function Singer(name, sex, age) {
  this.name = name
  this.sex = sex
  this.age = age
  // this.song=function(){
  // 	console.log("实力派唱将:"+name);
  // }
}
Singer.prototype.song = function () {
  console.log('实力派唱将:' + name)
}
var singer = new Singer('邓紫棋', '女', 25)
var singer1 = new Singer('周杰伦', '男', 44)

singer.song()
singer1.song()

apply 和 call

  • 都可以让一个对象调用能一个对象的方法,改变执行者
  • apply要求传递的值必须为数组或者类数组,这样使得window下的方法add可以被Singer的实例化对象调用
js
function Singer(name, sex, age) {
  this.name = name
  this.sex = sex
  this.age = age
  this.song = function () {
    console.log('实力派唱将:' + name)
  }
}
var singer = new Singer('邓紫棋', '女', 25)
var singer1 = new Singer('周杰伦', '男', 44)
function add(a, b) {
  return a + b
}
//apply使用
var result = add.apply(singer, ['zhangheng', 'nan'])
console.log(result) //zhanghengnan
//call使用
var result = add.call(singer, 'zhangheng', 'nan')
console.log(result) //zhanghengnan
  • callapply用法相似但不要求必须传递数组

实现 call、apply、bind

js
Function.prototype.mycall = function (that, ...agm) {
  if (that === undefined || that === null) that = window // 判断当参数 that 的边缘情况
  // 在需要转换 this 指向的对象上添加原函数 fn
  that.tap = this // 这里 this 指向 mycall 函数的调用者 fn
  const res = that.tap(...agm) // 通过对象调用 fn 转换 this并记录返回值
  delete that.tap // 删除对象上的这个属性
  return res // 返回 fn 的返回值
}
Function.prototype.myapply = function (that, agm) {
  if (that === undefined || that === null) that = window // 判断当参数 that 的边缘情况
  // 在需要转换 this 指向的对象上添加原函数 fn
  that.tap = this // 这里 this 指向 mycall 函数的调用者 fn
  const res = that.tap(...agm) // 通过对象调用 fn 转换 this并记录返回值
  delete that.tap // 删除对象上的这个属性
  return res // 返回 fn 的返回值
}
Function.prototype.mybind = function (that, ...agm) {
  return (...agm2) => this.call(that, ...agm, ...agm2)
}
function fn(a, b) {
  console.log(a, b)
  console.log(this)
}
// fn(2, 3);
let obj = { a: 2 }
// call 方法第一个参数为转换后的 this 指向,从第二个参数开始就是 fn 的参数,call 方法会将 this 指向为第一个参数并将后面的参数传递给原函数 fn 并执行 fn
// fn.mycall(undefined, obj);
// apply 方法和 call 方法类似,只不过第二个参数为数组,并依次传递给原函数 fn
// fn.myapply(obj, [1, 2]);
// bind 方法返回一个新的函数,所以写完 bind 方法还得在后面写括号调用这个新函数,这个新函数内部会调用原函数 fn 并改变原函数 this,并且会将 bind 从第二个参数开始和后面括号执行的参数一并传递给 fn
fn.mybind(undefined, 1)(2)

数据类型判断

  • 当我们使用**typeof**判断数据类型时,它无法区分数组对象和null
js
var a = null,
  b = [1, 2],
  c = {}
console.log(typeof a) //object
console.log(typeof b) //object
console.log(typeof c) //object
  • **instanceof**可以判断数据是谁的实例化对象
js
function Singer(name, sex, age) {
  this.name = name
  this.sex = sex
  this.age = age
}
var singer = new Singer('邓紫棋', '女', 25)
console.log(singer instanceof Singer) //true
js
var b = [1, 2],
  c = {}
console.log(b instanceof Array) //true
console.log(c instanceof Object) //true
js
// 借助对象原型上的 toString 方法判断
Object.prototype.toString.call('需要判断类型的数据')

值类型和引用型数据与栈堆的关系

  • 栈存放值类型数据,堆存放引用型数据

  • 堆空间的释放是靠垃圾回收机制进行的

  • 当程序函数或者整个程序执行完成后,栈里面的所有的东西都会被销毁,堆当中的数据可能还在,只是没有任何的变量指向(引用)那么堆当中的数据就会变成垃圾对象。回收机制会在适当的时候将垃圾对象清理回收

  • 如果外面在程序当中需要删除对象,那么就将这个对象的变量赋值为null,代表这个对象引用被改变,这个对象也就成了垃圾对象,其实删除对象就是让堆当中的对象数据成为垃圾对象

  • 对象之间比较的是在堆里的地址,只有地址一样才相等

  • js
    var a = [],
      b = []
    console.log(a == b) //false

js内置对象方法

  • 基本数据类型调用方法的问题

    • js
      var a = 10
      b = new Number(10) //包装对象
      console.log(a.toString())
    • a.toString()a显然是一个对象,对象才会有方法调用,但是此时的a我们定义的时候是一个基本数据类型它是没有方法的。但是js当中基本数据类型操作的时候会有这么一个规定:

    • 当调用数字、字符串、布尔值的方法的时候,会首先把这个值包装成对象(临时的),然后调用包装对象的方法,调用完成之后会把临时的包装对象立即清除。

  • JSON对象方法

    • JSONjs当中的一个内置对象,里面封装了对JSON格式数据的操作方法,JSON是一种数据格式,是前后端目前数据交互的主要格式

    • JSON.stringify():把对象转化成JSON字符串(结果为字符串)

    • js
      var person = {
        name: 'zhangheng',
        age: 32
      }
      var content = JSON.stringify(person)
      console.log(content) //{"name":"zhangheng","age":32}
    • JSON.parse():把JSON字符串解析成对象

    • js
      var person = '{"name":"zhangheng","age":32}'
      var content = JSON.parse(person)
      console.log(content)
  • date 日期对象

    • Date()获得一个日期对象

    • js
      var date = new Date()
      console.log(date) //Sat Mar 27 2021 16:24:25 GMT+0800 (中国标准时间)
      //获取年份
      console.log(date.getFullYear()) //2021
      //获取月份,但0-11代表1-12月这里代表3月
      console.log(date.getMonth()) //2
      //获取日
      console.log(date.getDate()) //27
      //获取时
      console.log(date.getHours()) //16
      //获取分
      console.log(date.getMinutes()) //24
      //获取秒
      console.log(date.getSeconds()) //25
      //获取周,周日为0
      console.log(date.getDay()) //6
      //获取当地时间
      console.log(date.toLocaleTimeString()) //下午4:24:25
      //获取当地日期
      console.log(date.toLocaleDateString()) //2021/3/27
      //获取从1970年1月1日0时0分0秒到现在的毫秒
      console.log(date.getTime()) //1616834416975
      
      //获取从1970年1月1日0时0分0秒到现在的毫秒,不兼容IE低版本
      console.log(Date.now()) //1617326300601
      
      //如果不传参数那么就返回从1970年1月1日0时0分0秒到现在的毫秒,如果传递参数就返回当前的毫秒
      var nowTime = +new Date('2021-4-2 9:37') //
  • Math工具对象

    • Math.ceil向上取整

    • js
      console.log(Math.ceil(1.23)) //2
    • Math.floor向下取整

    • js
      console.log(Math.floor(1.23)) //1
    • Math.round四舍五入

    • js
      console.log(Math.round(1.5)) //2
    • 上面三种用来处理小数,把小数处理为整数

    • Math.random随机数

    • js
      console.log(Math.random())
    • Math.maxMath.min求最大值最小值,不能直接传入一个数组

    • js
      console.log(Math.max(12, 45, 6, 3)) //45
      console.log(Math.min(12, 45, 6, 3)) //3
    • 利用这个求一个数组最大值最小值

    • js
      var arr = [3, 2, 4, 1, 8, 6]
      var maxValue = Math.max.apply(null, arr)
      console.log(maxValue) //8
    • Math.PI圆周率

    • js
      console.log(Math.PI) //3.141592653589793
    • Math.pow求一个数的几次方的值,有两个参数第一个是底数,第二个是指数

    • js
      console.log(Math.pow(10, 2)) //100
      //这里代表10的2次方

计算当前到将来的时间差(案例)

  • 利用时间戳计算距离下课还有多长时间

  • js
    var nowTime = +new Date() //获取当前的时间戳
    var nowTime1 = +new Date('2021/4/2 12:00') //获取将来12点的时间戳
    var times = (nowTime1 - nowTime) / 1000 //获取现在距离将来12点的秒数
    var d = parseInt(times / 60 / 60 / 24) //天
    d = d < 10 ? '0' + d : d
    var h = parseInt((times / 60 / 60) % 24) //时
    h = h < 10 ? '0' + h : h
    var m = parseInt((times / 60) % 60) //分
    m = m < 10 ? '0' + m : m
    var s = parseInt(times % 60) //秒
    s = s < 10 ? '0' + s : s
    console.log('距离下课还有' + d + '天' + h + '时' + m + '分' + s + '秒') //距离下课还有00天02时12分13秒

利用 random 随机数(案例)

  • 只要传递两个值,就能实现随机获得一个这两个值之间的数(包含两极,这里包含 3 和 5)
js
function getRondom(min, max) {
  return Math.floor(Math.random() * (max - min + 1) + min)
}
console.log(getRondom(3, 5))
  • 结合上面的函数封装一个随机验证码的功能。传递一个num就能随机获取到一个num位的验证码(这里是 6 位验证码)
js
function getRondom(min, max) {
  return Math.floor(Math.random() * (max - min + 1) + min)
}
function mycode(num) {
  var str = 'qwertyuiopasdfghjklzxcvbnmQWERTYUIOPASDFGHJKLZXCVBNM1234567890'
  var mycode = ''
  for (var i = 0; i < num; i++) {
    mycode += str[getRondom(0, 61)]
  }
  return mycode
}
console.log(mycode(6))

ES5严格模式

  • 语法更加严谨,使用的不多,因为ES6就是基于严格模式的语法
js
user strict;//设置使用严格模式语法
a=10;
console.log(a);//会报错,在严格模式下定义变量必须加var

装饰器

js
// 装饰器语法
@demo
class MyClass {}
function demo(t) {
  t.a = 1
}
// 如上装饰器语法相当于如下代码
class MyClass {}
function demo(t) {
  t.a = 1
}
MyClass = demo(MyClass)