JavaScript知识点

JavaScript-jQuery

JavaScript:https://developer.mozilla.org/en-US/docs/Web/JavaScrip
ES6:https://es6.ruanyifeng.com/
MDN:https://developer.mozilla.org/zh-CN/
w3School:https://www.w3school.com.cn/

js中的对象有:内置对象,浏览器对象,自定义对象

a++和++a的区别

/*        
  a++:a先创建自身的一个副本,然后a自增1,最后返回副本的值。
  a=3;b=a++;
  运行后 b=3,a=4
  ++a:将a自增1并返回a。
  a=3;b=++a;
  运行后 b=4,a=4 */
    let n = 0
    console.log(n++) //0
    console.log(++n)//2
    console.log(n);//2

JavaScript基础

变量

  • 声明

  • 赋值

数据类型

js的变量数据类型,只有在程序运行过程中才能知道数据的具体类型
js是动态语言,变量的数据类型是可以变化的
1、简单数据类型(Number,String,Boolean,Undefined,Null)
  • Number数字类型
    • NaN :非数值,如果无法计算的返回的就是NaN
    • isNaN() :验证是否是数字 ,返回true或false

  • String字符串类型

    • 转义符都是以开头: ,\,',", ,
    • str.length:字符串长度
    • str+任何数据类型 :结果都是拼接好的字符串
  • Boolean布尔类型:ture 或false

  • Undefined未定义类型:一个变量声明,但是没有赋值

  • Null空值:number+null=number本身

2、复杂数据类型(Object)

判断数据类型

  1. typeof xx :返回结果只能有string,number,boolean,undefined,function,object

  2. A instanceof B 可以判断A是不是B的实例 :返回结果true/false

  3. Object.prototype.toString.call(xx)

  4. 对象的constructor判断:xx.constructor === Date/Function/Array...

  5. Jquery提供的

  • jQuery.isArray();是否为数组

  • jQuery.isEmptyObject();是否为空对象 (不含可枚举属性)。

  • jQuery.isFunction():是否为函数

  • jQuery.isNumberic():是否为数字

  • jQuery.isPlainObject():是否为使用“{}”或“new Object”生成对象,而不是浏览器原生提供的对象。

  • jQuery.isWindow(): 是否为window对象;

  • jQuery.isXMLDoc(): 判断一个DOM节点是否处于XML文档中。

数据类型的转换

转换为字符串
  • String(x)

  • x.toString(x, 10)

  • x+''

转换为数字
  • Number(x)

  • parseInt(x, 10)

  • parseFloat(x)

  • x - 0

  • +x

转换为 boolean
  • Boolean(x)

  • !!x

0,NaN, '', null, undefined 转换为布尔型都是false

补充:
  • 解释语言和编译语言

    • 解释语言:解释一行执行一行(如JavaScript
    • 编译语言:在代码执行前,先编译生成中间代码文件,才去执行代码(如java
  • 内存图

    • object存储的是地址
    • 基本类型存储的是值
    • stack和heap
  • 深复制和浅复制

  • 对于简单类型的数据来说,赋值就是深拷贝
    • 对于复杂类型的数据(对象)来说,才要区分浅拷贝和深拷贝。赋值是浅拷贝,拷贝heap内存是深拷贝*

运算符

1.算数运算符
  • + ,- ,*, /, %,

  • a++(a--)是先执行表百达式后再自增,执行表达式时使度用的是a的原值

  • ++a(--a)是先自增再执行表知达示,执行表达式时使道用的是自增后的a

2.比较运算符

< ,>,>=,<=,,!=,=,!==

3.逻辑运算符
  • &&,||,!

  • 短路与:表达式1&&表达式2:1真返回2,1假返回1 (一旦发现假就结束,返回假的那个表达式)

  • 短命或:一旦发现真就结束,返回真。

4.赋值运算符

=,+=,-=,*=,/=,%=

5.运算符优先级

1)()

2)++ -- !

3)* / % + -

4)> >= < <=

5)== != === !==

6) && ||

7) =

8) ,

if语句

  • if

  • if-else

  • if-else if-else

三元表达式

  • 表达式?执行语句1:执行语句2

  • 相当于if-else

switch

  • 语法:
  switch (key) {
      case value:
        执行语句1
        break;
      case value2:
        执行语句2
        break;
      default:
        break;
    }
  • 注意:
    • key中的值和value是全等
    • 如果当前case里面没有break,就不会退出switch,会继续执行下一个case

for循环

for(初始变量;条件表达式;操作符){
    循环体
}

while循环

while(条件表达式){
    循环体
}

do-while循环

  • 先执行一次循环体,再判断条件;如果条件为真,执行循环体,否则就退出

  • 语法:

 do {
      循环体
    } while (条件表达式);

continue和 break

  • continue:立即跳出本次循环,继续下一次循环
  • break: 立即跳出整个循环

函数

1、声明函数:
  • function 函数名(){}
  • 调用:函数名()
2、return作用:
  • 返回函数值
  • 终止函数(return语句之后的代码不执行)
3、注意:
  • return只能返回一个值(一个数字,数组,对象都可以)
  • 如果函数没有return,返回的就是undefined
4、arguments:
  • arguments实际上是当前函数的一个内置对象
  • arguments存储了传递的所有实参
5、伪数组:不是真正意义上的数组
  • 具有数组的length属性

  • 按照索引的方式进行存储

  • 没有真正数组的一些方法如pop(),push()等

6、函数表达式(匿名函数)
  • var 变量名=function(){}
  • 调用:变量名()

作用域

1、目的:提高程序可靠性,减少命名冲突
2、全局作用域:在script标签或者js文件中
3、局部作用域(函数作用域):在函数内部
4、全局变量:
  • 在全局作用域下的变量
  • 浏览器关闭才会销毁,比较占内存资源
5、局部变量:
  • 在局部作用域下的变量
  • 当程序执行完毕,就会销毁,比较节约内存资源
6、作用域链:

内部函数访问外部函数的变量,采取的是链式查找的方式来决定取那个值 (就近原则)

7、注意:
  • 如果没有声明,直接赋值的变量是全局变量
  • 块级作用域:{} 【在es6中才出现的的】

预解析

1、预解析:var和function会被提升到当前作用域的最前面
2、分类:
  • 变量预解析(变量提升):var 变量=值【相当于:var 变量;变量=值】

  • 函数预解析(函数提升):function fn() {}

3、补充
  • 函数声明:可以先使用再声明

  • 函数表达式:必须先声明再使用

对象

1、创建对象的3种方式:
  • 字面量创建对象
  • new Object创建对象
  • 构造函数创建对象
2、字面量创建对象
	 *var 对象名={属性名:属性值,...,方法名:function(){}}*
3、new Object创建对象
	 *var变量名=new Object*
4、构造函数创建对象(可以创建多个对象)
  • ​ *构造函数语法:
 function 构造函数名() {
          this.属性名=属性值;
          this.方法名=function(){}
        }
  • 使用构造函数:new 构造函数名()

  • ​ 注意:

    • 构造函数名首字母大写

    • 利用构造函数创建对象的过程,就是对象的实例化

  • new关键字的执行过程:

    1)new构造函数可以在内存中创建一个空的对象

2)this就会指向刚才创建的对象

3)执行构造函数里面的代码,给这个空对象添加属性和方法

  *4)返回这个对象*
5、使用对象
  • 调用对象属性:
  • 对象名.属性名

  • 对象名['属性名']

  • 调用对象方法:
  • 对象名.方法名()
6、for-in遍历对象
 for(var k in 对象) {
       console.log(k)//属性名,方法名
       console.log(对象[k])//属性值和方法
     }  

Math对象js内置对象

Math.PI

Math.max(x)

Math.min(x)

Math.floor(x) 向下取值,往最小取

Math.ceil(x) 向上取值,往最大取

Math.round(x) 四舍五入

Math.abs(x) 绝对值

Math.random()*n [0,n)区间的随机数

Math.floor(Math.random()*(m-n+1))+n [n,m]区间的随机数整数

日期对象js内置对象*)

	console.log(new Date());
    console.log(new Date('2020-4-11 8:8:8'));
    console.log(new Date(2020, 4, 11));
    // 获取当前时间戳
    console.log(new Date().valueOf());
    console.log(new Date().getTime());
    console.log(+new Date());
    console.log(Date.now());

    function formatTime() {
      var now = new Date()
      var y = now.getFullYear()
      var m = (now.getMonth() + 1 + '').padStart(1, '0')
      var d = (now.getDate() + '').padStart(1, '0')
      var w = now.getDay()
      var wArr = ["星期日", "星期一", "星期二", "星期三", "星期四", "星期五", "星期六"]
      var week = wArr[w]
      var hh = (now.getHours() + '').padStart(1, '0')
      var mm = (now.getMinutes() + '').padStart(1, '0')
      var ss = (now.getSeconds() + '').padStart(1, '0')
      return `${y}-${m}-${d}-${week} ${hh}:${mm}:${ss}`
    }
    // setInterval(() => {
    //   console.log(formatTime());
    // }, 1000);
    /* 案例:倒计时 */
    // 天:n/60/60/24
    // 时:n/60/60%24
    // 分:n/60%60
    // 秒: n%60
    function countDown(a) {
      var now = Date.now()
      var inputTime = +new Date(a)
      var time = (inputTime - now) / 1000
      var d = (parseInt(time / 60 / 60 / 24) + '').padStart(2, '0')
      var h = (parseInt(time / 60 / 60 % 24) + '').padStart(2, '0')
      var m = (parseInt(time / 60 % 60) + '').padStart(2, '0')
      var s = (parseInt(time % 60) + '').padStart(2, '0')
      return `${d}天 ${h}:${m}:${s}`
    }
    console.log(countDown('2020-4-13 18:50:00'));

数组对象js内置对象

  • 检查是否是数组:

    • 数组 instanceof Array :返回true/false

    • Array.isArray(数组):返回true/false

  • arr.push(xx) 改变原数组,返回新数组的长度

  • arr.unshift(xx) 改变原数组,返回新数组的长度

  • arr.pop(xx) 改变原数组,返回删除元素

  • arr.shift() 改变原数组,返回删除元素

  • arr.reverse() 改变原数组

  • arr.sort() 改变原数组 【单位数好使,标准写法用下面】

 
      // 升序
      arr.sort(function (a, b) {
        return a - b
      })
      // 降序
        arr.sort(function (a, b) {
        return a - b
      })
  • arr.indexOf(x,start) 返回数组中第一个x的索引,如果没有返回-1 【正序查找】

  • arr.lastIndexOf(x) 同上【倒序查找】

  • arr.toString() 把数组转成字符串,逗号分隔每一项

  • arr.join('xx') 把数组转成字符串,xx分隔每一项

  • arr1.concat(arr2,arr3,...) 连接数组,返回新数组

  • arr.slice(begin,end) 返回被截取的新数组

  • arr.splice(start,deleteNumber,add1,add2...) 返回被删除的数组,影响原数组

    // 案例:数组去重
    function unique(arr) {
      var nArr = []
      for (var i = 0; i < arr.length; i++) {
        if (nArr.indexOf(arr[i]) === -1) {
          nArr.push(arr[i])
        }
      }
      return nArr
    }
    console.log(unique([1, 2, 5, 7, 22, 4, 2, 3, 4]));

字符串对象(js内置对象

0、基本包装类型:把String,Number,Boolean这些简单数据类型包装成复杂数据类型
1、字符串是不可变的,所以字符串的所有方法都返回 一个新的字符串
  • str.length

  • str.indexOf(x,start) 从start开始查找,返回str中x第一次出现的索引,没有返回-1

  • str.charAt(index) 返回索引为index的字符

  • str.charCodeAt(index) 返回索引为index的字符的ASCII码

  • str[index] 返回索引为index的字符

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

  • str.substr(start, length) 截取字符串,从start截取length个

  • str.slice(start, end) 截取字符串,从start到end-1,end取不到

  • str.substring(start,end) 截取字符串,从start到end-1,end取不到。不接受负值

  • str.replace('aa','bb') 用bb替换str中的aa

  • str.split("xx") 用xx把字符串分割成数组,每一项用xx隔开

  • str.toLowerCase()

  • str.toUpperCase()

    /* 案例:查找字符串中o出现的位置已经次数 */
    var str = '1234ididhsidhadjidiii'
    var index = str.indexOf('d')
    var n = 0
    var arr = []
    // while (index !== -1) {
    //   arr.push(index)
    //   index = str.indexOf('d', index + 1)
    //   n++
    // }
    for (var i = 0; i < str.length; i++) {
      if (index !== -1) {
        arr.push(index)
        index = str.indexOf('d', index + 1)
        n++
      }
    }
    console.log(n, arr);
    console.log(str.charAt(2));
    console.log(str.charCodeAt(2));
    console.log(str[2]);
    /*案例:判断一个字符串中出现最多次数的字符,统计其次数 */
    var obj = {}
    for (var i = 0; i < str.length; i++) {
      console.log(str.charAt(i));
      var chars = str.charAt(i)
      if (obj[chars]) {
        obj[chars]++
      } else {
        obj[chars] = 1
      }
    }
    console.log(obj);
    var max = 0
    var ch
    for (var k in obj) {
      if (obj[k] > max)
        max = obj[k]
      ch = k
    }
    console.log(max, ch);
    var str2 = 'abcdefG'
    console.log(str2.concat('1', 'm', 'a'));
    console.log(str2.substr(0, 3));
    console.log(str2.slice(0, 3));
    console.log(str2.substring(0, 3));
    console.log(str2.toLowerCase());
    console.log(str2.toUpperCase());

DOM文档对象

获取元素

  • document.getElementById("id名")
  • element.getElementsByTagName('标签名') 伪数组存储
  • document.getElementsByClassName('类名') 伪数组存储
  • document.querySelector('选择器') 指定选择器的第一个元素对象
  • document.querySelectorAll('选择器') 指定选择器的所有元素对象,伪数组存储
  • 获取body元素:document.body
  • 获取html元素:document.documentElement
  • 补充:console.dir(xx) 打印返回的元素对象,方便查看里面的属性和方法

改变元素内容

  • element.innerText 替换起始到终止的内容,去除html标签,空格,换行
  • element.innerHTML 替换起始到终止的内容,包括html标签,空格,换行 【用的比较多】

这两个属性是可以读写的,可以获取元素里面的内容

元素属性操作

获取元素属性值
  • element.属性 【只能获取内置属性值】
  • element.getAttribute('属性') 【可以获取自定义属性值】
设置元素属性并赋值
  • element.属性=属性值 【设置内置属性src,href,id,alt,title,type,value,checked,selected,disabled】
  • element.setAttribute(属性,属性值) 【设置自定义属性】
删除元素属性
  • element.removeAttribute('属性')
H5自定义属性(以 data-xx 格式的自定义的属性)*
  • 设置格式:data-xx

  • 获取:

    • element.getAttribute('data-xx')

    • element.dataset.xx

    • element.dataset['xx']

    • 如果自定义属性有多个-连接(data-lis-name),获取时采用驼峰命名法:element.dataset['listName']

元素样式操作

样式属性操作(大小,颜色,位置等)
  • element.style.样式名='值' 【行内样式】(如果是background-color这样的用驼峰命名法)
  • element.className='className' 【类名样式】(会覆盖原来的类)
  • 如果想要保留原来的类名: element.className='className oldClassName1 oldClassName2'

排他思想

<!DOCTYPE html>
<html lang="en">

<head>
  <meta charset="UTF-8">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <title>Document</title>
  <style>
    .btnBox {

      margin: 20px auto;
       100%;
      text-align: center;
    }

    .pink {
      background-color: pink;
    }

    .box {
      display: flex;
      margin: 0 300px;
      border: 4px solid #fff;
    }

    li {
      flex: 1;
      list-style: none;

    }

    img {
       100%;
      height: 200px;
    }

    body {
      background: url('./img/1.jpg') no-repeat center top;
    }

    table {
       800px;
      margin: 100px auto;
      text-align: center;
      border-collapse: collapse;
      font-size: 14px;
      background-color: #fff;
    }

    thead tr {
      height: 30px;
      background-color: skyblue;
    }

    tbody tr {
      height: 30px;
    }

    tbody td {
      border-bottom: 1px solid #d7d7d7;
      font-size: 12px;
      color: blue;
    }

    .bg {
      background-color: pink;
    }

    .wrap {
       300px;
      margin: 100px auto 0;
    }

    .wrap table {
      border-collapse: collapse;
      border-spacing: 0;
      border: 1px solid #c0c0c0;
       300px;
    }

    .wrap th,
    .wrap td {
      border: 1px solid #d0d0d0;
      color: #404060;
      padding: 10px;
    }

    .wrap th {
      background-color: #09c;
      font: bold 16px "微软雅黑";
      color: #fff;
    }

    .wrap td {
      font: 14px "微软雅黑";
    }

    .wrap tbody tr {
      background-color: #f0f0f0;
    }

    .wrap tbody tr:hover {
      cursor: pointer;
      background-color: #fafafa;
    }
  </style>
</head>

<body>
  <!-- 点击按钮变色 -->
  <div class="btnBox">
    <button>1</button>
    <button>2</button>
    <button>3</button>
    <button>4</button>
    <button>5</button>
  </div>
  <!-- 百度换肤 -->
  <ul class="box">
    <li><img src="./img/1.jpg" alt=""></li>
    <li><img src="./img/2.jpg" alt=""></li>
    <li><img src="./img/3.jpg" alt=""></li>
    <li><img src="./img/4.jpg" alt=""></li>
  </ul>
  <!-- 表格经过变色 -->
  <table>
    <thead>
      <tr>
        <th>代码</th>
        <th>名称</th>
        <th>最新公布净值</th>
        <th>累计净值</th>
        <th>前单位净值</th>
        <th>净值增长率</th>
      </tr>
    </thead>
    <tbody>
      <tr>
        <td>003526</td>
        <td>农银金穗3个月定期开放债券</td>
        <td>1.075</td>
        <td>1.079</td>
        <td>1.074</td>
        <td>+0.047%</td>
      </tr>
      <tr>
        <td>003526</td>
        <td>农银金穗3个月定期开放债券</td>
        <td>1.075</td>
        <td>1.079</td>
        <td>1.074</td>
        <td>+0.047%</td>
      </tr>
      <tr>
        <td>003526</td>
        <td>农银金穗3个月定期开放债券</td>
        <td>1.075</td>
        <td>1.079</td>
        <td>1.074</td>
        <td>+0.047%</td>
      </tr>
      <tr>
        <td>003526</td>
        <td>农银金穗3个月定期开放债券</td>
        <td>1.075</td>
        <td>1.079</td>
        <td>1.074</td>
        <td>+0.047%</td>
      </tr>
      <tr>
        <td>003526</td>
        <td>农银金穗3个月定期开放债券</td>
        <td>1.075</td>
        <td>1.079</td>
        <td>1.074</td>
        <td>+0.047%</td>
      </tr>
      <tr>
        <td>003526</td>
        <td>农银金穗3个月定期开放债券</td>
        <td>1.075</td>
        <td>1.079</td>
        <td>1.074</td>
        <td>+0.047%</td>
      </tr>
    </tbody>
  </table>
  <!-- 表单全选和取消全选 -->
  <div class="wrap">
    <table>
      <thead>
        <tr>
          <th>
            <input type="checkbox" id="j_cbAll" />
          </th>
          <th>商品</th>
          <th>价钱</th>
        </tr>
      </thead>
      <tbody id="j_tb">
        <tr>
          <td>
            <input type="checkbox" />
          </td>
          <td>iPhone8</td>
          <td>8000</td>
        </tr>
        <tr>
          <td>
            <input type="checkbox" />
          </td>
          <td>iPad Pro</td>
          <td>5000</td>
        </tr>
        <tr>
          <td>
            <input type="checkbox" />
          </td>
          <td>iPad Air</td>
          <td>2000</td>
        </tr>
        <tr>
          <td>
            <input type="checkbox" />
          </td>
          <td>Apple Watch</td>
          <td>2000</td>
        </tr>
      </tbody>
    </table>
  </div>
  <script>
    /* 案例:点击按钮变色 */
    var btns = document.querySelectorAll('button')
    for (var i = 0; i < btns.length; i++) {
      btns[i].onclick = function () {
        // 去掉其他人,只设置我自己
        for (var i = 0; i < btns.length; i++) {
          btns[i].className = ''
        }
        this.className = 'pink'
      }
    }
    /* 案例:百度换肤 */
    var imgs = document.querySelectorAll('img')
    for (var i = 0; i < imgs.length; i++) {
      imgs[i].onclick = function () {
        document.body.style.backgroundImage = `url(${this.src})`
        console.log(this.src);
      }
    }
    /* 案例:表格经过变色 */
    var tbody = document.querySelector('tbody')
    var trs = document.querySelectorAll('tr')
    for (var i = 0; i < trs.length; i++) {
      trs[i].onmouseover = function () {
        this.className = 'bg'
      }
      trs[i].onmouseout = function () {
        this.className = ''
      }
    }
    /* 案例:表单全选和取消全选 */
    var all = document.querySelector('#j_cbAll')
    var others = document.querySelector('#j_tb').querySelectorAll('input')
    all.onclick = function () {
      for (var i = 0; i < others.length; i++) {
        others[i].checked = this.checked
      }
    }
    for (var i = 0; i < others.length; i++) {
      others[i].onclick = function () {
        var flag = true
        // 检查是否全部都选中,全选中all就是true,否则就是false
        for (var i = 0; i < others.length; i++) {
          if (!others[i].checked) {
            // all.checked = false
            flag = false
            break
          }
        }
        all.checked = flag
      }
    }
  </script>
</body>

</html>

获取节点

节点:nodeType节点类型,nodeName节点名称,nodeValue节点值*
  • 元素节点:nodeType=1
  • 属性节点:nodeType=2
  • 文本节点:nodeType=3 (包括文字,空格,换行等)
父节点: node.parentNode 亲父亲(如果找不到返回null)
子节点
  • node.childNodes 所有子节点,包括文本节点元素节点
  • node.firstChild 第一个子节点
  • node.children 所有子元素节点
  • node.firstElementChild 第一个子元素节点
  • node.lastElementChild 最后一个子元素节点
  • node.children[0] 第一个子元素节点
  • node.children[node.children.length-1] 最后一个子元素节点
兄弟节点
  • node.nextSibling 下一个兄弟节点
  • node.nextElementSibling 下一个兄弟元素节点
  • node.previousSibling 前一个兄弟节点
  • node.previousElementSibling 前一个兄弟元素节点

节点操作

创建节点
  • document.createElement('tagName')
添加节点
  • node.appendChild(child) 在node节点中的末尾 添加child
  • node.insertBefore(child, 指定元素) 在node节点中的指定元素前面 添加child
删除节点
  • node.removeChild(child) 删除node节点中的child节点,返回删除节点
复制节点
  • node.cloneNode() 只复制节点本身
  • node.cloneNode(false) 只复制节点本身
  • node.cloneNode(true) 复制节点本身和子节点
三种动态创建元素的区别
  • document.write(xxx) 如果文档流执行完毕,它会导致页面重绘
  • element.innerHTML=xxx 【创建多个效率更高,采用数组形式拼接】
  • document.createElement('tagName') 【创建多个效率稍低,但结果清晰】

事件

  • 事件三要素:事件源,事件类型,事件处理程序
  • 注册和删除事件
    • 传统方式【能绑定一个事件】

      //注册
      element.on事件类型=function(){} 
      //删除
      element.on事件类型=null
      
    • 监听注册方式可以绑定多个事件,常用】

      //注册 (第三个参数可有可无,默认false。false在冒泡阶段调用事件处理程序,true在捕获阶段调用事件处理程序)
      element.addEventListener('事件类型', fn,true/false)
      function fn() {}
      //删除
      element.removeEventListener('事件类型',fn)
      
    • 只有ie9以前才支持

      //注册  
      element.attachEvent('on事件类型', fn)
      function fn() {}
      //删除
      element.detachEvent('on事件类型',fn)
      
  • DOM事件流的3个阶段
    • 捕获阶段: element.addEventListener('事件类型', fn,true)

    • 当前目标阶段

    • 冒泡阶段 element.addEventListener('事件类型', fn,false)或 element.addEventListener('事件类型', fn)

    • 注意: (1 )S代码只能执行捕获或者冒泡中的一个阶段 。(2)传统方式和attachEvent只能得到冒泡阶段

事件对象

事件对象的定义:事件对象只有有了事件才会存在,在事件的侦听函数的小括号里面。当成形参看。是系统自动创建的

element.addEventListener('事件类型', function(event) {
    console.log(event)
})
//事件对象的名称是自己命名的,常用e
  • 事件对象常见属性和方法:

    • 1、普通浏览器:

    • e.target 触发事件的对象

      • e.type 事件类型
    • e.preventDefault() 阻止默认行为

      • e.stopPropagation() 阻止冒泡
    • 2、低版本浏览器:

    • e.srcElement 触发事件的对象

      • e.returnValue 阻止默认行为
    • e.cancelBubble 阻止冒泡

【传统方式return false 也可以阻止默认行为,return后面的代码不执行了】

  • 补充:
    • 事件里面的this指向的是事件函数的调用者

    • this返回的是绑定事件的对象

    • e.target或e.srcElement 触发事件的对象

事件委托

事件委托核心原理:给父节点添加侦听器,利用事件冒泡影响每一个子节点

常用鼠标事件和鼠标事件对象

  • 鼠标事件:
    • click

    • mouseover(鼠标经过自身盒子会触发,进过子盒子也会触发。会冒泡)

    • mouseout

    • mouseenter(只会经过自身盒子触发。不会冒泡)

    • mouseleave(不会冒泡)

    • focus

    • blur

    • mousemove

    • mouseup

    • mousedown

// 禁止鼠标右键菜单
    document.addEventListener('    contextmenu', function (e) {
      e.preventDefault()
    })
//禁止鼠标选中
    document.addEventListener('selectstart', function (e) {
      e.preventDefault()
    })
  • 鼠标事件对象
    • e.clientX 可视区域
    • e.clientY
    • e.pageX 文档页面
    • e.pageY
    • e.screenX 电脑屏幕
    • e.screenY

常用键盘事件和键盘事件对象

键盘事件:
  • keyup
  • keydown
  • keypress
  • 执行顺序:keydown,keypress,keyup
    // 键盘事件
    document.addEventListener('keyup', function (e) {
      console.log('keyup');
    })
    document.addEventListener('keydown', function (e) {
      console.log('keydown');
    })
//keypress不识别功能键,如ctrl,shift等
    document.addEventListener('keypress', function (e) {
      console.log('keypress');
    })
//keyup,keydown事件不区分字母大小写
键盘事件对象
  • keycode 返回该键的ASCII码
  • keyup,keydown事件不区分字母大小写

BOM浏览器对象

window常见事件

1、窗口加载事件:
//load事件 是等页面全部加载完毕(包括dom元素,img,flash,css等;
// window.onload=function() {}
    window.addEventListener('load',function() {})
// DOMContentLoaded事件 是dom加载完毕
    window.addEventListener('DOMContentLoaded',function() {})
  • load事件 是等页面全部加载完毕(包括dom元素,img,flash,css等;
  • DOMContentLoaded事件 是dom加载完毕
2、调整窗口大小事件
  //window.onresize=function(){}
    window.addEventListener('resize', function () {}) 
  • window.addEventListener('resize', function () {}) 或 window.onresize=function(){}

定时器

1、 setTimeout

    setTimeout(() => {},延迟时间)
    clearTimeout(定时器名字) 清除定时器

2、 setInterval

   setInterval(() => { }, 间隔时间)
    clearInterval(定时器名字) 清除定时器

3、如果第二个时间参数不写,默认是0(单位是毫秒)】

this指向

  1. 一般情况下,this指向的是调用它的对象
  2. 全局作用域或者普通函数中的this指向全局对象window
  3. 定时器里面的this指向window
  4. 对象方法中的this指向调用该方法的对象
  5. 构造函数中的this指向构造函数的实例
  6. 事件中的this,指向的是绑定事件的对象

URL

  • 格式 :protocol://host[:port]/path[?query]#fragment
  • 协议
  • 主机(域名)
  • 端口号
  • 路径:由0个或者多个/ 隔开
  • 参数:以键值对形式,通过&符号分隔
  • 片段:常见链接或锚点

location对象

  • location.href 整个URL【常用】
  • location.host
  • location.port
  • location.pathname
  • location.search 参数【常用】
  • location.hash 片段
  • location.assign('path') 跳转页面
  • location.replace('path') 替换当前页面,无历史记录
  • location.reload() 重新加载页面【location.reload(true)强制刷新】
     // 判断用户是那个终端打开,实现跳转
      if ((navigator.userAgent.match(
                /(phone|pad|pod|iPhone|iPod|ios|iPad|Android|Mobile|BlackBerry|IEMobile|MQQBrowser|JUC|Fennec|wOSBrowser|BrowserNG|WebOS|Symbian|Windows Phone)/i
                ))) {
              window.location.href = ""; //手机
            }else{
              window.location.href = ""; //电脑
            }

history对象

  • hisory.back()
  • hisory.forward()
  • hisory.go(n)

元素偏移量offset

1、【以带有定位的父级为准,如果没有父级或者父级无定位,就相当于body】
  • element.offsetTop
  • element.offsetLeft
2、【padding+border+width/height 返回数值无单位】
  • element.offsetWidth
  • element.offsetHeight
3、返回带有定位的父亲,否则返回body
  • element.offsetParent
4、offset和style区别
  • 获取元素大小和位置:element.offsetWidth/offsetHeight 【padding+border+widht 返回数值,只可读】
  • 元素改变大小:element.style.width/height 【width 返回有单位的字符串,可读可赋值】

元素可视区client

  • element.clientTop【上边框的大小】
  • element.clientLeft【左边框的大小】
  • element.clientWidth【padding+width 返回数值】
  • element.clientHeight 【padding+height 返回数值】

元素滚动scroll

  • element.scrollTop 【元素被卷去的上侧距离,返回数值】

  • element.scrollLeft 【元素被卷去的左侧距离,返回数值】

注意:(scrollTop 和scrollLeft一般在scroll事件中获取)

  • element.scrollWidth 【真正的内容width+padding,返回数值】

  • element.scrollHeight 【真正的内容height+padding,返回数值】

补充:

  • 页面被卷去的头部:window.pageYOffset
  • 页面被卷去的左侧:window.pageXOffset
  • 返回顶部:window.scroll(0,0)

立即执行函数

  • 格式:(function(){})()或(function(){}())

  • 作用:创建一个独立的作用域,避免命名冲突

  • 补充:

  • dpr物理像素比:window.devicePixelRatio
  • pageshow是重新加载页面触发的事件,这个事件是给window添加的
    • 如果是从缓存取过来的页面:那么pageshow事件中的e.persisted返回的是true

移动端

触摸事件
  • touchstart
  • touchmove
  • touchend
触摸事件对象
  • e.touches 当前触摸屏幕的所有手指列表
  • e.targetTouches 当前手指触摸的列表
  • e.targetTouches[0] 当前触摸元素的第一个手指的相关信息
  • e.changedTouches 手指状态发生了改变列表,无到有或有到无
  • 移动端拖动原理:盒子原来的位置+手指移动的距离
  • 手指移动的距离:手指滑动后的位置-手指刚开始触摸的位置
解决移动端延迟3毫秒
    //使用fastclick :
    //1、引入js
    //2、在点击事件之前写入:
      if ('addEventListener' in document) {
            document.addEventListener('DOMContentLoaded', function () {
              FastClick.attach(document.body);
            }, false);
          }
	//3、正常注册点击事件
*移动端插件
移动端框架

classList 返回元素的类名

element.classList.add('className') 添加类名 是在后面追加类名不会覆盖以前的类名

element.classList.reomve('className') 删除类名

element.classList.toggle('className') 切换类

本地存储

sessionStorage
  • 存储数据 sessionStorage.setItem('key',value)
  • 获取数据 sessionStorage.getItem('key')
  • 删除数据 sessionStorage.removeItem('key')
  • 清空所有数据 sessionStorage.clear()
localStorage
  • 存储数据 localStorage.setItem('key',value)
  • 获取数据 localStorage.getItem('key')
  • 删除数据 localStorage.removeItem('key')
  • 清空所有数据 localStorage.clear()

JavaScript高级

对象和类

1、创建类
//类名,首字母大写
   class Star {
      constructor(uname, age) {
        this.uname = uname
        this.age = age
      }
      sing(a) {
        console.log("我的作品:", a);
      }
    }
2、利用类创建对象
    var wyf = new Star('kris', 29)
    console.log(wyf.uname, wyf.age);
    wyf.sing('july')
3、类的继承
// class Son extends Father{} 【Son类继承了Father类里面的方法和属性】
// sper 可以调用父类的构造函数或普通函数;super必须在子类this之前调用
// 继承中的属性和方法查找原则:就近原则
// 类里面共有的属性和方法一定要加this
    class Father {
      constructor(x, y) {
        this.x = x
        this.y = y
      }
      sum() { console.log(this.x + this.y); }
      money(a) { console.log(a)}
      say() { console.log("我是father")}
    }

    class Son extends Father {
      constructor(x, y) {
        super(x, y) //super调用了父类里面的构造函数
        this.x = x
        this.y = y
      }
      say() {
        console.log("我是son")
        super.say() //super调用了父类里面的普通函数
      }
      substract() { console.log(this.x - this.y); }
    }
    var ss = new Son(10, 20)
    ss.money(100)
    ss.sum()
    ss.say()
    ss.substract()


4、类中this的指向

constructor里面的this指向创建的实例化对象

类中方法的this指向 调用该方法的对象

构造函数和原型

利用构造函数创建对象
     // 利用构造函数创建对象
    function Star(name, age) {
      //  实例成员:构造函数内部通过this添加的成员,如name,age等
      // 实例成员只能通过实例化的对象来访问
      this.name = name
      this.age = age
      this.sing = function (a) {
        console.log(a);
      }
    }
    /* new在执行时会做4件事情:
          1、在内存中创建一个新的空对象
          2、让this指向这个空对象
          3、执行构造函数里面的代码,给这个新对象添加属性和方法
          4、返回这个新对象(所以构造函数里面不需要return) 
        */

    var wyf = new Star('kris', 29)
    console.log(wyf.name, wyf.age);
    wyf.sing('july')
    // 静态成员:在构造函数身上直接添加的成员
    // 静态成员只能通过构造函数来访问
    Star.sex = "男"
    console.log(Star.sex);
    /* 构造函数原型对象prototype
          原型对象的作用:共享方法
          公共属性定义到构造函数里面,公共方法放在原型对象身上
          对象身上系统自己添加一个__proto__属性,指向构造函数的原型对象【对象.__proto__ === 构造函数.prototype】
          方法查找规则:先去对象找,如果没有去构造函数原型对象prototype上找 
        */
    // console.dir(Star);
    Star.prototype.eating = function () {
      console.log("我在吃饭");
    }
    // Star.prototype = {
    //   constructor:Star,
    //   movie: function () {
    //     console.log('movie');

    //   },
    //   drink: function () {
    //     console.log("drink");
    //   }
    // }
    wyf.eating()
    console.log(wyf);
    console.log(wyf.__proto__ === Star.prototype);
    console.log(Star.prototype);
    console.log(Star.prototype.__proto__ === Object.prototype);
    console.log(Object.prototype.__proto__);
    console.log(wyf.toString());
构造函数中的this指向
  • 构造函数中的this指向对象实例.
  • 构造函数中方法中的this指向调用该方法的对象.
  • 原型对象函数中的this指向对象实例.
扩展内置对象
    // 扩展内置对象
    console.dir(Array.prototype);
    Array.prototype.sum = function () {
      var sum = 0
      for (var i = 0; i < this.length; i++) {
        sum += this[i]
      }
      return sum
    }
    var arr = [1, 2, 3, 4]
    console.log(arr.sum());
构造函数的继承
 // 借用call()继承父类中的属性
    function Father(name, age) {
      this.name = name
      this.age = age
    }
    function Son(name, age, sex) {
      Father.call(this, name, age)
      this.sex = sex
    }
    var son = new Son('kris', 29, '男')
    console.log(son);
    // 借用原型对象继承父类中的方法
    Father.prototype.money = function () {
      console.log("money");
    }
    son.prototype=new Father()
    Son.prototype.constructor=Son
    Son.prototype.home = function () {
      console.log("home");
    }

数组新增方法

  • forEach()
  • map()
  • filter() 返回新数组
  • some() 返回ture/false 找到第一个满足条件的就终止循环
  • every() 返回ture/false
  • reduce()

字符串新方法

  • str.trim() 去除字符串两边的空格

对象方法

定义新属性或修改属性
 Object.defineProperty(对象,'属性名',{
      value:属性值,
      writable:true, //是否允许重写
      enumerable:true,//是否可以被枚举 (默认false,false不允许被遍历)
      configurable:true//是否可以被删除或修改特性(默认false,false不允许被删除)
    }) 

函数进阶

函数定义
  • 自定义函数:function fn()
  • 数表达式(匿名函数):var fun = function () {}
  • 利用new Function('参数1','参数2','函数体')
函数调用
  • fn()
  • fn.call()
  • 对象.函数名()
  • 立即执行函数
this指向
  • 普通函数中的this指向window
  • 对象中的方法的this指向调用该方法的对象
  • 构造函数中的this指向实例对象
  • 构造函数的原型对象上的方法指向实例对象
  • 绑定事件中的this指向函数的调用者
  • 定时器里面的this指向window
  • 立即执行函数里面的this指向window
改变函数内部 this指向

fn.call(thisArg,参数1,参数2,...) 调用fn,同时把fn中的this指向thisArg

fn.apply(thisArg,[参数1,参数2,...]) 调用fn,同时把fn中的this指向thisArg,apply只能传递数组(或者伪数组)

fn.bind(this.Arg,参数1,参数2,...) 不调用fn,fn中的this指向thisArg,返回原函数this指向改变之后一个新函数

  // 求数组中的最大值
    var arr = [1, 33, 4, 6, 7, 9, 10]
    console.log(Math.max(...arr));
    // apply可以用来求数组中的最大值
    console.log(Math.max.apply(Math, arr));
严格模式
  • 开启严格模式:"use strict" 【放在script的最前面或者函数中的最前面】

  • 变化:

    • 变量必须先声明再使用

    • 已经声明的变量不能删除

    • 全局作用域下函数中的this是undefined

    • 构造函数不加new调用 ,this会报错

    • 函数中不能有重名的形参

    • 不允许在非函数块声明函数

高级函数:把函数作为形参或者返回值的函数

闭包

  • 定义:一个函数(作用域)访问了另一个函数中的局部变量,这个局部变量所在的函数称为闭包
  • 作用:延伸了变量的作用范围
  • 补充:立即执行函数也称为小闭包

递归函数

  • 函数内部自己调用自己,这个函数就是递归函数
  • 递归里面必须加退出条件

浅拷贝和深拷贝

浅拷贝

Object.assign(target,...被拷贝对象)

深拷贝
  • 封装函数:

    
        function deepClone(obj) {
          let objClone = Array.isArray(obj) ? [] : {};
          if (obj && typeof obj === "object") {
            for (key in obj) {
              // obj.hasOwnProperty("属性")返回true/false,判断obj是否包含特定的自身(非继承)属性
              if (obj.hasOwnProperty(key)) {
                // 判断 obj 是否是对象,如果是,递归复制
                if (obj[key] && typeof obj[key] === "object") {
                  objClone[key] = deepClone(obj[key]);
                } else {
                  // 如果不是
                  objClone[key] = obj[key];
                }
              }
            }
          }
          return objClone
        }
    
        function deepClone2(newObj, oldObj) {
          for (var k in oldObj) {
            var item = oldObj[k]
            // 判断属性值的数据类型
            if (item instanceof Array) {
              newObj = []
              deepClone2(newObj[k], item)
            } else if (item instanceof Object) {
              newObj = {}
              deepClone2(newObj[k], item)
            } else {
              newObj[k] = item
            }
          }
        }
        var o2={}
        deepClone2(o2,obj)
        console.log(o2);
    
  • JSON.parse(JSON.stringify(被拷贝对象))

  • $.extend(true, target, 被拷贝对象);

正则表达式

作用:表单验证,替换敏感词,提取相关内容
创建正则表达式:
  • var xx=/表达式/
  • var xx=/表达式/
测试正则表达式:
  • 正则表达式.test(要测试的str)
特殊字符:
   abc   包含abc就可以
    ^abc  必须以abc开头
    ^abc$ 必须是abc
    [abc]  包含三个中的任何一个
    ^[abc]$ 必须是三个中的任何一个
    ^[a-z]$ 必须是26个小写字母中的任何一个
    ^[a-zA-Z]$ 必须是26大小写个字母中的任何一个
    ^[a-zA-Z0-9]$ 必须是26大小写个字母,0-9数字中的任何一个
    ^[a-zA-Z0-9_-]$ 必须是26大小写个字母,0-9数字,_,- 中的任何一个
    ^[^a-zA-Z0-9_-]$ 不能是26大小写个字母,0-9数字,_,- 中的任何一个 【中括号里面的^表示取反】
    [0-9] 包含0-9中的任何一个
    * 重复 >=0次
    + 重复 >=1次
    ? 重复0或1次
    {n} 重复n次
    {n,} 重复 >=n次
    {n,m} 重复n到m次
    d 就是 [0-9]
    D [^0-9]
    w [a-zA-Z0-9]
    W [^a-zA-Z0-9]
    s [	
vf] 换行符,制表符,空格符
    S [^	
vf]
    | 表示或
	替换: str.replace(str1或正则表达式,str2)
	/表达式/g  全局匹配
	/表达式/i  忽略大小写
	/表达式/gi 全局匹配+忽略大小写
原文地址:https://www.cnblogs.com/xiaojimeng/p/12821091.html