javascript 面向对象的对象创建与继承

javascript中对象的定义:无序属性的集合,其属性包含基本值、对象或者函数。

javascript中有两种属性:数据属性和访问器属性。
数据属性包含一个数据值的位置,在这个位置可以读取和写入值。数据属性有4个描述其行为的特性。
1.[[Configurable]]:表示能否通过delete删除属性和重新定义属性。
2.[[Enumerable]]:表示能否通过for-in循环返回属性。
3.[[Writeable]]:表示能否修改属性的值
4.[[Value]]:表示这个属性的值

实例:
javascript: var person={};  
Object.defineProperty(person,"name",{writable:false,value:"seacean"}); 
 console.log(person.name); 
 person.name="hello wrold!"; 
 console.log(person.name);
运行结果显示是

这些数据属性的配置如果有设置,在严格模式下进行非法操作会返回错误,非严格模式会忽略。


访问器属性不包含任何数值,包含一对get/set函数。
1.[[Configurable]]:表示能否通过delete删除属性和重新定义属性。
2.[[Enumerable]]:表示能否通过for-in循环返回属性。
3.[[get]]:在读取属性的时候调用的函数
4.[[set]]:在设置属性的时候调用的函数
访问器的属性和数据属性一样,只能使用Object.defineProperty来进行定义。这样的话,数据属性和访问器属性可以同时定义。
定义多个属性的方法是Object.defineProperties.


创建对象的方法

工厂模式
function createPerson(name,age,job){
   var o=new Object();
   o.name=name;
   o.age=age;
   o.job=job;
   o.sayName=function(){ return this.name;};
   return o;
}
javascript:
function createPerson(name,age,job){     var o=new Object();     o.name=name;     o.age=age;     o.job=job;     o.sayName=function(){ return this.name;};     return o;  }    
这是一个创建Person类的工厂方法

构造函数方式

function Person(){
  this.name="nicole";
}

原型模式

function Person(){};
Person.prototype.name="nicole";

这些方法各有优缺点,工厂无法让创建变得更像面向对象,构造函数无法保存类共享属性,原型的所有属性都是共享的。

结合各自的优缺点,我们使用构造函数创建每个类中非静态的属性和方法,原型创建类中的静态属性和方法。
function Man(obj){
  this.name=obj.name;
}

Man.prototype={
    constructor:Person,
   sayName:function(){alert(this.name);}
}


还有一类安全程度更高的构造函数,成为稳妥构造函数,不使用this,不使用new操作符调用构造函数,与别的对象没有关联

function Person(name,age,job){
  var obj=new Object();
   obj.name=name;
  obj.age=age;
   obj.job=job;
  return obj;
}

一般情况下我们用不到使用继承这种情况,使用到继承这种情况的时候大多是定义框架,开发组件等等。而且一般的web开发是用不到继承的。但是一用到继承就说明面对的情况很复杂。

面向对象的继承关系显得有些复杂
js的继承是实现上的继承,造成继承的事实。
原型链方式继承
function SuperType(){
   this.property=true;
}

SuperType.prototype.getSuperValue=function(){
   return this.property;
}


function SubType(){
   this.subproperty=false;
}

SubType.prototype=new SuperType();

SubType.prototype.getSubValue=function(){
   return this.subproperty;
}

var instance=new SubType();
alert(instance.getSuperValue());

这个说明了继承的含义和形式,继承就是采用上面的样子,不断扩展原型。
也可以将SuperType里面的全部属性和方法copy到SubType中,造成事实上的继承关系。

继承关系中的方法重写
在SubType.prototype=new SuperType();之后可以添加对里面方法的重写为SubType.prototype.getSuperValue=function(){
    return this.subproperty;
}


继承的另一种方式
使用call,apply方法
借用构造函数式继承
function SuperType(name){
 this.name=name;
  this.colors=["red","yellow","orange"];
}

function SubType(){
    SuperType.call(this,"max");
   this.age=100;
}

组合继承方式,组合前面两种情况
function SuperType(name){
 this.name=name;
  this.colors=["red","yellow","orange"];
}

SuperType.prototype.sayName=function(){
   alert(this.name);
}

function SubType(name,age){
    SuperType.call(this,name);
    this.age=age;
}

SubType.prototype=new SuperType();
SubType.prototype.sayAge=function(){
   alert(this.age);
}

这样子类本身通过构造函数可以扩展,通过prototype也可以扩展

原型式继承
基于已有的对象创建新的对象,同时还不必因此创建新的对象

function  getPerson(/*object*/ obj){
   function F(){}
   F.prototype=obj;
return new F();
}
obj是已将存在的对象,新对象的类型不需要给出明确定义

寄生式继承
function  createAnother(original){
   var clone=getPerson(original);//进行新的包装
   clone.color="red";
   clone.sayColor=function(){alert(this.color);};
  return clone;
}
在这里面,original是一个已存在的对象,进入函数内要进行添加新的属性和方法,返回一个新的对象。这个不是通过构造函数方式运作的。

寄生组合式继承
function SuperType(name){
 this.name=name;
  this.colors=["red","yellow","orange"];
}

SuperType.prototype.sayName=function(){
   alert(this.name);
}

function SubType(name,age){
    SuperType.call(this,name);
    this.age=age;
}

function inheritPrototype(subType,superType){
   var proto=object(superType.prototype);
   proto.constructor=subType;
  subType.prototype=proto;
}

inheritPrototype(SubType,SuperType); 
//对子类父类之间的关系进行修正

SubType.prototype.sayAge=function(){
   alert(this.age);
}

这种继承方式只引用了一次构造函数,不改变其它东西。这种方式是目前最理想的继承方式。
var person={};
Object.defineProperty(person,"name",{writable:false,value:"seacean"});
console.log(person.name);
person.name="hello wrold!";
console.log(person.name);

你可能感兴趣的:(javascript 面向对象的对象创建与继承)