javascript 面向对象的对象创建与继承
2012-11-19 11:52
585 查看
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.
创建对象的方法
工厂模式
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);
}
这种继承方式只引用了一次构造函数,不改变其它东西。这种方式是目前最理想的继承方式。
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面向对象中的对象创建、继承、封装等实现方式
- JavaScript面向对象中的属性,对象创建,继承
- 全面理解Javascript的面向对象(二)--创建对象与继承
- JavaScript [面向对象] 对象创建
- JavaScript高级程序设计【面向对象-创建对象2】
- JavaScript对象创建及继承原理实例解剖
- 在没有类的情况下,JavaScript如何创建对象、实现继承?
- javascript 创建对象与继承总结和回顾
- JavaScript对象之面向对象的三种继承方式
- JavaScript面向对象之对象创建
- javascript的函数、创建对象、封装、属性和方法、继承
- JavaScript高级程序设计之面向对象的程序设计之创建对象之组合使用构造函数模式和原型模式 第6.2.4讲笔记
- 【JavaScript高级程序设计】对象的创建与继承
- JavaScript的中对象创建和继承原理
- JavaScript中怎样创建对象和继承
- JavaScript基础——面向对象的程序设计(一)创建对象的几种方式总结
- javascript面向对象学习笔记——创建对象(转)
- JavaScript2种构造函数创建对象的模式以及继承的实现
- Java程序员从笨鸟到菜鸟之(二十九)javascript对象的创建和继承实现
- javascript 创建对象——类,继承