js对象定义方式:
-
字面式
var obj={ 属性名:属性值, 方法名:function(){ //... } }```
-
new Object()方式
var obj=new Object(); obj.属性名=属性值; obj.方法名=function(){...};
-
构造函数方式
function obj(var1,var2,...){ this.属性名=属性值; this.方法名=function(){}; } var o=new obj(var1,var2,...);
-
工厂方式
function fn(var1,var2,...){ var obj=new Object(); obj.属性名=var1; ... obj.方法名=function(){...}; return obj; } var o=fn(var1,var2,...);
-
原型方式
function obj(var1,var2,...){ obj.prototype.属性名=属性值; ... obj.prototype.方法名=function(){...}; } var o=new obj(var1,var2,...); //实例对象可以直接访问原型对象上的属性和方法 o.属性名; o.方法名();
-
混合方式
工厂方式会导致各个实例拥有各自的方法,不能共用方法;原型方式会导致每个实例共用属性,不能拥有实例各自的属性。混合方式可以解决这个问题,属性在对象上定义,方法在原型上定义。function obj(var1,var2,...){ this.属性名=属性值; } obj.prototype.方法名=function(){ alert(this.属性名); } var o=new obj(var1,var2,...); var o1=new obj(var1,var2,..); alert(o.方法名==o1.方法名)//弹出true
原型与原型链
函数都属于对象,它有一个prototype属性,叫做函数的原型对象,简称原型。普通对象没有prototype,但有__proto__属性,指向其构造函数的原型对象,举例:
function obj(var1,var2,...){
this.属性名=属性值;
this.方法名=function(){};
}
var o=new obj(var1,var2,...);
alert(o.__proto__==obj.prototype)//弹出true
//o的创建过程
//1,o={}
//2,o.__proto__=ob.prototype
//3,初始化o,obj.call(o);
继承
-
原型继承
function parent() { this.age = "18"; } parent.prototype.name = "小明"; parent.prototype.fn = function() { alert(this.name); }; function child() {} child.prototype = new parent(); child.prototype.name = "小红"; var ch = new child(); ch.fn();//弹出小红,后赋值会覆盖前面的赋值 alert(ch.age);//弹出18,原型方式可以继承父对象所有属性,包括自有属性和prototype对象
-
构造函数继承(对象冒充)
这种方式只能继承父对象的自有属性和方法,不能继承父对象原型上的属性和方法。function parent(name) { this.name = name; this.fn = function() { alert(this.name+this.age); }; } parent.prototype.age='18'; function child(name) { this.p = parent; this.p(name); this.name='小红' } var ch = new child("小明"); ch.fn();//弹出‘小红undefined’,说明后赋值会覆盖前面的赋值,并且对象冒充方式不能继承父对象prototype
-
call和apply方式继承
每个函数都自带有call和apply方法,call和apply方法可以改变this指向,实现继承。function parent(name,age){ this.name=name; this.age=age; this.fn=function(){ alert(this.name+this.age); } } var p=new parent('小明',22); p.fn();//弹出‘小明22’ function child(name,age){ parent.call(this,name,age); }; var ch=new child('小红',18); ch.fn();//弹出‘小红18’,子对象继承了父对象的方法,子对象实例与父对象实例互不影响 //apply方法同call方法,把参数整合到一个数组即可:parent.apply(this,[name,age]);