JS高级原型,继承,闭包
第一天
1.面向对象和面向过程
- 
面向过程:作为一个执行者,关注是过程中每一步,事事亲力亲为。 
- 
面向对象:作为一个指挥者,关注的是对象能干什么,需要什么对象 
- 
注意:对于 对象 本身,对象内部还是过程 
2.面向对象编程
明确需求→划分对象→对象分工→对象合作→完成目标
3.对象与类
对象,具体的实例,也叫实例对象。
- 
属性:静态特征 
- 
方法:功能特征。方法要赋值为函数。 
4.new关键字的执行过程
执行过程: var zs = new Obj('zs',18)
- 
向内存申请一块空间,存放对象 
- 
进入构造函数内部,让this(搬运工)指向当前创建的对象(当前申请的空间) 
- 
通过this.key = value方式,向堆中搬运属性和方法。 
- 
变量在栈中开辟空间,进行赋值运算此时this指向变量 
- 
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 
- 
规则: - 
外层函数 和 子函数 
  2. 外层函数必须有局部变量  3. 子函数要操作外层函数的局部变量 - 
让子函数和外部产生关联。 
 
- 
 
- 
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);
}
 
                    
                     
                    
                 
                    
                
 
                
            
         
         浙公网安备 33010602011771号
浙公网安备 33010602011771号