JavaScript知识点总结

JavaScript知识点总结

1.1 EC(G),VO,GO

  • EC:执行上下文
  • VO:变量对象
  • GO:全局对象

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-oyjPPv86-1617025064455)(C:\Users\尘寰\AppData\Roaming\Typora\typora-user-images\image-20201227083525635.png)]

1.2 定义变量有var与没有var区别

  • 在全局代码中,加var会提升,没有var的不会提升
  • 不管加没加var的全局变量,都会作为window的属性
  • 没有加var的只能作为全局对象,只要是全局对象,就是window的属性
  • 加var的局部变量,不会作为window的属性
		console.log(a,b)  // undefined undefined
    if(true) {
      var a = 1
    } else {
      var b = 1
    }
    console.log(a,b)  // 1 undefined

1.3 数据存储

  • 内存
    • 堆内存,保存基本数据类型
    • 栈内存,保存引用数据类型

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-0v4IiH3k-1617025064458)(C:\Users\尘寰\AppData\Roaming\Typora\typora-user-images\image-20201227091934875.png)]

2 .1 练习题分析

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-hoRvorRH-1617025064460)(C:\Users\尘寰\AppData\Roaming\Typora\typora-user-images\image-20201227095820911.png)]

var a = b = 2  // 等价于 var a = 2 , b = 2
var a = 2, b = 2 // 等价于 var a = 2 , var b = 2
		var a = 1
    var b = 1
    function f() {
      console.log(a, b) // undefined 1
      var a = b = 2     
      console.log(a, b) // 2, 2
    }
    f()
    console.log(a, b)   // 1,2

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-J80jcMRm-1617025064464)(C:\Users\尘寰\AppData\Roaming\Typora\typora-user-images\image-20201227101317522.png)]

    var a = 1
    var obj = {
      name: 'wangcai'
    }
    function f() {
      var a2 = a
      obj2 = obj
      a2 = a
      obj.name = "xiaoqiang"
    }
    f()
    console.log(a)    // 1
    console.log(obj)  // {name: "xiaoqiang"}
    console.log(obj2) // {name: "xiaoqiang"}
    var a = 12
    var b = a
    b = 13
    console.log(a)  // 12
    var a = {n:12}
    var b = a
    b.n = 13
    console.log(a.n)  // 13
    var a = {m:666}
    var b = a
    b = {m:888}
    console.log(a.m)  // 666
		var a = {n:110}
    var b = a
    b.m = b = {n:666}	// 同时进行 b={n:666}, b.m={n:666}
    console.log(a)    // {m:{n:666}, n:110}
    console.log(b)    // {n: 666}

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-D3jZIvNq-1617025064466)(C:\Users\尘寰\AppData\Roaming\Typora\typora-user-images\image-20201227111716646.png)]

2.2 使用let和const声明变量和常量

2.2.1:let

  • let声明的变量没有提升(let声明的变量也提升,仅仅是没有初始化)
console.log(a)   //Cannot access 'a' before initialization
let a = 110 
  • let 配合 { } 也可以形成块级作用域
    if(true) {
      var a = 110
      let b = 666 // let + {} 形成块级作用域
    }
    console.log(a)  // 110
    console.log(b)  // b is not defined
  • 使用let声明的变量不会挂载到GO上
    let a = 110   
    console.log(window.a) // undefined
  • 使用let不能重复声明
let a = 1   
let a = 2
console.log(a)  //Identifier 'a' has already been declared

2.1.2const与let区别

  • const 声明一个常量,不能改变
  • const声明式必须赋值

2.3 函数当中的声明与赋值

    console.log(fn)   //undefined
    // window.fn()    //报错
    console.log(window.fn)  //undefined
    // fn()    // 报错
    if('fn' in window) {
      /**
       * 在判断中,如果有函数,编译仅提升函数名
       * 
       * 如果条件满足,进入条件第一件事就是给fn赋值
      */
      fn()      // fn...
      function fn() {
        console.log('fn...')
      }
    }
    fn()        // fn...

2.4 同名问题处理

    fn()
    function fn() {console.log(1)}
    fn()
    function fn() {console.log(2)}
    fn()
    var fn = function() {console.log(3)}
    fn()
    function fn() {console.log(4)}
    fn()
    function fn() {console.log(5)}
    fn()
    // 5 5 5 3 3 3

3.1 闭包

  • 闭包作用
    • 延长局部变量的声明周期
    var i = 5
    function fn(i) {
      return function (n) {
        console.log(n + (++i));
      }
    }
    var f = fn(1)
    f(2)      // 4
    fn(3)(4)  // 8
    fn(5)(6)  // 12
    f(7)      // 10
    console.log(i)  // 5

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-MNQoXZy5-1617025064468)(C:\Users\尘寰\AppData\Roaming\Typora\typora-user-images\image-20201227162504544.png)]

3.2 作用域链

  • 描述栈数据的链,先在自己的EC中找,如果找不到数据,就去父EC找,还找不到,去父EC的父EC中找,直到找到EC(G),如果还找不到就报错。数据查找机制。
  • 练习题
    let a= 0
    b= 0
    function A(a) {
      A = function(b) {
        alert(a+b++)
      }
      alert(a++)
    }
    A(1)    // 1
    A(2)    // 4

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-yjgkIh5l-1617025064469)(C:\Users\尘寰\AppData\Roaming\Typora\typora-user-images\image-20201227185105847.png)]

4.1相关概念

  • 什么是代码段?

    • 使用script标签包起来就是代码段
    • 特点:上一个代码段定义的状态,在下一个代码段中可以使用
  • JS代码执行分几个阶段?

    • 预编译

      1. 扫描代码段,如果代码段有语法错误,停止一切工作,立即报错

      2. 提升

        A) 加var变量提升

        ​ 全局代码:提升代码段最前面

        ​ 局部代码:提升局部代码最前面

        B) 函数定义提升

    • 代码执行

      • 一行一行执行代码
    • JS中的数据类型和数据存储

      • 为什么需要数据类型?
        • 为了更加合理的使用内存(堆内存、栈内存)
      • 基本:
        • number string boolean und null 存储在栈区 栈区保存了堆区的地址
      • 引用:
        • object array function 存储在堆区
    • 说出下面结果?

      • 作用域链

        • 数据的查找机制
      • EC

        • 全局代码执行时产生全局的EC,调用一个函数时,就产生一个局部的EC。EC是放在栈结构中的,全局的EC,先入栈,调用一个函数,局部的EC也入栈,函数调用完毕,局部EC出栈,全局代码执行完毕,全局EC也出栈
      • closure

        • 一个不能被销毁的执行上下文就是一个闭包
        • low:函数嵌套,里面的函数使用外面的函数的数据,此时里面的函数也可以叫做闭包
        • 作用:
          • 保护,位于闭包中的数据 外界不能访问
          • 保存 EC出栈了 数据是没有销毁 数据的生命周期延长
          • 缺点:内存泄漏 合理使用闭包
      • 在JS中,IIFE都有哪些写法?

        • 立即函数调用表达式

          (function(){})()
          (function(){}())
          +function(){}{}
          -function(){}{}
          !function(){}{}
          
          setTimeout(() => {
                
          }, timeout);
          
      • EC,AO,GO,ECStack,Scope,ScopeChain

        • EC:执行上下文
        • AO:活动对象(存储了局部执行上下文中数据)
        • VO:变量对象(存储全局执行上下文中的数据)
        • GO:全局对象 window
        • ECStack:执行上下文栈
        • Scope:作用域
        • ScopeChain: 作用域链

4.2 JS错误分类和异常处理

4.2.1 语法错误

let a = 1
let a = 1
// Uncaught SyntaxError: Identifier 'a' has already been declared
  • JS在预编译时,就发现了错误
    • 特点:
      • 代码没有机会执行
      • 错误最好找

4.4.2 引用错误

console.log(a)
// Uncaught ReferenceError: a is not defined
  • 访问没有定义的变量
    • 特点:JS代码在执行的时候,才发现引用错误,错误之后的不执行

4.4.3 类型错误

var f = 1
f()
// Uncaught TypeError: f is not a functio
  • 使用类型不当
    • 特点:JS代码在执行的时候,才发现引用错误,错误之后的不执行

4.4.4 范围错误

var arr = new Array(-5)
// Uncaught RangeError: Invalid array length
  • 使用容器时,范围指定不当

4.4.5 逻辑错误

  • 特点
    • 控制台不报错
    • 通过debug解决

4.4.6 异常处理

  • 异常不是错误,异常是指可能出错的代码
  • 语法:
try{
  // 仿可能出错的代码
  console.log(a)
}catch(e) {
  // 如果上面的代码错误了,就在这里进行错误的处理,其中e表示错误对象
  // 它里面包含了错误信息。通过查看e,可以知道他到底什么出了错误
  console.log('有错误:',e)
}finally{
  // 无论对错,代码都会执行到此处,在JS中用的不多
  console.log("一定会执行")
}
  • 抛出错误
try{
  var a = 0
  console.log(a)
  if(a == 0){
    // 程序员主动抛出错误
    throw new Error('不能为0')  // 抛出错误 catch会捕获到
  }
}catch(e) {
  console.log('友情提示:这里有点小问题,工程师正在解决中...',e)
  // 友情提示:这里有点小问题,工程师正在解决中... Error: 不能为0
}

4.3 逻辑与、逻辑或

4.3.1 逻辑与

    var a = 10
    var b = 0
    var c = b && a++	// && 左结合性 b = 0 , 不再执行&&后面的
    var d = a++ && b
    console.log(a)		// 11
    console.log(b)		// 0
    console.log(c)		// 0
    console.log(d)		// 0

4.3.2 逻辑或

    var a = 0
    var b = 2
    var c = b || a++
    console.log(a)  //0
    console.log(b)  //2
    console.log(c)  //2

    var m = 1
    var n = ""
    var q = m || n
    console.log(m)  //1
    console.log(n)  //''
    console.log(q)  //0

4.3.3 优先级

    let x = 1 || 2 && 3 || 4 && 0 || 5
    // &&>||
    console.log(x)  // 1

4.4 同步代码与异步代码

  • 三种方法实现
    var btns = document.getElementsByTagName('button')
    // for(var i = 0;i<btns.length;i++) {
    //   btns[i].onclick = function() {
    //     console.log(i)
    //   }
    // }
    // 3 3 3

    // 使用闭包解决
    // for (var i = 0; i < btns.length; i++) {
    //   btns[i].onclick = (function (i) {
    //     return function () {
    //       console.log(i)
    //     }
    //   })(i)
    // }
    // 0 1 2

    // 给btns[i]添加属性
    // for (var i = 0; i < btns.length; i++) {
    //   btns[i].index = i
    //   btns[i].onclick = function () {
    //     // 由于此函数是浏览器帮我们调用的,是得不到全局EC中的全局数据的
    //     //   解决办法:使用this this表示当前的事件源
    //     // 此处要使用this替换btns[i]
    //     console.log(this.index)
    //   }
    // }

    // 使用let + {} 形成块级作用域
    //  相当于每次for循环,都会产生执行上下文
    for(let i = 0;i<btns.length;i++) {
      btns[i].onclick = function() {
        console.log(i)
      }
    }

4.5 this 大总结

4.5.1 this几种身份

  1. 如果this出现在普通的函数中,this表示window,如果你通过window打点调用一个函数,这个函数中的this也是window

  2. 事件绑定,事件处理程序,事件发生时,浏览器帮我们调用这个函数,此函数中的this表示事件源

  3. 在一个对象中,如果有方法(函数),如果通过这个对象调用方法,方法中的this表示这个对象

  4. 在IIFE(立即调用函数表达式)中,this表示window

        (function () {
          console.log(this)   // window
        })()
    
  5. 前四点都是在非严格模式下,在严格模式下,调用一个普通函数,this表示undefined

        "use strict";
          (function () {
            console.log(this)   // undefined
          })()
    

5.1 类和对象以及内置类

  • 基本上所有的高级语言都是面向对象编程。面向对象是一种思想
    • 常见几种思想?
      • 面向过程:C语言 没有类 没有对象
      • 面向对象:JAVA C++ JS()
        • 特征:
            1. 抽象:把一个具体问题抽象化
            2. 封装:把属性和方法封装到类中,在JS中重点说对象
            3. 继承:一个类可以继承另一个类,在JS中,类是通过函数表达式
            4. 多态
        • 面向对象中的类和对象
          1. 类: JS的类本质上还是一个函数 是抽象的,不具体
          2. 对象:是具体的
      • 面向切片:Spring IOC AOP

5.1.1JS默认提供的类

  • instanceof
    • instance:实例
    • 判断一个对象时否属于一个类
      • 例如:n instanceof Number 返回true或false
  1. Number 类 或构造器
  2. String 类
  3. Boolean 类
  4. Object 类
  5. Date 类
  6. Math 类
    • 不需要new 单体内置类
    • 常驻内存不需要new
  7. Array 类

5.1.2 JS 中一切数据都是对象

  1. HTML元素是一个对象

  2. 函数也是对象

  3. 基本数据类型在某些情况下也是对象

    •     var a = 100;
          console.log(a.toFixed(3)); // 110.000
          // 上面的a叫包装对象
          // 上面调用toFixed时,他会把a瞬间包装成一个对象
      
          var str = 'hello'
          console.log(str.length);  // 5
          console.log(str.toUpperCase); // HELLO
      
  4. console、window等也是对象

5.1.3 操作对象集合

  • 增删改查

    • 访问对象
        /**
         * 访问对象里面的属性 键可以用引号包起来,也可以省略
         *  1)打点调用
         *  2)通过[]来调用
        */
        var obj = {
          name: 'wangcai',
          123: 456,
          '1+1': 2,
          'a': 'hello',
          'b': null,
          'c': function () {
            console.log('c..')
          },
          'd':['1','2','3'],
          'e':{x:'xxx'}
        }
        // console.log(obj.123) 语法错误
        console.log(obj[123]);  // 123
        console.log(obj.a);     // hello
        console.log(obj[1+1]);  // undefined
        console.log(obj['1+1']) // 2
        
        // 如果键是一个变量 我们需要通过变量去访问 必须使用[]
        var k = 'name'
        console.log(obj[k]) //wangcai
    
    		// 访问对象里面保不存在的属性,结果为undefined
    
    • 遍历对象 for in
        // for in
        var obj = {
          name:'wangcai',
          age:100,
          say:function(){
            console.log('say...')
          },
        }
        for(var key in obj){
          // key 是一个变量,要通过[]调用
          console.log(key)      // 属性
          console.log(obj[key]) // 值
        }
    
    • 添加、修改属性

    • 删除属性

      // delete 是一个单目运算符 只有一个操作数 
      delete obj.age
      
          var a = 100;
          console.log(window.a);  //100 var 中的变量放进GO中。是不能删除的
          delete window.a;
          console.log(window.a);  //100
      
          b = 666;
          console.log(window.b);  // 666
          delete window.b;  
          console.log(window.b);  //undefined
      

5.1.4 对象中的属性的四大特征

获取对象属性
  • 获取对象属性:Object.getOwnPropertyDescriptor(window,‘a’)
  1. configurable 表示是否可以删除 true表示可以删除
  2. writable 修改 true可修改
  3. enumerable 枚举 true可枚举
  4. value 属性值 默认undefined
    var a = 100;
    b = 666;

    // 获取属性特征
    console.log(Object.getOwnPropertyDescriptor(window,'a'));
    console.log(Object.getOwnPropertyDescriptor(window,'b'));

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-61x99WKG-1617025064470)(C:\Users\尘寰\AppData\Roaming\Typora\typora-user-images\image-20201229144421589.png)]

设置对象属性
    var obj = {}
    // 定义属性
    Object.defineProperty(obj, 'name', {
      configurable: false,
      writable: false,
      enumerable: false,
      value: 'wnagcai'
    })
    console.log(obj.name) // wangcai
    obj.name = 'xing'
    console.log(obj.name) // wangcai

5.1.5 属性分类

  • 属性分为两类

    // in 运算符  判断一个属性是否属于一个对象
    // 不论私有还是公有
    
    • 私有属性
      • api:hasOwnProperty
    • 共有属性
      • __proto__里面的属性
    // hasOwnProperty 私有属性
    var arr = [1, 2, 3]
    console.log(arr)
    console.log(arr.hasOwnProperty('length'))   //true
    console.log(arr.hasOwnProperty('__proto__'))  //false
    console.log(arr.hasOwnProperty('push'))  //false
    
    // 只能删除私有属性 不能删除公有属性
    delete a[0]

    // 如果一个私有属性和公有属性重名了,私有会覆盖公有
  • 数组去重与统计数组
    // 数组去重
    var arr = [2, 4, 1, 2, 4, 5, 9, 5];
    for (var i = 0; i < arr.length; i++) {
      for (var j = i + 1; j < arr.length; j++) {
        if (arr[i] == arr[j]) {
          // delete arr[j]
          arr.splice(j,1)
        }
      }
    }
    console.log(arr)
//-------------------------------------------------------

    var arr = [2, 4, 1, 2, 4, 5, 9, 5];
    var newArr = [];
    var o = {};
    for (let i = 0; i < arr.length; i++) {
      let t = arr[i]
      // if (o[t]) {

      // } else {
      //   newArr.push(t)
      //   o[t] = true
      // }
      if(!o[t]) {
        newArr.push(t)
        o[t] = true
      }
    }
    console.log(newArr)
//++++++++++++++++++++++++++++++++++++++++++++++++++++++++

		var arr = [2, 4, 1, 2, 4, 5, 9, 5];
    var x = new Set(arr)
    console.log([...x])
    // 统计一个数组中元素出现的个数
    var arr = [2, 4, 1, 2, 4, 5, 9, 5];
    var obj = {}
    for (var i = 0; i < arr.length; i++) {

      if (!obj.hasOwnProperty(arr[i])) {
        obj[arr[i]] = 1
      } else {
        obj[arr[i]]++
      }
    }
    console.log(obj)

5.1.6 对象是函数创造的

  • 在JS当中 ,一个函数是多个角色

    1. 普通函数
    2. 在对象中可以当成一个方法
    3. 类 构造器
    4. 对象
  • new 操作符干了几件事?

    1. 在构造器内部创建了一个空对象
    2. 让构造器中的this指向这个对象
    3. 返回这个对象
  • 来踩new的坑?

        function Fn(x) {
          let y = 20;
          this.total = x + y;
          this.say = function () {
            console.log(x + "+" + y + "=" + this.total)
          }
        }
        let f1 = Fn(10)
        console.log(f1)		// undefined
    
        function Fn(x) {
          let y = 20;
          this.total = x + y;
          this.say = function () {
            console.log(x + "+" + y + "=" + this.total)
          }
        }
        let f1 = new Fn(10)
        f1.say()        // 10+20=30
        console.log(f1.x) // undefined
        console.log(f1.y) // undefined
    
        function Fn(x) {
          let y = 20;
          this.total = x + y;
          this.say = function () {
            console.log(x + "+" + y + "=" + this.total)
          }
        }
        let f1 = new Fn(10)
        let f2 = new Fn(10)
        console.log(f1 == f2)  // false
        console.log(f1 === f2)  // false
    
        function Fn(x) {
          let y = 20;
          this.total = x + y;
          this.say = function () {
            console.log(x + "+" + y + "=" + this.total)
          }
        }
        let f1 = Fn(10);
        console.log(window.total);  // 30
    
        function F(num) {
          this.num = num;
          return 123;
        }
        let o = new F(100);
        console.log(o)  // {num: 100}
    
        function F(num) {
          // this 还是指向它内部创建出来的空对象 
          // 此时这个空对象,外界是引用不了的
          this.num = num;
    
          // 如果类内部返回了一个对象,那么最终指向是你返回的对象
          return {
            name:'xxx'
          };
        }
        let o = new F(100);
        console.log(o)  // {name: "xxx"}
    

6 .1 原型

6.1.1 原型对象和原型链

  1. 每一个对象上都有一个属性:_proto_ 它叫隐式原型
  2. 每个构造器(函数)上都有一个属性:prototype 它叫原型,是一个对象,这个对象我们叫原型对象
  • 原型对象:构造器(函数)的一个属性——prototype,它的值是一个对象,这个对象我们叫原型对象
  • 隐式原型:对象的一个属性——_proto_
  • 原型链:是一个对象属性的查找机制
    • 先在私有属性中找,如果找不到,就沿着__proto__去原型对象中找,如果还找不到,继续沿着__proto_去它原型对象中的原型对象中找,直到找到Object的原型对象(Object原型对象的__proto__指向了null),如果还找不到,结果就是undefined
  • 作用域链:EC中数据的查找机制
    • 先在自己EC中找数据,没有就去父函数所对应的的上下文中找,如果还找不到,就去父函数的父函数的EC中找,直到找到EC(G),如果还找不到,就报错。

6.1.2 练习

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-pi3duIBs-1617025064471)(C:\Users\尘寰\AppData\Roaming\Typora\typora-user-images\image-20201229200312572.png)]

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-eRKi55Uu-1617025064472)(C:\Users\尘寰\AppData\Roaming\Typora\typora-user-images\image-20201229204702817.png)]

  • 私有属性、公有属性的坑
    function C1(name) {
      if (name) {
        this.name = name
      }
    }
    function C2(name) {
      this.name = name
    }
    function C3(name) {
      this.name = name || 'join'
    }
    C1.prototype.name = 'Tom'
    C2.prototype.name = 'Tom'
    C3.prototype.name = 'Tom'
    console.log((new C1().name) + (new C2().name) + (new C3().name))
    // Tomundefinedjoin

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-nf1pFeeA-1617025064473)(C:\Users\尘寰\AppData\Roaming\Typora\typora-user-images\image-20201229210841542.png)]

7

7.1 面试坑

    // let a = ?
    let a = {
      n: 0,
      toString: function () {
        return ++this.n
      }
    }
    //  == 进行比较时,浏览器默认调用toString()
    if (a == 1 && a == 2 && a == 3) {
      console.log('ok')
    }
    // let a = ?
    //  == 进行比较时,两边数据类型不一致时,浏览器默认调用toString()
    let a = [1,2,3];
    a.toString = a.shift; // 你调用了toString相当于调用了shift
    if (a == 1 && a == 2 && a == 3) {
      console.log('ok')
    }

7.2 运算符优先级

7.3 call、apply、bind的使用

  • typeof 可用于检测基本数据类型数据,对于复杂数据类型,返回Object
  • Object.prototype.toString.call可以精准的检测数据类型
    // 使用 Object.prototype.toString.call可以精准的检测数据类型

    console.log(Object.prototype.toString.call(1))
    console.log(Object.prototype.toString.call('hello'))
    console.log(Object.prototype.toString.call(true))
    var a;
    console.log(Object.prototype.toString.call(a))
    console.log(Object.prototype.toString.call({}))
    console.log(Object.prototype.toString.call([]))
    function f(){}
    console.log(Object.prototype.toString.call(f))
    let d = new Date()
    console.log(Object.prototype.toString.call(d))
    let r = new RegExp()
    console.log(Object.prototype.toString.call(r))

  • call的使用

        // 封装返回类型
        function getType(abc) {
          var rs = Object.prototype.toString.call(abc)
          rs = rs.substr(8)
          var len = rs.length
          rs = rs.substr(0, len - 1)
          rs = rs.toLocaleLowerCase()
          // rs = rs.toLocaleUpperCase()
          // console.dir(rs)
        }
        getType(123)
        console.dir(String.prototype)
    
        // 数组中有一个翻转的方法
        var arr = [1,2,3];
        console.log(arr.reverse())  // [3, 2, 1]
    
        var str = '123456789';
        // console.log(str.split('')) 
        // //["1", "2", "3", "4", "5", "6", "7", "8", "9"]
        // str = str.split('').reverse().join('')
        // console.log(str)
    
        str = Array.prototype.reverse.call(str.split('')).join('')
        console.log(str)
    
call/apply/bind的使用
  • 伪数组:本质是对象,没有数组的方法

    • 通过document.getElementsByTagName获取的集合就是伪数组
    • 函数内部的arguments
      • 只能在函数内部访问arguments
        // 将伪数组变为数组
        var btns = document.getElementsByTagName('button')
        var arr = []
        for (let i = 0; i < btns.length; i++) {
          arr[i] = btns[i]
        }
        console.dir(arr)
    
  • call- apply- bind区别

    1. call 改变了this指向 ,并让函数执行 ,传递参数一个个传递
    2. apply 改变了this指向 ,并让函数执行,传递参数必须是数组
    3. bind(绑定的意思)改变了this指向 函数不执行
        // call与apply
    		function F(a,b) {
          return a+b
        }
        var obj = {}
        console.log(F.call(obj,1,2))  // 3
    		// apply 接受一个数组
        console.log(F.apply(obj,[1,2])) // 3
    
       // bind
    		function F(a,b) {
          console.log('F...')
          return a+b
        }
        var obj = {};
        let k = F.bind(obj);
        console.log(k(1,2))		// 通过加()调用
    

7.4 ES6 入门(ES2015)

  1. letconst

  2. 变量的解构赋值

    {res:data} = 
    
  3. 模板字符串

    •     let name = 'wangcai';
          console.log(`${name}`)  // wangcai
      
          // 可以拼接字符串
      
  4. 对象中的属性简写

    • 键和值一样
  5. rest参数 ,代替arguments的,用来收集实参的

        function f() {
          console.log(arguments)
        }
        // 如果实参个数非常多,使用形参接受不方便了,此时可以使用arguments
        f(1,2,3,4,5,6,7,8,9);   
        // 伪数组 [1, 2, 3, 4, 5, 6, 7, 8, 9, callee: ƒ, Symbol(Symbol.iterator): ƒ]
    
        function g(...rest) {
          console.log(rest);
        }
        g(1,2,3,4,5,6,7,8,9)    
        // [1, 2, 3, 4, 5, 6, 7, 8, 9]
    
        // rest形参,我们使用是叫args
        function k(...args) {
          console.log(args);
        }
        g
        k(1,2,3,4,5,6,7,8,9)    
        // [1, 2, 3, 4, 5, 6, 7, 8, 9]
    
  6. 拓展运算符(扩展运算符)spread

    • spread 也是… ,rest参数也是…
    let arr = ['wc','xq','zs']
    function f(...args) { //rest 参数
      console.log(args) // ["wc", "xq", "zs"]
    }
    f(...arr) // 拓展运算符
    class Player {
      constructor() {
        console.log('Player类中的constructor')
      }
    }
    class NBAPlayer extends Player {
      constructor(name) {
        super();  // 调用父类中的构造方法
        this.name = name; //设置私有属性
      }
      // NBAPlayer.prototype.say = function(){}
      say() {
        console.log('say...')
      }
      // NBAPlayer.play = function(){}
      static play() { // 静态的 通过类进行调用
        console.log('play...')
      }
    }
    let n1 = new NBAPlayer('乔丹');
    NBAPlayer.play()

8

8.1 创建对象的几种方式

  1. 字面量
  2. 工厂模式
  3. 构造函数
  4. 构造函数 + 原型
  5. ES6中通过class创建类 new对象

8.2 继承

  • 子类去继承父类的公有属性和私有属性
8.2.1原型继承
    // 原型继承
		// Child.prototype = new Parent;
		function Parent() {
      this.x = 100;
    }
    Parent.prototype.getX = function() {
      return this.x;
    }
    function Child() {
      this.y = 200;
    }
    // 原型继承
    Child.prototype = new Parent;
    Child.prototype.getY = function() {
      return this.y
    }
    var c1 = new Child();
    console.log(c1.x);
    console.log(c1.getX());
    console.log(c1.y);
    console.log(c1.getY());
8.2.2 call继承
    // call继承
    // 特点:只能继承父的私有属性
    // Parent.call(this)
    function Parent() {
      this.x = 100;
    }
    Parent.prototype.getX = function() {
      return this.x;
    }
    function Child() {
      // 改变Parent的this指向
      Parent.call(this);
      this.y = 200;
    }
    var c1 = new Child();
    console.log(c1.x)
8.2.3 组合式继承
    // 组合继承
    // 1)Parent.call(this);//继承父的私有属性
    // 2)Child.prototype = Object.create(Parent.prototype); 继承公有属性
    //    Child.prototype.constructor = Child
    function Parent() {
      this.x = 100;
    }
    Parent.prototype.getX = function() {
      return this.x;
    }
    function Child() {
      Parent.call(this);//继承父的私有属性
      this.y = 200;
    }
    Child.prototype = Object.create(Parent.prototype);
    Child.prototype.constructor = Child
    var c1 = new Child();
    console.log(c1.x)
8.2.4 ES6继承
    // ES6中的继承:
    //  super();  //类似call继承
    //  extends 类似原型继承 继承公有属性
    class Parent{
      constructor() {
        this.x = 100;
      }
      getX() {
        return this.x
      }
    }

    class Child extends Parent{
      constructor() {
        super();  //类似call继承
        this.y = 200;
      }
      getY() {
        return this.y
      }
    }
    var child = new Child();
    console.log(child.x);
    console.log(child.getX());

8.3 DOM

8.3.1 什么是DOM
  • DOM Document Object Model文档对象模型
  • 文档是有节点组成的
    • 元素节点
    • 属性节点
    • 文本节点
  • Object
    • 对象 标签对象 元素对象 ,每一个标签都是一个对象
  • Model
    • 模型 树模型 在树不会出现属性节点 会出现元素节点和文本节点
8.3.2 DOM版本
  • DOM0

  • DOM1:很多对象,方法

    • 树模型:

      • 元素节点 nodeType = 1
      • 属性节点 nodeType = 2
      • 文本节点 nodeType = 3
      • 节点与节点之间的关系
        • childNodes 所有的子节点 ==》children
        • firstChild 有兼容性问题 ==》 firstElementChild (可以用)
        • lastChild ==》 lastElementChild (可以用)
        • nextSibling 下一个兄弟节点, ==》 nextElementSibling(可以用)
        • previousSibling 上一个兄弟节点 ==》 previousElementSibling(可以用)
        • parentNode(重要)
    • 两个标准方法:

      document.getElementById();

      document.getElementsByTagName();

      其他方法,有兼容性问题

    • html5中提出两个方法

      document.querySelector();

      document.querySelectorAll();

  • DOM2: 很多对象,方法

    • 事件绑定
    • 鼠标事件
    • 键盘事件
    • 焦点事件
    • UI事件
  • DOM3

8.3.3 操作节点
  • js操作样式

    • 操作CSS类:calssName = ‘xxx’
    • 操作CSS行内样式
  • 操作元素节点

    • 访问元素

      document.getElementById(ID);
      
      document.getElementsByTagName(tagName)
      
    • 遍历元素

      使用 parentNode、nextSibling、previousSibling、firstChild 和 lastChild 属性可以遍历文档树中任意类型节点,包括空字符(文本节点)。HTML 5 新添加 5 个属性专门访问元素节点。

      • childElementCount:返回子元素的个数,不包括文本节点和注释。
      • firstElementChild:返回第一个子元素。
      • lastElementChild:返回最后一个子元素。
      • previousElementSibling:返回前一个相邻兄弟元素。
      • nextElementSibling:返回后一个相邻兄弟元素。
    • 创建元素

      var element = document.createElement("tagName");
      
    • 复制节点

      var p1 = p.cloneNode(false);  //复制节点 不包含子节点
      var p1 = p.cloneNode(true);  //复制节点 包含子节点
      
    • 插入节点

      document.body.appendChild(div)  // 在节点后插入
      
      box.insertBefore(h1,text)	// 在box内,text节点之前插入h1节点
      
    • 删除节点

      nodeObject.removeChild(node)
      ul.removeChild(lis[0])	// 该节点所包含的所有子节点将同时被删除
      
    • 替换节点

      box.replaceChild(add,h1) // 在box内,将h1替换为add
      
    • 添加:

      • 创建元素节点:var div = document.createElement(“div”);

      • 把节点挂到树上:

        document.body.appendChild(div)

        box.insertBefore(h1,text) 在box内,text节点之前插入h1节点

    • 删除:父节点可以删除子节点(权限)

      • ul.removeChild(lis[0])
  • 操作文本节点

    • div.innerHTML = “hello”

9

9.1 操作DOM

9.1.1 操作节点值操作元素节点
  • 创建元素节点
    • document.createElement(“ul”);
  • 插入元素节点
    • body.appendChild(ul);
    • insertBefore();
  • 删除元素节点
    • div.remove(“ul”);
  • 复制元素节点
    • cloneNode();
      • 深复制:包含子节点
      • 浅复制:仅复制当前元素
  • 替换(修改)元素节点
    • replaceChild();
9.1.2 操作节点值操作属性节点
  • 属性

    • 标准属性
    • 自定义属性
  • 获取属性节点:

    • div.title
    • div.getAttribute(“title”)
  • 设置属性节点:

    • div.title = ‘yyyy’
    • div.setAttribute(“title”,"ooo)
  • 打点调用和api接口调用区别

    • 打点方式不能操作自定义属性 ,操作指获取和设置
    • 使用getAttribute和setAttribute可以操作自定义属性
    • 通过打点方式设置的属性,后期还可以通过打点修改
9.1.3 操作节点值操作文本节点
  • innerHTML()
  • innerHTML(“xx”)
9.1.4 操作节点值操作CSS样式
  • 通过类名

    • div.calssName

    • div.calssName()

  • 行内样式表

9.1.5 操作节点——添加类、删除类
// 添加类
document.getElementsByClassName('myEL')[0].classList.add('checked');
// 删除类
document.getElementsByClassName('myEL')[0].classList.remove('checked');
// 包含类
document.getElementsByClassName('myEL')[0].classList.contains('checked'); 
//true or false

9.2 默认事件去除

  • html中有两个标签有默认事件

    • a

      <a href="javascript:;"></a>
      
    • form

9.3 事件绑定

  • 事件绑定有两种

    • btn.onclick = function(){} ,DOM1

    • btn.onclick = function(){} 写多个后面的会把前面的覆盖掉

      • 原因:JS中对象如果有同名属性,后面的肯定会覆盖前面的
    • DOM2 的事件绑定

    • btn.addEventListener(‘click’,function() {})

      • 可以写多个监听器

      • 原理:不是基于属性绑定,是基于事件池机制(异步任务)

    // 在一个事件源上绑定多个点击事件,只会执行最后一个
    let btn1 = document.querySelector('.btn1');
    btn1.onclick = function() {	// DOM1
      alert(123);
    }
    btn1.onclick = function() {
      alert('abc');
    }

9.4 进程-线程-任务

  • JS是单线程,一次只能执行一个任务
    • 进程:工厂 ,一个项目运行就会产生一个进程,进程与进程彼此独立
      • 单进程:你把进程杀死了,这个软件就进行不了了
      • 多进程:典型:浏览器;一个选项卡关闭,不会影响其他选项卡的使用
    • 线程:工人
      • 一个进程中可能有多个线程 ,JS是单线程
    • 任务

10

10.1 JS操作盒子模型的API

10.1.1 client(客户端)系列
  • 注意:

    • 以下几个都是只读属性,只能获取值,不能设置值
    • 获取的值,是一个数字,并没有单位
    • 获取的值是一个整数(小数会转换为整数)
    • client系列不管内容是否溢出,得到的都是盒子的可视区域
  • clientWidth

    • 获取box的内容区域width+左右padding(可视区域width的大小)
  • clientHeight

    • 获取box的内容区域height+上下padding(可视区域height的大小)
  • clientTop

    • 获取盒子的上边框大小
  • clientLeft

    • 获取盒子的左边框大小
  • 常用:获取当前页面一屏的高度

    • document.body.clientHeight
    • document.documentElement.clientHeight
10.1.2 offset(偏移量)系列
  • offsetWidth
    • box.offsetWidth ,在clientWidth的基础上加了border
  • offsetHeight
    • box.offsetHeight ,在clientHeight的基础上加了border
  • offsetTop
    • 获取一个绝对定位元素相对于参考点上面的距离
  • offsetLeft
    • 获取一个绝对定位元素相对于参考点左面的距离
  • offsetParent
    • 获取一个绝对定位元素的参考点
10.1.3 scroll系列
  • scrollWidth
    • 在没有内容溢出的情况下:scrollWidth = clientWidth
    • 有内容溢出情况下:scrollWidth的值约等于真实内容的宽度,不同浏览器中得到的值可能不一样
    • overflow属性会影响scrollWidth
    • 只能获取值,不能设置值
  • scrollHeight
    • 在没有内容溢出的情况下:scrollHeight = clientHeight
    • 有内容溢出情况下:scrollHeight的值约等于真实内容的高度,不同浏览器中得到的值可能不一样
    • overflow属性会影响scrollHeight
    • 只能获取值,不能设置值
    • 常用:获取当前页面的真实内容的高度
      • document.body.scrollHeight
      • document.documentElement.scrollHeight
  • scrollTop
    • 获取垂直滚动条卷上去的高度
    • 特点:可读可写
    • 常用:
      • 获取当前页面卷上去的高度
        • document.body.scrollTop
        • document.documentElement.scrollTop
      • 一张网页卷上去的最大高度是?
        • 内容真实高度scrollHeight - 可视区高度clientHeight
  • scrollLeft
    • 可读可写
    • 获取水平滚动条卷去的距离
10.1.4 常用
  • 获取一张网页可视区的高度
    • document.body.clientHeight
  • 获取一张网页真实的高度
    • document.body.scrollHeight
  • 获取一张网页卷去的高度
    • document.body.scrollTop

10.2 定时器

10.2.1 一次性定时器
  • window.setTimeout(()=>{},1000); // 1s后执行回调函数
  • 关闭定时器:clearTimeout();
10.2.2 循环定时器
  • window.setInterval(()=>{},1000); // 每隔1s执行里面的回调函数
  • 循环定时器会产生很多EC,如果不用,一定要关闭定时器
  • 关闭定时器:clearsInterval();

10.3 事件流与事件对象

10.3.1 事件流
  • 事件会流动

    • 默认情况下:从里向外流动,这种方式叫冒泡。
    • 从外向里,叫捕获。
  • DOM0(例如onclick 事件),只能冒泡,不能捕获

  • DOM2 能够修改

    // 第三个参数默认为false:冒泡,修改true:捕获
    fa.addEventListener('click',fn,true);
    
10.3.2 事件对象(e)
  • 事件本质是对象

  • 能干啥:

    • 阻止冒泡

      		son.onclick = function (e) {
            // 阻止冒泡
            e.cancelBubble = true;
            console.log('son...');
          }
      
    • 阻止默认事件

      	<!-- 第一种方式 -->
        <!-- <a href="javascript:;">百度</a> -->
      
      	let link = document.querySelector('a');
          link.onclick = function (e) {
            // 第二种方式
            // 阻止默认事件 
            e.preventDefault()
          }
      
          link.onclick = function (e) {
            // 第三种方式 在监听器后面写一个 return false;
            return false
          }
      

11 图片懒加载

  • 图片延迟加载

    • 一个网站上的图片,并不是一次加载所有的。
    • 当图片冒尖的时候,再给图片的src赋值,给图片的src赋值,src会重新去请求服务器要资源
  • 实现步骤:

    1)不要直接写src

    ​ 这样写直接显示

    2)给src起一个别名,叫什么无所谓,通常叫data-src,就是一个自定义属性

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值