思路
new一个对象的过程:
- 首先创建一个空对象
- 设置原型:把这个空对象的原型设置为构造函数的prototype属性
- 绑定this:让构造函数的this指向这个对象
- 添加属性:执行构造函数内部的代码(为这个新对象添加属性)
- 判断构造函数的返回值类型:
(1)如果构造函数没有返回值,则实例对象就是新创建的obj (2)如果构造函数有返回值,但返回值不是一个对象,那么实例对象还是新创建的obj
function Person() {...return 1}
(3)如果构造函数有返回值,且返回值是一个对象,那么实例对象不是新创建的对象obj了,而是显式return的这个对象
function Person() {// 函数也是对象return function() {}}
function _new() {// 截取第一个参数为构造函数let constructor = Array.prototype.shift.call(arguments)// 判断传入的是不是函数类型(构造函数)if (typeof constructor !== 'function') {console.error("type error");return}// 创建一个空对象,并把其原型设置为 构造函数的原型let newObj = Object.create(constructor.prototype)// 让构造函数的 this 指向 这个对象,并且执行构造函数的代码let result = constructor.apply(newObj, arguments)// 判断构造函数返回值类型let flag = result && (typeof result === "object" || typeof result === "function")return flag ? result : newObj}// test1function Person() {this.name = "mikasa"this.age = 16this.getName = function () {console.log(this.name);}}let person = _new(Person)console.log(person);// test2function Person(name, age) {this.name = namethis.age = agethis.getName = function () {console.log(this.name);}}// 构造函数后面为输入的参数let person = _new(Person, "mikasa", 16)
附加知识
apply改变this指向并执行构造函数代码?
有关函数调用的知识看这里!!!
(apply 能够将特定函数当做一个方法绑定到指定对象上,并进行调用。属于动态调用的一种)
Function.apply(obj,args)方法能接收两个参数obj:这个对象将代替Function类里this对象args:这个是数组,它将作为参数传给Function(args—>arguments)
function Person(name,age) {this.name=name;this.age=age;}function Student(name,age,grade) {Person.apply(this,arguments);this.grade=grade;}var student=new Student("zhangsan",21,"一年级");//testconsole.log(student)

这是为什么呢?学生类里面我没有给name和age属性赋值啊,为什么又存在这两个属性的值呢?
由于 apply 会 动态调用 函数
通俗一点讲就是: 用student去执行Person这个类里面的内容,在Person这个类里面存在this.name等之类的语句,这样就将属性创建到了student对象里面
