目录
1 面向对象与面向过程
2 原型对象 prototype
3 在内置对象中添加方法
4 constructor 属性
5 实例对象原型 __proto__
6 原型继承
7 原型链与instanceof
7.1 原型链
7.2 instanceof
8 案例-模态框
编程思想有 面向过程 与 面向对象,我们举个把大象从冰箱中拿出来的例子
面向过程就是 开冰箱门->把大象拿出来->关冰箱门 这三个步骤的代码自己写
面向对象就是 找一个会 开冰箱门->把大象拿出来->关冰箱门 的人,写代码的时候只写找人这一步(封装有可能得自己封装)
简单理解就是 面向对象将过程封装成一个整体,每次使用的时候使用整体。面向过程每次使用的时候使用若干个过程
面向对象有三个特性,封装性,继承性,多态性
我们通过下面这个图可以简单理解一下
面向过程与面向对象各有千秋,前端主要用面向过程
prototype是构造函数的一个属性,实例对象中没有prototype
JS中通过构造函数体现面向对象的封装性
在构造函数中封装方法会造成内存浪费,因为用构造函数中创造的每个对象都是独立的,创建了两个对象就会有两个方法占用两个内存空间,创建了十个对象就会占用十个内存空间
原型可以让相同的方法放在同一个内存空间中,JS规定每一个构造函数都有一个prototype属性,这个属性指向的是一个对象,所以我们称其为原型对象
我们可以将方法挂载在prototype中,这样方法就会存放在相同的内存空间中
构造函数和原型中的this指向的都是实例化对象
我们之前用的方法,比如str.split()实质上是str.prototype.split(),我们现在想在内置对象Array添加sum()方法,以便让数组中所有的数字都加起来
每一个实例对象都有constructor属性,constructor属性指向该实例对象的构造函数
constructor是实例对象的一个属性。
构造函数也有constructor,构造函数也是被构造出来的,我们写的构造函数的constructor同样指向上一级构造函数。
原型对象(prototype)也有constructor属性,他的属性内容与实例对象的属性内容相同,都指向实例对象的构造函数
constructor属性可以帮助我们批量增加构造函数中的函数,如果我们不适用constructor,我们可以这样写
上面的写法在创造多个方法的时候会很麻烦,也可以下面这样写
上面那样写很方便,但是会丢失掉constructor属性
我们可以这样写添加construcor属性
这样就可以做到无丢失属性添加方法了
__proto__是实例对象的一个属性,构造函数也有__proto__,构造函数也是被构造出来的,我们写的构造函数的__proto__同样指向上一级的对象原型
在实例对象中都有一个属性__proto__指向构造函数的prototype原型对象,这个是 实例对象 可以使用 原型属性与方法的原因
实例对象的__proto__与构造函数的prototype相同
__proto__只能读取不能修改
我们现在有一个对象Person,然后创建一个构造函数Man,将Person赋值给Man的原型对象,然后再加一个属性
其中eays与head都是从Person中继承的属性,放在__proto__中。name是自己的属性
像上面那样写,如果你再创建一个对象,对象a与对象b,彼此不相互影响
原型继承不只有这一种方式,但大体上功能差不多
原型链实际就是继承顺序,最大的是Object,Object再使用proto向上指会得到null,其余的原型对象使用proto均会得到上一级的原型对象
在使用属性的时候,代码会先找你当前级有没有这个属性,如果没有就去你的父类里找,如果都没有才会报错
instanceof的左侧是 类a(或实例对象),右侧是 类b(不能是实例对象)。意思是 类a属不属于类b
我们再搞一个不属于的例子
下面这个是true
下面这个是false,这个我也不清楚为什么是false
下面这个是true
这里我们使用面向对象的思想,这种思想也就是前端框架中组件的思想
Document
这里使用了箭头函数,箭头函数是this指向上一级的this,由于我们的open使用function写的,所以箭头函数的this一直往上找,找到open的this,也就是Tip_window 就停了
如果使用了function,那么this则指向函数的使用者,也就是 .Tip_header button