js是一门基于原型的面向对象语言,与传统的面向对象如Java,C#相比,它在对象创建及继承上有自己独特的实现方式,本文主要描述js中对象创建及继承的一些实践。

1.对象创建

方式一:工厂模式创建对象

<script>

    function createPerson(name,age,job)
{
var o=new Object();
o.name=name;
o.age=age;
o.job=job;
o.sayName=function(){
alert(this.name);
};
return o;
}
//这就是工厂方式创建对象
var a=createPerson('my',27,'student');
a.sayName();
</script>

  这种方式就是将对象属性作为参数传入函数,然后在函数中创建一个新对象再返回给外部使用,属于典型的输入处理输出模式,优点在于简单易于理解也很好的实现了对象的创建和隔离,缺点在于不符合典型OOP语言创建对象实例的做法,而且这样创建出来的对象都属于object类型而不能进一步确定其属于哪个具体的对象类型。

方式二:构造函数创建对象

function Person(name,age,job){
this.name=name;
this.age=age;
this.job=job;
this.sayName=function(){
alert(this.name);
} }
var p1=new Person('my',27,'stu');
// 这是使用构造函数来创建对象
p1.sayName();

  这种方式使用function来模拟一个类,通过调用这个类的构造函数通过new的方式实例化一个对象,这符合经典OOP创造实例对象的做法,同时也可以确定这个实例属于哪个具体的类型,这里是Person类的实例

,但是这种方式造成的缺点在于每个实例的方法都要在创建该对象时被创建一次,function本质上是一个object,这样做对内存浪费较大,实际上,对于多个不同实例他们的方法是共同引用一个function的关系。

方式三:基于原型创建对象

<script>
function Person(){}
Person.prototype.name='my';
Person.prototype.age=27;
Person.prototype.job='stu';
Person.prototype.sayName=function() {
alert(this.name);
} var p1=new Person(); p1.sayName();
</script>

  这种方式利用每个函数都具有一个原型并且它的多个实例都共享该原型的特性,将该类的属性和方法都挂载到了其原型上,这样做的好处是让多个实例共享了一个方法定义,但是其确定也很明显,即不能通过传参去调用构造函数,构造函数内部的属性都是硬编码的,同时任一实例对其自身的引用类型的属性修改都会影响到其他实例

方式四:构造函数结合原型方式

//属性放在构造函数
//实例间不会相互影响
function Person(name,age,job){
this.name=name;
this.age=age;
this.job=job;
}
//方法放在原型中
//节省内存
Person.prototype.sayName=function() {
alert(this.name);
} //使用组合方式创建对象
var p1=new Person('my',27,'stu'); p1.sayName();

  这种方式综合了构造函数和原型的优点,将属性等定义5放在构造函数中,实现了不同实例间的隔离,使之不会互相影响,同时又将方法定义挂载到了原型上,使多个实例共享一个方法定义(方法体),节省了内存空间,但是这种方式实际上将两种方式人为分开了,调用构造函数之后还要再去操作其原型,不符合经典OOP语言创建对象的方式。

方法五:动态原型方式

    function Person(name,age,job){
this.name=name;
this.age=age;
this.job=job;
if(typeof this.sayName!='function'){
this.sayName=function(){
alert(this.name);
}
}
} var p1=new Person('my',27,'stu');
p1.sayName();

  该方式将方法四操作原型的代码直接放入到了构造函数中,同时在new该类型的实例的时候进行判断,如果存在function实例,就不创建,否则创建function,实现了多个实例共享一个方法体的单例模式,该模式也是目前广为使用的,比较好的一种对象实例创建方式。

在创建对象较好实现的基础上,我们来讨论js中的继承。

方式一:基于原型链的继承

function SuperType(){
this.color=['a','b','c']; }
function SubType(){ }
SubType.prototype=new SuperType();
var a1= new SubType();
alert(a1.color);//a,b,c
a1.color.push('d');
var a2=new SubType();
alert(a2.color);//a,b,c,d

  该方法是将子类的原型指向父类的一个实例,子类就具有了父类的方法和属性,但是存在两个缺点,其一是对于父类引用类型的属性来讲,对于其子类任何实例对该属性的操作,其他实例都会受影响,其二是子类继承无法传参到父类,继承的属性无法控制,只能通过修改完成;

方法二:对象冒充继承

function Person(name){
this.name=name;
this.sayName=function(){
alert(this.name);
}
}
function Worker(name,age){
Person.call(this,name);
this.age=age;
}
var w1=new Worker('my',27);
//alert(w1.name);
w1.sayName();

  该种继承方式实现了通过传参去初始化子类的实例,达到了多个实例之间属性方法的隔离,即不会相互影响,但是同样对于方法的继承由于是调用call方法执行父类构造函数中的代码,相当于每次都要创造一个function,这样是对内存的浪费。

方法三:组合继承

 function SuperType(name){
this.name=name; }
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);
} var s1=new SubType('my',27);
s1.sayAge();
s1.sayName();

  该种类型的方法是将对属性的继承采用对象冒充的方式,将对方法的继承基于原型链方式,同时对于父类自身其定义也采取上面所讲的属性定义在构造函数中,方法定义在原型中,这样才能够配合这两种不同方式完成组合继承。

javascript中的对象创建与继承的更多相关文章

  1. js中的对象创建与继承

    对象创建 1.工厂模式 优点:解决了创建多个相似对象的问题 缺点:没有解决对象识别问题:每一个对象都有一套自己的函数,浪费资源 function createPerson(name, age, job ...

  2. javascript中的对象之间继承关系

    相信每个学习过其他语言的同学再去学习JavaScript时就会感觉到诸多的不适应,这真是一个颠覆我们以前的编程思想的一门语言,先不要说它的各种数据类型以及表达式的不同了,最让我们头疼,恐怕就是面向对象 ...

  3. javascript中的对象,原型,原型链和面向对象

    一.javascript中的属性.方法 1.首先,关于javascript中的函数/“方法”,说明两点: 1)如果访问的对象属性是一个函数,有些开发者容易认为该函数属于这个对象,因此把“属性访问”叫做 ...

  4. Javascript中的对象和原型(3)

    在Javascript中的对象和原型(二)中我们提到,用构造函数创建的对象里面,每个对象之间都是独立的,这样就会降低系统资源的利用率,解决这样问题,我们就要用到下面提到的原型对象. 一 原型对象 原型 ...

  5. JavaScript中的对象描述符(属性特性)

    我们先创建一个对象: var person = { name: "Nicholas", _job: "Software Engineer", sayName: ...

  6. Javascript中的对象和原型(三)(转载)

    在Javascript中的对象和原型(二)中我们提到,用构造函数创建的对象里面,每个对象之间都是独立的,这样就会降低系统资源的利用率,解决这样问题,我们就要用到下面提到的原型对象. 一 原型对象 原型 ...

  7. JavaScript中的对象与原型—你不知道的JavaScript上卷读书笔记(四)

    一.对象 对象可以通过两种形式定义:声明(文字)形式和构造形式.即: var myObj = { key: value // ... }; 或: var myObj = new Object(); m ...

  8. javascript中的对象字面量为啥这么酷

    原文链接 : Why object literals in JavaScript are cool 原文作者 : Dmitri Pavlutin 译者 : neal1991 个人主页:http://n ...

  9. JavaScript中判断对象类型方法大全1

    我们知道,JavaScript中检测对象类型的运算符有:typeof.instanceof,还有对象的constructor属性: 1) typeof 运算符 typeof 是一元运算符,返回结果是一 ...

随机推荐

  1. JDK工具学习

    javap: 可以对照源代码和字节码,从而了解很多编译器内部的工作. 查看class字节码:JDK有自带的工具包,使用javap命令打开.class文件就行 javap -c JAVAPTest

  2. Item27--优先考虑泛型方法

    类型推导:发生在以下三个地方.1.Java编译器根据泛型方法传入的参数,推导出具体的类型.2.Java编译器,根据泛型构造器传入的类型来推导出实际要构造的实例类型.3.Java编译器根据表达式的目标类 ...

  3. 自定义View的实现流程

    1.继承View组件,比如,LabelView继承了View   2.重写两个构造方法,比如,对于自定义View LabelView   LabelView(Context context),如果该自 ...

  4. NGINX: 返回大 JSON 数据不完整的问题

    说明: 内容全部来自 [ CSDN 金玮良 ] nginx 返回数据不完整的问题 当nginx 遇到大数据流时,会把数据先放在自己的缓冲区,然后一并发给客户端. 那如果这个结论成立, 那一次请求的数据 ...

  5. 如何使用webpack打包你的项目

    webpack是前端开发中比较常用的打包工具之一,另外还有gulp,grunt.之前没有涉及过打包这块,这里介绍一下使用webpack打包的流程. Grunt和Gulp的工作方式是:在一个配置文件中, ...

  6. jsp之jstl核心标签库

    JSTL核心标签库技术 1. JSTL介绍 在JSP页面中即可书写html,也可以书写Java代码,导致页面混乱,维护,修改,升级难度加大,于是国际上不同的公司在实际应用中,根据页面的需求将Java代 ...

  7. Java 中的成员内部类

    内部类中最常见的就是成员内部类,也称为普通内部类.我们来看如下代码: 运行结果为: 从上面的代码中我们可以看到,成员内部类的使用方法: 1. Inner 类定义在 Outer 类的内部,相当于 Out ...

  8. vue-实现倒计时功能

    JavaScript 创建一个 countdown 方法,用于计算并在控制台打印距目标时间的日.时.分.秒数,每隔一秒递归执行一次. msec 是当前时间距目标时间的毫秒数,由时间戳相减得到,我们将以 ...

  9. 虚拟机出现intel vt -x 处于禁用状态打不开处理方式

    处理方式 . 1 进入bios 以华硕主板为例 进入高级模式找到cpu虚拟技术 打开虚拟技术支持 其它电脑找到这个

  10. 对list对象进行排序

    List<LjlSevOrdersVO> list = ljlSevOrdersService.findSevForOrders(ljlSevOrdersVO); //查出所有是自愿者的订 ...