一:原型与原型链

原型:

每当定义一个函数数据类型(普通函数、类)的时候,都会隐式的生成一个prototype属性,而这个属性,指向函数的原型对象,这个属性是一个对象数据类型的值

原型链:

每一个对象数据类型(普通的对象、实例、prototype......)也天生自带一个属性__proto__,这个属性的值是当前实例所属类的原型对象(prototype)。
原型对象中有一个属性constructor, 它指向构造函数。
 
用一个自己画的图来解释原型链:
当我们访问对象的一个属性或方法时:
它会先在对象自身中寻找,如果有则直接使用,
如果没有则会去原型对象中寻找,如果找到则直接使用。
如果没有则去原型的原型中寻找 ......
由于Object对象是所有对象的老祖宗,Object对象的原型没有原型
所以~直到找到Object对象的原型,如果在Object原型中依然没有找到,则返回undefined
以上 这样就形成了一个原型指向的链条,就是原型链
 
二:new一个函数会发生什么
首先 我们来看一下new一个对象的代码:

由此可见,new一个对象:

1.会新创建一个对象:ming

2.新对象的__proto__属性会被设置为构造函数的prototype:ming.__proto__ = Person.prototype

3.新对象和构造函数的this会绑定起来:Person.call(ming, args)

4.如果构造函数中有代码,就执行构造函数中的代码

5.如果构造函数有返回值并且是返回值是引用数据类型,则返回构造函数的返回值,否则返回创建的这个新对象

 

尝试代码实现:

 

 

这里会引申出来一个新的问题:

三:为什么箭头函数不能当构造函数用?

首先 咱们回顾一下 箭头函数的特点:

1.没有自己的this,其中的this指向函数定义位置的上下文this

2.内部没有arguments和new.target,使用的都是外部的

3.没有protoype属性,占用内存空间小

拿箭头函数的特点跟new一个对象发生了什么一对比,就可以看出来 箭头函数为什么不能当构造函数用了。