1. 普通函数、构造函数的区别:
(1)名字:构造函数首字母建议大写,普通函数首字母建议小写
(2)内容:① 构造函数内部this指向的是构造出来的新对象。普通函数this
指向的是window
全局对象 ; ②构造函数默认不用return
返回值,普通函数一般都有return
返回值
如果使用了return
,那返回值会根据return
值的类型而有所不同
1 | function Person() { |
return
的是引用类型得话,构造函数和普通函数都会返回return
后面的值
1 | function Person() { |
(3)调用:构造函数使用new
关键字调用,普通函数函数名+小括号形式调用当以new
调用构造函数(执行var p1 = new Person()
)时,函数内部会发生以下情况:
创建一个空对象
var obj = {}
this
变量指向对象p1
Person.call(p)
p
继承了构造数Person()
的原型p.__proto__ = Person.prototype
执行构造函数
Person()
内的代码return
对象P1
2. 构造函数
构造函数和其他函数区别:会new
实例化对象,每个构造函数都有一个原型对象(下面代码中的Person
就是原型对象),还有一个原型属性prototype
1 | function Person(name, age) { |
任何一个函数只要被new
了之后,就是构造函数,而new
出来的被成为实例,任何函数都可以作为构造函数
函数中都有一个prototype
属性,声明一个函数得时候会有个prototype
属性,这个属性会初始化一个空对象,也就是原型对象
原型对象中会有一个构造器:constructor
,默认会指向声明的那个函数。

1 | p1.constructor === Person // true |
构造函数的特点:
函数体内部使用了
this
关键字,代表所要生成的对象实例生成对象的时候,必须使用
new
3. 构造函数new操作具体做了什么
1 | function Person(name, age) { |
常见面试题:new
命令原理
创建一个新对象(作为将要返回的对象实例)
将这个空对象的原型,指向构造函数的
prototype
将这个空对象赋值给函数内部的
this
关键字开始执行构造函数内部的代码
如果构造函数内部有
return
语句,且return
一个对象,那会返回return
语句指定的对象,否则,返回this
对象
如果return
语句返回的是一个与this
无关的新对象,new
命令会返回这个新对象,而不是this
对象。如果对普通函数(内部没有this
关键字的函数)使用new
命令,则会返回一个空对象
4. prototype
在js中,每个函数都有一个prototype
属性,这个属性指向函数的原型对象。
原型对象prototype
有一个默认的constructor
属性,用于记录实例是由哪个构造函数创建的
1 | function Person(name) { |
上面代码,函数的prototype
指向了一个对象,这个对象是调用构造函数时创建的实例的原型,也就是p1
的原型,即Person.prototype == p1.__proto__
每一个js对象创建的时候,就会与之相联另一个对象,这个对象就是我们所说的原型,每一个对象都会从原型中继承属性
5. proto
每个对象都会有一个__proto__
,这个属性会指向该对象的原型,只有函数对象才有prototype
属性
__proto__
是一个对象,它有两个属性:constructor
、__proto__
1 | function Person() {} |
6. constructor
每一个原型都有一个constructor
属性,指向该关联的构造函数
1 | function Person() {} |
7. 实例、原型
读取实例的属性时如果找不到,会去与对象关联的原型中读取,如果找不到,就去原型的原型读取,一直找到最顶层为止
1 | function Person() {} |
删除实例对象p1
的name
属性时,读取p1.name
,从p1
对象中找不到name
,就会从p1
的原型(p1.__proto__
),也就是Person.prototype
中读取。这里在原型里找到了name = 'Jerry'
,如果找不到呢?
8. 原型的原型
原型也是一个对象,即是对象,就可以用最原始的方式创建它
1 | let obj = new Object() |
其实原型对象就是通过Object
构造函数生成的,实例的__proto__
指向构造函数的prototype
。
9. 原型链
原型链的核心就是对象的__proto__
的指向,当自身不存在时,就会一层层往上找,直到找到创建对象的构造函数,直至到Object
时,就没有__proto__
指向了
因为__proto__
实质找的是prototype
,所以只要找到这个链条上的构造函数的prototype
即可,Object.prototype
没有__proto__
属性,所以Object
的原型对象Object.prototype
的__proto__
指向null
,即除Object
的原型对象(Object.prototype
)的__proto__
指向null
, 其他内置函数对象的原型对象(Array.prototype
等)和自定义构造函数的__proto__
都指向Object.prototype
,因为原型对象本身是普通对象
1 | Object.prototype.__proto__ === null // true |
如有疑问,欢迎添加我的个人微信:
