JS高级原型,继承,闭包

JavaScript高级

第一天

1.面向对象和面向过程

  • 面向过程:作为一个执行者,关注是过程中每一步,事事亲力亲为。

  • 面向对象:作为一个指挥者,关注的是对象能干什么,需要什么对象

  • 注意:对于 对象 本身,对象内部还是过程

2.面向对象编程

明确需求→划分对象→对象分工→对象合作→完成目标

3.对象与类

对象,具体的实例,也叫实例对象。

  • 属性:静态特征

  • 方法:功能特征。方法要赋值为函数。

4.new关键字的执行过程

执行过程: var zs = new Obj('zs',18)

  1. 向内存申请一块空间,存放对象

  2. 进入构造函数内部,让this(搬运工)指向当前创建的对象(当前申请的空间)

  3. 通过this.key = value方式,向堆中搬运属性和方法。

  4. 变量在栈中开辟空间,进行赋值运算此时this指向变量

  5. new关键字执行完毕,会把内存的地址返回给变量名。

5.认识原型

为什么学习原型?

前提:当创建对象时,如果对象的属性变化,方法不变,在创建多个对象时就会添加很多方法,占用内存

解决:将不变的方法提出来共享

  • 原型就是一个对象,系统为函数自动分配的。

    • 原型中自带一个constructor指向相关的函数

  • 获取原型: ==构造函数名.prototype==

  • 使用方式:==原型对象.方法名= function(){ // 执行程序 }==

  • 作用:放在原型中的方法,可以被相关构造函数创建的实例对象==共享==

  • 实例对象在去调用一个属性或方法时,查找的过程是这样的:

    • 先从实例对象自身中查找,若查找不到

    • 则会通过系统给__proto__ 存放的原型地址,进入原型中查找

  • 构造函数和原型的关系:

    • 构造函数可以通过prototype获取原型

    • 原型可以通过constructor获取构造函数

6.原型链

  • 本质:就是实例对象调用属性或方法的过程

  • 原型链过程是这样的:

    • 先从实例对象自身中查找,若查找不到

    • 则会通过系统给__proto__ 存放的原型地址,进入原型中查找,若原型中查找不到

    • 则原型会通过___proto__会去原型的原型中查找,以此类推

       
       
       
      Object 是构造函数
      Object 的原型: Object.prototype
      Object是祖宗类
      原因:所有的对象,不论是任何类型,都属于Object
      终于明白万物皆对象
       

第二天

1.继承

  • 继承:子类和父类的关系

  • 作用:减少代码冗余

2.原型继承

  • 如何实现原型继承?

    • 更改子类的prototype指向父类的一个具体实例。子类.prorotype= new 父类(),原型指向新的对象,可以使用它的属性,调用新原型的方法,以及新原型的原型中的方法

    • 在新的原型上添加constructor指向子类。 子类.prorotype.constructor=子类

  • 优缺点:

    • // 优点:完美的继承了方法

    • // 缺点:无法完美的继承属性,当属性需要变化时无法达到要求

3.借用继承

call方法的使用

  • 目的:借用其他函数中的操作

  • 实现方式:更改函数内部this的指向

  • 语法:函数名.call(借用者,实参,实参...)

  • 如何实现借用继承?

    • 在子类构造函数中,通过call方法调用了父类构造函数、

    • 实现方式: 父类.call(this子对象的地址,实参...)

  • 优缺点:

    • 优点:可以完美的继承属性

    • 缺点:无法继承方法

apply方法的使用

函数名.apply(借用者,[实参....]) (与call使用方法一样,区别在于实参需要放入数组中)

bind方法的使用

  • 语法:函数名.bind(借用者,实参....)

  • 作用:不会立刻执行,返回一个新的函数,需要调用新的函数

 
 
 
 
 
fn.bind(obj,10,20)();  函数需要调用一下,效果与call,apply一样
伪数组借用数组中方法
Array.prototype.push.call(obj,xx);
 var r = Math.max.apply(arr,arr); 借用math对象中的方法取出数组最大值
 

4.组合继承

原型+借用

  • 过程:

    • 原型继承弥补了借用继承无法继承方法的缺点。

    • 借用继承弥补了原型继承无法完美继承属性的缺点。

  • 缺点:在原型链中会有多余属性

第三天

1.函数作为函数的参数-回调函数

常见的语法格式:

  • function 函数名(v){ v() }

  • function 函数名(v){ v(实参,实参) }

  • 原理:

    • 实参和形参的关系,实参赋值给了形参

  • 实际应用场景:当一个函数内部,需要接受外部传入一段程序时,使用回调函数

2.函数作为函数的返回值

  • 语法格式:

    • function 函数名(){ return function(){ // 执行代码 }; }

    • function 函数名(){ var i = function(){ // 执行代码 }; return i }

  • 原理:利用了return谷关键字。 return 数据

  • 应用场景:在闭包中会应用

闭包

闭包是将函数内部和函数外部连接起来的桥梁

总结:

  • 变量的生命周期:变量在内存中的创建销毁

    • 全局变量:何时生→打开程序时, 何时销毁→关闭程序

    • 局部变量:何时生→调用函数时, 何时销毁→函数调用执行结束后

  • GC:全称Garbage Collection

    • 垃圾回收机制,回收和销毁没有用的数据。

    • 没有用的数据,不在使用的数据。

  • 闭包:函数内部的子函数,桥梁

  • 作用:

    • 延长局部变量的生命周期

    • 维护局部变量的安全

  • 如何检测一个程序是否存在闭包:

    • 调试:在子函数内部设置断点,刷新检测,右侧是否存在closure

    • ​规则:

      1. 外层函数 和 子函数

      ​ 2. 外层函数必须有局部变量

      ​ 3. 子函数要操作外层函数的局部变量

      1. 让子函数和外部产生关联。

 
 
 
 
 
function xp(){
  var a = 10;
  function dp () {
    console.log(a)
  }
  return dp;
}
var bs = xp();
bs();
外部调用子函数,子函数调用外层函数局部变量,产生闭包
 

js中函数中的参数是局部变量,在函数的内部可以使用,函数外部不可以

 
 
 
 
 
闭包经典案例
在页面上有一组元素(如按钮),点击哪个元素就显示哪个元素的索引
var btns = document.querySelectorAll('button');
    for (var i = 0; i < btns.length; i++) {
      (function (i) {
        // var i; 局部变量   产生函数嵌套,参数就是局部变量,内层函数使用外层函数变量
        btns[i].onclick = function () {
          alert(i);
        }
      })(i);
    }
 

猜你喜欢

转载自www.cnblogs.com/bgd150809324/p/11352272.html
今日推荐