JS:面向对象小结
1.对象的创建:
缺点:当我们想创建多个面向对象的时候,重复代码过多,需要封装,所以有了工厂方法。
2、工厂方式(流水线式地创建对象)
缺点:无法识别创建的对象的类型。因为全部都是Object,没有区分度,不像Date、Array等,因此出现了构造函数模式。
3、构造函数模式
1。首字母大写,区别于普通的函数,本身其实就是普通的函数,只是我们专门用它来实现了构造的功能,所以专门起了一个名字叫构造函数,任何函数都可以成为构造函数,这取决于你调用函数的方式,当使用了New的方式调用就成了构造函数。
2 New 关键字调用,new 后函数中this指向函数本身,普通函数则指向Window(相当于以下操作)
function CreatePerson(name) { var obj = {}; //声明一个空对象obj obj._proto_ = CreatePerson.prototype; //把这个对象的_proto_属性指向构造函数的原型对象,这样obj就可以调用CreatePerson原型对象下的所有方法 CreatePerson.apply(obj); //用apply方法让this指向obj对象 this.name = name; //obj对象添加属性,方法 this.showName = function () { console.log(this.name); }; return obj;//返回这个对象 }
存在的问题:
可见这两个对象并不是共用一个方法,每new一次,系统都会新创建一个内存,这两个对象各自有各自的地盘,但他们具有相同的功能,还不共用,肯定不是我们所希望的。
4、原型+构造模式
每个函数都有一个prototype属性,它是一个对象,也称作原型对象,我们可以把方法和属性写在它上面(不过原型对象不仅仅有我们写的属性和方法,还有别的,下面会介绍),而通过这个函数创建出来的实例对象,都能共享这个原型对象下的方法和属性。所以我们只需要把想要共享的东西放在函数的prototype下,不想共享的东西通过构造函数来创建就可以了。
_proto_属性: 实现同一函数创建后的实例化对象都能共享这个函数Prototype(原型对象)下的方法和属性
怎么做到的呢?
每个实例化对象都有——proto_属性,它是一个指针,指向函数的prototype,也就是保存了访问它(创建实例化对象的构造函数)的地址。(JS中任何对象的值都是保存在堆内存中,我们声明的变量只是一个指针,保存这个对象的实际地址,所以有了地址就能找到对象)_proto_属性实际就是实例化对象和原型对象之间的连接。
补充说明;
所有引用类型(函数,数组,对象)都拥有__proto__属性(隐式原型)
所有函数拥有prototype属性(显式原型)(仅限函数)
原型对象:拥有prototype属性的对象,在定义函数时就被创建
原型链:
每个函数都可以成为构造函数,都有自己的原型对象,每个原型对象也可以是一个实例化对象。
具体化: 比如创建一个函数getList,它是构造函数function的实例化对象, 而构造函数function的原型对象也是一个实例化对象,也有_proto_属性可以访问到Object的原型对象。
通过_proto_属性,形成了一条原型链,每个实例化对象都可以访问到上方的方法和属性,所以getList函数是可以访问Object原型对象下的方法和属性的。实际上所有对象都可以访问到Object的原型对象。
原型链访问规则:先在自身的下面寻找,再去一级一级的往原型链上找。
原型对象:
原型对象下可能有三种属性:
1 原型对象所带方法和属性 2 constructor 3_proto_属性
constructor:构造函数属性,每个函数的原型对象都有的默认属性,指向函数。
每个实例化对象本身是没有constructor属性的,他们下面默认只有一个_proto_属性,用来连接原型对象,而和构造函数本身是没有直接的联系的。所以它的constructor是访问的原型对象上的。所以当原型对象的constructor变化了,实例化对象的constructor也会改变。但是如果这个对象本身既是原型对象,又是实例化对象,那就拥有了constructor属性,无需从原型对象上面访问。
=============================================================================
obj = null; // 对象销毁(没有任何变量的对象会被回收释放)
应用场景:前端需要传递一个后端需要的时间(前端本身不需要这个属性),为了避免每次创建新的实例时,都要新创建一个对应的属性,可以使用prototype对象(这个对象的所有的属性跟方法,都会被构造函数的实例所继承。)
Protype原型对象使用: