JavaScript 构造函数和原型补充

2019-03-01 0 By admin

一、错误的调用构造函数

如果像使用正常的函数一样使用构造函数,构造函数中的this将不再指向新创建出来的对象(因为根本就没有创建对象)。
构造函数中的this这个时候指向的就是window全局对象,当使用this给对象添加成员的时候,全部都添加到了window上。

二、构造函数中的函数

如果在构造函数中定义函数,那么每次创建对象,都会在对象创建过程中重新创建该函数。
但是因为函数内部代码完全相同,就造成了资源浪费;为了处理这个问题,我们可以让所有的对象共用一个方法。在构造函数外部定义好所需的函数,将该函数赋值给构造函数内的方法。

三、原型

在构造函数创建出来的时候,系统会默认的帮构造函数创建并关联一个对象,这个对象就是原型对象。
原型对象默认的是一个空的对象。原型对象中的属性和方法可以被使用该构造函数创建出来的对象使用。
1、当使用对象去访问属性和方法的时候
1、首先会在对象自己内部进行查找,如果找到了,就直接使用。
2、如果没有找到,就去原型中查找,查找到之后,就会使用。
3、如果原型中还没有,如果是属性,就是Undefined;如果是方法,就报错。
2、如何访问构造函数的原型
使用prototype关键词访问构造函数原型,也可以通过它,对原型对象添加属性和方法。操作方式:构造函数名.prototype
注意:prototype是构造函数的属性,跟对象没有关系。
补充:对象有.__proto__属性,指向对象的原型对象。
原型对象有.constructor属性,是原型对象指向构造函数。
3、对象和原型对象的关系
对象使用原型对象的成员
构造函数的原型对象中的成员,可以被所有该构造函数创建出来的对象访问;而且所有的对象共享该原型对象。所以,我们可以将构造函数中需要创建的函数,放到原型对象中存储,这样的话就方便创建的对象的使用。
4、需要对原型对象修改的情况
1、利用对象的动态特性给原型对象添加成员。
2、直接通过prototype关键词替换原型对象。
如果使用第二种方式修改原型对象,那么会出现如下问题:
在替换原型对象之前创建的对象所属的原型对象 和 在替换原型对象之后的创建的对象所属的原型对象不是同一个。
也就是说构造函数先后创建出的对象,它们的原型对象不是同一个。
4、原型对象成员修改对对象的影响
使用原型对象的注意事项
1、在对象访问属性的时候,如果在本身内找不到就会去原型中查找。
但是使用点语法进行属性赋值的时候,并不会去原型中进行查找属性。
使用点语法赋值的时候;如果对象中不存在该属性,就会给该对象新增该属性;而不会去修改原型中的属性。
2、如果在原型中的属性是引用类型的属性
那么所有的对象共享该属性,并且一个对象修改了该引用类型属性中的成员,其他对象也都会受影响。
3、一般情况下不会将属性放到原型对象中;一般情况下原型中只会放需要共享的方法。

四、原型对象包含的属性和方法

1、constructor
原型对象内的一个属性,指向该原型对象相关联的构造函数。
2、hasOwnProperty
一个方法,用来判断对象本身(不包含原型)是否拥有某个属性。
3、propertyIsEnumerable
1. 判断属性是否属于对象本身
2. 判断属性是否可以被遍历
4、Object.defineProperty();
使用以上方法添加属性的时候,可以附加一些信息,例如这个属性是否可写 可读 可遍历。
5、valueOf
获取当前对象的值。
在对象参与运算的时候
1.默认的会先去调用对象的valueOf方法,
2.如果valueOf获取到的值,无法进行运算 ,就去去调用p的toString方法 最终做的就是字符串拼接的工作。
6、 __proto__
原型对象对象中的属性。
可以使用 对象.__proto__ 去访问原型对象