在js中建立对象能够有多种方式,好比字面量和构造函数的方式,可是这两种方式有缺点:产生大量重复的代码。
1.工厂模式: 不能肯定对象的类型。(即instanceof没法判断。p1 instanceof ob-->false
)web
function ob(name,sex){ var o=new Object(); o.name=name; o.sex=sex, o.sayName=function(){ alert(this.name); } return o; } var p1=ob("xs",1) var p2=ob("ys",2) console.log(p1.name)
2.构造函数模式:缺点时相同的方法都要在每一个实例上建立一遍,建立的两个方法是不一样的,所以,实例其实并无共享这个方法,而是,各自建立了一个函数。若是将方法定义为全局函数,内部方法经过指针指向这个全局函数会让这个自定义对象缺失封装性。数组
function ob(name,age){ this.name=name; this.age=age; this.say=function(){ alert(this.name) } } var p1=new ob("xjf",12); console.log(p1); console.log(p1 instanceof ob)//--true;
3.原型模式:将属性和方法所有添加到这个对象的原型对象prototype中,每一个对象都包含一个prototype属性,它指向这个函数的原型对象,这个原型对象包含了全部对象实例共享的属性和方法。bash
function ob(){ } ob.prototype.name="xxj"; ob.prototype.sex="nan"; ob.prototype.say=function(){ return this.name } var p1=new ob() console.log(p1.name); console.log(p1 instanceof ob); console.log(p1.say())
全部原型对象都会得到一个constructor属性,这个属性指向原型对象所在函数。当为对象实例添加一个同名属性时,这个属性会覆盖原型的属性。
hasOwnProperty()
方法能够检测一个属性是否存在于对象实例而非对象原型中。(若存在于对象实例中则返回“true”,若存在于原型中则返回“false”)。
"in"
方法则不管是存在于对象实例中仍是原型对象中都会返回true.
for-in
循环,返回的是全部能经过对象访问的,可枚举的属性,不管是对象实例的属性,仍是对象原型上的属性。
Object.keys(object)
方法取得对象上全部可枚举的属性,返回一个包含全部可枚举属性的字符串数组。
更简单的原型语法svg
function ob(){ } ob.prototype={ name:"xx", sex:"nan", say:function(){ console.log(this.name)}
这样写的好处是省去了不少的object.prototype代码。可是,每建立一个函数的同时就建立了他的prototype对象而且自动添加了coonstructor属性。可是简单的写法意味着:咱们重写了整个ob的原型对象,所以,此时的constructor也再也不指向建立这个原型对象的函数ob了,而是指向了object构造函数。
能够在prototype对象中添加“constructor:ob
”从新设置。函数
function ob (){ } ob.prototype.name="xx"; ob.prototype.say=function(){ console.log(); }//第一种写法只是在prototype对象中添加了name,say属性而已,此时prototyp的constructor指向ob. function ob (){ } ob.prototype={ name:"xx", age:"12", say:function(){ console.log() } } //第二种写法本质上重写了prototype对象。此时的constructor已经再也不指向ob.
原型对象存在的问题,全部实例默认状况下都会取得相同的属性值,更重要的是对于包含引用类型值的属性来讲,不一样的对象实例对属性的操做对在这些对象实例中共享。this
function ob(){ } ob.prototype={ constructor:ob, num:[1,2,3] } var p1=new ob(); p1.num.push('4'); var p2=new ob(); console.log(p4.num)--->1,2,3,4
4.组合使用构造函数模式和原型模式spa
function ob(name,sex,num){ this.name=name; this.sex=sex; this.num=num } ob.prototype={ constructor:ob, sayname:function(){ console.log(); } }