常见考点
- new 做了那些事?
- new 返回不同的类型时会有什么表现?
- 手写 new 的实现过程
new 关键词的主要作用就是执行一个构造函数、返回一个实例对象,在 new 的过程中,根据构造函数的情况,来确定是否可以接受参数的传递。下面我们通过一段代码来看一个简单的 new 的例子
function Person(){
this.name = 'Jack';
}
var p = new Person();
console.log(p.name) // Jack
这段代码比较容易理解,从输出结果可以看出,p 是一个通过 person 这个构造函数生成的一个实例对象,这个应该很容易理解。
new 操作符可以帮助我们构建出一个实例,并且绑定上 this,内部执行步骤可大概分为以下几步:
1.创建一个新对象
2.对象连接到构造函数原型上,并绑定 this(this 指向新对象)
3.执行构造函数代码(为这个新对象添加属性)
4.返回新对象
总结:new 关键词执行之后总是会返回一个对象,要么是实例对象,要么是 return 语句指定的对象
手工实现New的过程
function create(fn, ...args) {
if(typeof fn !== 'function') {
throw 'fn must be a function';
}
// 1、用new Object() 的方式新建了一个对象obj
// var obj = new Object()
// 2、给该对象的__proto__赋值为fn.prototype,即设置原型链
// obj.__proto__ = fn.prototype
// 1、2步骤合并
// 创建一个空对象,且这个空对象继承构造函数的 prototype 属性
// 即实现 obj.__proto__ === constructor.prototype
var obj = Object.create(fn.prototype);
// 3、执行fn,并将obj作为内部this。使用 apply,改变构造函数 this 的指向到新建的对象,这样 obj 就可以访问到构造函数中的属性
var res = fn.apply(obj, args);
// 4、如果fn有返回值,则将其作为new操作返回内容,否则返回obj
return res instanceof Object ? res : obj;
};
- 使用 Object.create 将 obj 的proto指向为构造函数的原型;
- 使用 apply 方法,将构造函数内的 this 指向为 obj;
- 在 create 返回时,使用三目运算符决定返回结果。
- 我们知道,构造函数如果有显式返回值,且返回值为对象类型,那么构造函数返回结果不再是目标实例
function Person(name) {
this.name = name
return {1: 1}
}
const person = new Person(Person, 'lucas')
console.log(person)
// {1: 1}
测试
//使用create代替new
function Person() {...}
// 使用内置函数new
var person = new Person(1,2)
// 使用手写的new,即create
var person = create(Person, 1,2)
new 被调用后大致做了哪几件事情
- 让实例可以访问到私有属性;
- 让实例可以访问构造函数原型(
constructor.prototype
)所在原型链上的属性; - 构造函数返回的最后结果是引用数据类型。