前端开发 prototype的本质

网页前端开发技术|前端开发比网页制作|前端开发比网页制作

构造函数、实例对象和原型之间的关系。

看一个最最简单的例子:

var a = new Object();
上面的代码等价于字面量形式:

var a = {};
其中我们把new的Object叫做构造函数,
a,我们称为Object的实例对象,下面简称实例(对象)。

接下来有一大段文字,请耐心的看完三者之间的关系。

我们先看看对象与构造函数是什么关系?
如果用Java语言来解释的话,类和实例的关系。
构造函数是模板,new后,生成一个对象。
构造函数是蓝图,对象是按照蓝图施工后的建筑物。

蓝图可以只有一个,建筑物允许有多个。
每new一次就建造一个新的大楼。
而new的过程,就是工人施工的过程。
new的具体过程可以看本系列第一篇。
对象与构造函数的关系讲完了,对象与原型是什么关系呢?
委托关系(即有一个关系),前三篇一直再说这个事情。

那么构造函数与原型是什么关系呢?
也是有一个关系。但不是委托关系。

new的过程就说明了这一点,
从第一篇里我们就知道new只是对对象与原型关系(委托)的封装。
此原型是挂在构造函数身上的,不是给函数本身用的,而是给实例用的。

艾玛大段文字终于说完,上代码。

其实a的原型是Object.prototype:
javascript 代码

var a = {};
console.log(a.__proto__ == Object.prototype);

二者是同一个东西!
注意原型是个对象,是引用类型,而proto和prototype只是名字罢了,
是指针或者说引用,指向了同一个对象。

Object是系统内置的构造函数。我们自定义的类型,道理也是一样的:
javascript 代码

var Person = function() {}
var me = new Person()
console.log(me.__proto__ == Person.prototype)

说道此处,就得提提我们函数的三大作用:
1.封装可复用逻辑代码段
2.作为可以new的构造函数
3.本身是对象

因为第三条,本身就是引用类型,
跟普通对象{},没什么区别,
所以我们对Person.prototype见怪不怪。

因为构造函数本身也是对象,那么函数是否就有两个原型呢!!
是的!!

Person.prototype此原型是给Person的实例用的。
Person.proto是给自己用的。
而call、bind、apply啥的,都是哪来的,都来自于Person.proto

Person是对象,也是实例,是谁的实例?
Function的实例
因此有:
javascript 代码

var Person = function() {};
console.log(Person.__proto__ == Function.prototype);

而Object本身也是函数,因此也有:
javascript 代码

console.log(Object.__proto__ == Function.prototype)

那么新的问题又来了。
Function本身也是函数,那么它又是谁的实例??
它自己!!因此有:
javascript 代码

console.log(Function.__proto__ == Function.prototype);

先有鸡,先有蛋?答案是鸡蛋。

至此。构造函数、对象和原型三者关系已经全部讲完。
总结一下:
这三者都是引用类型,
new构造函数生成对象,
new的过程封装对象与原型之间的委托关系,
此原型来自于构造函数的prototype属性。

说来说去,还是讲new的过程。

构造函数的默认的prototype对象,比如{}多了一个constructor属性,指向该构造函数。
如果用自定义的对象,重设prototype的话,最好也重置constructor。
注意原型是引用类型,那么我是否可以指定prototype为数组?为函数?可以的,不妨试试。

最后再来两个问题结束此文。

1.如何判断某对象是否是某构造函数的实例?
javascript 代码

var Person = function() {};
var me = new Person();
console.log(me instanceof Person);

原理是看Person.prototype是否在me的原型链中。

2.原型相关api?
javascript 代码

var proto = {
    name: ‘Person’,
}
var Person = function() {}
Person.prototype = proto
var me = new Person()
console.log(proto.isPrototypeOf(me))
console.log(Object.getPrototypeOf(me) == proto)
Object.setPrototypeOf(me, {})
console.log(Object.getPrototypeOf(me) == proto)

北京市前端开发招聘信息|前端开发和移动开发|腾讯 前端开发 招聘

赞(0)
前端开发者 » 前端开发 prototype的本质
64K

评论 抢沙发

评论前必须登录!