1.知识储备
1.理解JS中的__proto__,prototype,constructor属性
2.理解Object.create()方法
2.举例
function Person(name){
this.name = name
}
var person = new Person('张三')
console.log(person) // 输出Person {name:"张三"}
3.步骤解析
当执行new Person(‘张三’)时,经历了四个步骤
参考文档new-keyword-in-javascript和MDN文档-new运算符
①创建一个空的JavaScript对象,即{ }(这里先称作obj)
②将obj的[[prototype]]属性,也就是__proto__属性,指向构造函数的原型,也就是Person.prototype
(JavaScript总体分为两种对象,函数对象和普通对象。被new Function()构造出来的,称为函数对象,其余的为普通对象。函数对象具有可见的prototype属性和不可见的__proto__属性,而普通对象只有不可见的__proto__属性,没有prototype属性)
③执行构造函数Person,将构造函数中的this绑定到新建的对象obj中
④返回新创建的对象obj。
需要注意的是,如果构造函数Person中,没有return语句,或者说return了一个基本类型,则返回新创建的对象obj;如果构造函数返回了一个对象,则返回这个对象,而不返回新创建的obj
步骤图如下:
4.自己实现new操作符
function Person(name) {
this.name = name
}
// constructorName: 构造函数名 args: 可变参数列表
function myNew(constructorName, ...args) {
// 这句代码同时实现了步骤一和步骤二,Object.create()方法的具体使用可以参考MDN文档
var obj = Object.create(constructorName.prototype)
// 注意这里要使用apply方法而不是call方法,因为得到的可变参数列表args是一个数组,apply方法接收的是数组,call方法接收的是可变参数列表
let result = constructorName.apply(obj, args)
return result instanceof Object ? result : obj
}
var person1 = new Person('张三')
var person2 = myNew(Person, '张三')
console.log(person1) // 输出Person {name:"张三"}
console.log(person2) // 输出Person {name:"张三"}