js面试重点总结(构造函数和原型)
对象的三种创建方法
- 字面量创建
- new关键字创建
- 构造函数创建
我们可以把对象的公有属性抽离出来封装到构造函数中,构造函数就像一个对象创建的工厂,利用new构造函数来创建一个对象
new的过程
- 在内存中新开辟一块空间存放空对象
- 让空对象的__proto__对象原型指向构造函数的prototype原型对象
- 修改this指向,指向新生成的空对象
- 执行构造函数中的代码,挂载属性和方法
- 返回实例对象
静态成员和实例成员
- 实例成员就是构造函数内部通过this添加的成员,实例成员只能通过实例化对象来访问到
- 静态成员是直接添加在构造函数上的成员,只能通过构造函数访问到
function Star(uname, age) {
this.uname = uname;
this.age = age;
this.sing = function() {
console.log('我会唱歌');
}
}
Star.sex = '男';
var ldh = new Star('刘德华', 18);
console.log(Star.sex);//静态成员只能通过构造函数来访问
构造函数存在的问题
- 构造函数很好用但是如果多次调用生成内含方法的构造函数会造成内存浪费
- 因此一般将方法挂载到构造函数的prototype指向的原型对象上,这样生成的实例对象也能共享到其中的方法,节约内存
- 通过构造函数生成的实例对象会有一个__proto__属性指向生成该实例对象的构造函数的prototype指向的原型对象,这也是实例对象能访问prototype中属性和方法的原因
- constructor属性存在于对象原型和原型对象中,用于指回生成这个原型对象的构造函数,但是当我们要修改prototype中的内容,挂载多个方法时会利用对象式的赋值方法,这样做就会覆盖原有的prototype,使其constructor失效,因此我们要注意设置一个constructor属性,指回创建该原型对象的构造函数
原型链
每个实例对象都有__proto__属性指向生成该实例对象的构造函数的prototype实例对象,但是prototype也是个对象,是对象就有生成它的构造函数,因此该构造函数为Object,该构造函数也必有一个prototype实例对象,因此也能有一个__proto__属性指向Object的prototype原型对象,继续网上找则返回null
这样一层一层网上找的链就是原型链,当一个对象要调用某个方法或属性时会先查找自身实例对象上是否存在该属性或方法,没有则查找prototype上,还是没有则顺着原型链一层层往上查找,__proto__属性的意义就在此,给对象查找指明了一个方向或者说是个路线
原型对象中的this指向
构造函数中的this和原型对象中的this都指向我们new出来的实例对象