刚刚结束面试,面试官问到的这个问题,本来还是理解,现在成功被绕晕,所以来重新梳理一下。
- 首先明确一点,
prototype
是函数独有的,__proto__
和constructor
是对象所独有的。 - 再理清一个点,任何函数,只要通过new操作符来调用,那它就可以作为构造函数。
//我们来看这个问题
function A(){} //定义了一个构造函数
var a = new A() //可以通过这种方式得到一个A的实例
//那么如何通过a找到A呢
//一般来说,我们都知道
a.__proto__===A.prototype
///函数的prototype是给new的实例用的,可以在prototype中写一些其他的函数
typeof a
"object"
typeof a.__proto__
"object"
typeof A
"function"
typeof A.prototype
"object"
//constructor主要用于记录该对象引用于哪个构造函数,它可以让原型对象重新指向原来的构造函数。
//我原来会错误的理解为constructor是一个构造函数,但是在函数中,他其实是一个属性,返回创建此对象的数组函数的引用
var a=[1]
a.constructor===Array true
var a={a:1}
a.constructor===Object true
//所以
A.prototype.constructor===A
a.__proto__.constructor===A
所以可以写出一个自定义的new
function myNew() {
//new出来的结果是一个对象,所以先定义一个对象
let obj = {};
//[].shift是数组的一个函数,用来得到数组的第一项,所以这里可以获取到参数的第一项,也就是构造函数
let con = [].shift.call(arguments);
//将对象的原型指向构造函数的prototype
obj.__proto__=con.prototype;
//改变this指向,执行构造函数
con.apply(obj,arguments);
return obj instanceof Object ?obj:{};
}