构造函数存在的问题
构造函数中的方法,每新创建一个对象的时候,该对象都会重新的创建一次这个方法,每个独享独占一个方法,但是该方法内容完全相同,所以造成资源浪费
解决办法1
将构造函数内的方法,进行提取,放在构造函数外面,在构造函数内部进行引用赋值,那么创建出来的对象,都会指向构造函数外面的这个函数,达到共享的目的
缺点:全局变量增多,造成全局变量污染,代码结构混乱,不容易维护
解决办法2
使用原型
原型是什么
在构造函数创建出来的时候,系统会默认的创建并关联一个对象,这个对象就是原型
原型的作用
原型对象中的成员,可以被使用和它关联的构造函数创建出来的所有实例对象共享
如果试图引用实例对象的某个属性,会首先在对象内部寻找该属性,直至找不到,然后会在该对象的原型里去找这个属性,如果还找不到,就去原型的原型中找,直到顶层为止
原型链
每一个构造函数都有一个原型对象,每个原型对象都有构造函数,这样就形成以一个链式结构
例如通过Number构造函数使用new方法创建一个实例对象num,它享有Number的共有属性,即num.__proto__ === Number.prototype
;同时Number函数也是一个对象,它享有Object的共有属性,即Number.prototype.__proto__ === Object.prototype
Object.prototype.__proto__ === null
链式结构:num.__proto__.__proto__.__proto__ === null
以下为常见的指向情况:
var num = new Number(1)
num.__proto__ === Number.prototype
num.__proto__.__proto__ === Object.prototype
num.__proto__.constructor === Number
Number.prototype.__proto__ === Object.prototype
Number.prototype.constructor === Number
var fn = function(){}
fn.__proto__ === Function.prototype
fn.__proto__.__proto__ === Object.prototype
fn.__proto__.constructor === Function
Function.prototype.__proto__ === Object.prototype
Function.prototype.constructor === Function
var array = []
array.__proto__ === Array.prototype
array.__proto__.__proto__ === Object.prototype
array.__proto__.constructor === Array
Array.prototype.__proto__ === Object.prototype
Array.prototype.constructor === Array
var bool = true
bool.__proto__ === Boolean.prototype
bool.__proto__.__proto__ === Object.prototype
bool.__proto__.constructor === Boolean/**/
Boolean.prototype.__proto__ === Object.prototype
Boolean.prototype.constructor === Boolean
var str = "String"
str.__proto__ === String.prototype
str.__proto__.__proto__ === Object.prototype
str.__proto__.constructor === String
String.prototype.__proto__ === Object.prototype
String.prototype.constructor === String
var object = {}
object.__proto__ === Object.prototype
object.__proto__.__proto__ === null
object.__proto__.constructor === Object
Object.prototype.__proto__ === null
Object.prototype.constructor === Object
- 以上代码会用到的几个构造函数分别是
Function,Number,Boolean,String,Object
- 而这些构造函数都是由 Function构造出来的, 所以
Function.__proto__ === Function.prototype
Array.__proto__ === Function.prototype
Object.__proto__ === Function.prototype
Number.__proto__ === Function.prototyp
Boolean.__proto__ === Function.prototyp
String.__proto__ === Function.prototype
原型链结构图如下:
总结
所有的构造函数都是由Function构造函数所构造出来的
Array.__proto__ === Function.prototype
所有的实例对象的proto属性都指向该构造函数的prototype属性
array.__proto__=== Array.prototype
所有的实例对象的proto.proto属性都指向的构造函数Object的prototype属性num.__proto__.__proto__ === Object.prototype
所有的原型的constructor属性都指向该构造函数
num.__proto__.constructor === Number