其实之前对js原型链有个基本的理解,但工作中用到的并不多,逐渐忘记了。所以准备写个博客。
我觉得首先得明白一个,就是每一次创建一个构造函数(其实就是普通的函数)的时候,都会根据一个特定的规则创建一个原型属性(prototype)。其中包括两项:construct和__proto__
其次先来看下构造函数创建对象:
function Person(){
this.name='yy',
this.sayname=function(){
alert(this.name)
}
}
var person1 = new Person()
var person2 = new Person()
new 实例对象是所做的步骤
1:先创建一个空的对象
2:将构造函数的作用域赋给新创的对象(即 this指向这个新对象)
3:执行构造函数里面的代码(为这个新的对象添加新的属性)
4:返回新的对象
单纯构造函数的弊端:每创建的示例对象都会创建一个新的实例方法,而创建的实例方法是完成同一个功能,导致出现冗余的实例方法
接着就是原型链创建对象:
funcion Person(){}
Person.prototype={
construct:Person,//以字面量的形似创建的一个原型对象,之前shuo
name:'yy',
say:function(){
alert(this.name)
}
}
或者
Person.prototype.name='yy'
Person.prototype.say=function(){
alert(this.name)
}
var person1 =new Person()
var person2 =new Person()
1:创建一个空的的函数
2:对这个函数prototype添加新的对象(修改construct值以及属性值和方法)construct指向的是构造函数,如果不是不手动赋值默认指向Object
3:创建一个实例时,实例的指针construct指向函数的原型对象(prototype)而不是构造函数
4:返回一个新对象
单纯原型链创建对象弊端:多个对象复用同一个属性值,多个实例之间对这个属性值都可能做出修改。
通过isPrototypeOf()判断该实例对象与构造函数是否存在关系==>true
通过Object.getPrototypeOf()获取实例的原型对象
通过实例.hasOwnProperty('xxx')检测一个属性xxx是否属于实例属性
通过Object.getOwnPropertyDescriptor(实例,'xxx')获取实例属性的描述
通过Object.getOwnpropertyNames()获取所有属性名包括不可枚举的
组合构造函数和原型链创建对象步骤:
1:创建一个构造函数,
2:给构造函数添加原型(prototype)方法
3:new实例的过程(先创建一个空的对象=》将构造函数的作用域指向新创建的对象=》执行构造函数里面的代码、实例对象的construct指向构造函数的原型)
4:返回一个新的对象
优势:每个实例对象拥有自己的的属性副本,同时又共享着方法的引用,最大限度的节省了内存
1动态原型模式:
在构造函数里面执行,
if (typeof this.sayName != "function"){
Person.prototype.sayName = function(){ alert(this.name);
}; }