前端面试题:原型 / 构造函数 / 实例
1、原型 / 构造函数 / 实例
- 原型(prototype): 一个简单的对象,用于实现对象的继承
- 构造函数: 可通过new 来新建一个对象的函数
- 实例: 通过构造函数和new 创建出的对象
实例通过 __proto__ 指向原型
通过 constructor 指向构造函数
缺个图?
实例上并不是真正有constructor这个指针,其实是从原型链上获取的
2、原型链
原型链:由原型对象组成
每个对象都有 __proto__ 属性,指向创建该对象的构造函数的原型
__proto__ 将对象连接起来组成了原型链,是一个实现继承和共享属性的有限对象链
属性查找机制:
查找属性时,如在实例上找不到,则从原型链一层一层查找,直到找到输出;
若找到最顶级的原型对象Object.prototype还未找到,则输出undefined
属性修改机制:
只会修改实例本身属性,若不存在,则进行添加属性
如需修改原型的属性时,则可用:
b.__proto__.x = 'YYY';
b.x === 'YYY' => true
但这样会造成所有继承于该对象的实例的属性发生改变
3、作用域
上下文中声明的变量 和 声明的作用范围;可分为块级作用域 和 函数作用域;
声明提前:一个声明在函数体内都是可见的(函数优先于变量)
非匿名自执行函数,函数变量为只读状态,无法修改
4、作用域链
执行上下文中访问到父级甚至全局的变量,便是因为作用域链
两部分:
属性:指向父级变量对象和作用域
AO: 自身活动对象
如此属性包含属性,便自上而下形成一条作用域链
5、new运算符的执行过程
1、新生成一个对象
2、链接到原型
object.__proto__ = constructor.prototype
3、绑定this: apply, 属性和方法被添加到实例中
4、返回新对象;如果构造函数有自己return时,则返回该值
eg:
const obj = new Object();
obj.__proto__ = Person.prototype;
let result = Person.call(obj);
if (typeOf(result) === 'object') {
Person1 = result
} else {
Person1 = obj
}
I: 创建一个对象,this引用该对象,同时继承该对象原型
II: 属性和方法被加入到this所引用的对象中
III: 新创建的对象由this所引用,并且隐式返回this