javascript中的对象创建与继承
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中的对象创建与继承的更多相关文章
- js中的对象创建与继承
对象创建 1.工厂模式 优点:解决了创建多个相似对象的问题 缺点:没有解决对象识别问题:每一个对象都有一套自己的函数,浪费资源 function createPerson(name, age, job ...
- javascript中的对象之间继承关系
相信每个学习过其他语言的同学再去学习JavaScript时就会感觉到诸多的不适应,这真是一个颠覆我们以前的编程思想的一门语言,先不要说它的各种数据类型以及表达式的不同了,最让我们头疼,恐怕就是面向对象 ...
- javascript中的对象,原型,原型链和面向对象
一.javascript中的属性.方法 1.首先,关于javascript中的函数/“方法”,说明两点: 1)如果访问的对象属性是一个函数,有些开发者容易认为该函数属于这个对象,因此把“属性访问”叫做 ...
- Javascript中的对象和原型(3)
在Javascript中的对象和原型(二)中我们提到,用构造函数创建的对象里面,每个对象之间都是独立的,这样就会降低系统资源的利用率,解决这样问题,我们就要用到下面提到的原型对象. 一 原型对象 原型 ...
- JavaScript中的对象描述符(属性特性)
我们先创建一个对象: var person = { name: "Nicholas", _job: "Software Engineer", sayName: ...
- Javascript中的对象和原型(三)(转载)
在Javascript中的对象和原型(二)中我们提到,用构造函数创建的对象里面,每个对象之间都是独立的,这样就会降低系统资源的利用率,解决这样问题,我们就要用到下面提到的原型对象. 一 原型对象 原型 ...
- JavaScript中的对象与原型—你不知道的JavaScript上卷读书笔记(四)
一.对象 对象可以通过两种形式定义:声明(文字)形式和构造形式.即: var myObj = { key: value // ... }; 或: var myObj = new Object(); m ...
- javascript中的对象字面量为啥这么酷
原文链接 : Why object literals in JavaScript are cool 原文作者 : Dmitri Pavlutin 译者 : neal1991 个人主页:http://n ...
- JavaScript中判断对象类型方法大全1
我们知道,JavaScript中检测对象类型的运算符有:typeof.instanceof,还有对象的constructor属性: 1) typeof 运算符 typeof 是一元运算符,返回结果是一 ...
随机推荐
- 【zoj3645】高斯消元求解普通线性方程
题意: 给你一个方程组(含有12个方程),求(x1,x2,x3,x4,x5,x6,x7,x8,x9,x10,x11) 方程组的形式是一个二次方程组 (ai1-x1)^2 + (ai2-x2)^2 +( ...
- centos6.5下安装svn并且实现多项目管理配置方案
#安装SVN服务器 yum install subversion #在home下创建svn根目录 mkdir /home/svn #在 /home/svn下创建pro1 , pro2, pro3 三个 ...
- HTML5 Canvas时间效果
Canvas 时间效果: function clockTest() { var canvas = document.getElementById('canvas'); if (!(canvas &am ...
- 转载:WebView
前言 现在很多App里都内置了Web网页(Hyprid App),比如说很多电商平台,淘宝.京东.聚划算等等,如下图 那么这种该如何实现呢?其实这是Android里一个叫WebView的组件实现的.今 ...
- 安装Vue.js devtools
1.下载安装 https://github.com/vuejs/vue-devtools#vue-devtools 通过以上地址下载安装包,解压以后进入文件,按住shift,点击鼠标右键打开命令窗口 ...
- 火狐浏览器下点击a标签时出现虚线的解决方案
1.兼容性问题 火狐浏览器下点击a标签时出现虚线 2.解决方案 a:focus { outline: none;}
- C++学习之路(五):复制构造函数与赋值运算符重载
之前没有细想过两者的区别,今天对此进行简要记录,后续完善补充. 复制构造函数是在类对象被创建时调用的,但是赋值运算符是被已经存在的对象调用完成赋值操作. 复制构造函数只在对象实例化时才被调用,即在复制 ...
- monkey测试===Android测试工具Monkey用法简介(转载)
Monkey是Android中的一个命令行工具,可以运行在模拟器里或实际设备中.它向系统发送伪随机的用户事件流(如按键输入.触摸屏输入.手势输入等),实现对正在开发的应用程序进行压力测试.Monkey ...
- pycaffe使用.solverstate文件继续训练
import caffe solver_file = "solver.prototxt" solverstate = "xx.solverstate" caff ...
- 判断ArcSDE是否安装成功
安装SDE后在ArcMap的Toolboxes - Data Management Tools中会新增Geodatabase Administration 即数据管理工具下面会新增地理数据库管理