Javascript基础编程の面向对象编程

javascript是解释型的语言,在编译时和运行时之间没有明显区别,因此需要更动态的方法。javascript没有正式的类的概念,我们可以使用在运行时创建新的对象类型来替代,并且可以随时更改已有对象的属性。

javascript是一种基于原型的面向对象的语言,即每个对象有个原型,对象从原型中继承属性和方法。当访问对象的属性或调用对象的方法时,解释器首先检查对象是否有个同名的实例属性或方法。如果有,就使用实例属性或方法;如果没有,解释器就检查对象的原型中是否有适当的属性或方法。在这样一个特殊的环境下,该类型(类)的所有对象公共方法和属性可以被封装在原型中,每个对象可以有代表该对象特定数据的实例属性。

在javascript中,原型关系是递归的。即,对象的原型也是一个对象,而原型的本身可能还有一个原型。这就意味着如果被访问的属性发现不是对象的实例属性,也不是对象的原型的属性,解释器将沿着原型链搜索到原型的原型。如果还没有找到,就继续沿原型链向上搜索。javascript中object是所有对象的超类,所以object是它搜索的终点。如果object中还没有找到,那么返回的值就是undefined。如果是在调用方法,则抛出error。

一、javascript面向对象基础

1、对象的创建

javascript中的对象使用一个new运算符和一个构造函数创建。构造函数是一个特殊类型的函数,它通过初始化对象要占据的内存,来准备一个新对象的使用。我们可以使用一个不带参数的构造函数,也可以使用一个带参数的构造函数,来创建对象。如:

var city = new String();
var city = new String(‘上海‘);

2、对象销毁和垃圾回收

对象和其他变量都需要使用内存,而一个计算机中内存资源是有限的。为了防止潜在的内存不足,某些编程语言强制要求程序员仔细的管理他们程序中内存的使用。幸运的是,javascript并不要求程序员管理内存。当javascript创建对象时,解释器自动给对象分配内存。当对象使用完毕后,解释器自动清理对象所用内存,即垃圾回收。

但是,如果我们的对象代码中包含了大量的数据操作,最好将不需要的数据用null来替换,以尽快释放资源。

var book = new Book();
....
大量数据操作后...
....
book = null;

如果对相同数据有多个引用,必须确保所有的引用设为null。否则,解释器将保留这些数据,以备再次需要。
    3、动态添加对象属性

var obj = new Object(‘hello world‘);
alert(obj.name);//undefined
obj.name=‘jiajia‘;
alert(obj.name);//jiajia

动态添加的属性,我们称之为实例属性,之所以叫实例属性,是因为它们仅出现在它们添加到的特定对象或实例中。与此相反还有一个公共属性,比如说string的length属性,所有string对象都具有这一公共属性。实例属性有利于为了某些特殊用途对已存在的对象进行补充或扩展。

4、动态删除对象属性

var mystring = new String(‘hello world‘);
mystring.isTrue = true;
delete mystring.isTrue;
alert(mystring.isTrue);//undefined;

java程序员注意,javascript中delete与Java中不同,它仅仅用在对象中删除属性或者从数组中删除元素,但是我们不能删除对象本身。

5、动态添加对象的方法

像添加属性方式一样,方法也可以动态添加:

var mystring = new String(‘hello world‘);
function alertSay(){alert(‘不行‘);};
mystring.sayno=alertSay;
mystring.sayno();//不行

以上是添加了一个实名函数,我们还可以添加一个匿名函数:

var mystring = new String(‘hello world‘);
mystring.sayno=function(){alert(‘不行‘);};
mystring.sayno();//不行

6、对象语句

如果程序中要使用某个对象的多个属性和方法,则可以考虑使用with语句,将需要使用其属性和方法的对象用with语句包含起来,语法:

with(对象){
    .....语句.....
}

例如:

with(document.myform){
     if(username.value==‘‘)
     if(password.value==‘‘)
}

for语句是一种特殊的循环语句,用于遍历一个对象的所有属性。注意是所有属性!
    例如,以下示例用for...in语句遍历了document对象的所有属性,并将其显示出来:

document.write(‘<h3>document对象的所有属性如下:</h3>‘);
for(var i in document){
    document.write(i+‘<br/>‘);
}

二、创建自定义的javascript类和对象

1、工厂方式

所谓工厂方式,就是先创建对象,然后往对象中添加属性和方法。

带参批量生产:

function createPerson(name){
     var personobj = new Object();
     personobj.name=name;
     personobj.say=function(){
         alert(‘who is‘+this.name);
     }
     return personobj;
 }
 var persion1 = createPerson(‘fanfan‘);
 var persion2 = createPerson(‘xiaoxiao‘);
 person1.say();//fanfan
 person2.say();//xiaoxiao

随着javascript正规起来,这种创建对象的方式并不提倡了。原因有二:

(1)语义上的,即这种方式不适用new运算符创建对象;

(2)功能上的,每次调用createPerson()函数,都建一个新的函数say()。这意味着每个对象都有自己版本的say()方法。然后在现实中,每个对象都是共享相同的方法。

2、构造函数的方式

与工厂方式类似,类名的第一个字母是大写。

function Person(name){
    this.name = name;
    this.say = function(){
      alert(‘who is‘+name);
    }
}
var person1 = new Person(‘fanfan‘);
var person2 = new Person(‘xiaoxiao‘);

我们可以看到,在构造函数内部没有创建对象,而是使用了this关键字。当用new运算符调用构造函数时,在构造函数第一行被执行之前就创建了一个对象,此时这个对象可以通过this运算符访问。然后,我们可以直接给this分配属性,而这个this是默认是作为函数值返回的。

然后,与工厂模式一样,构造函数方式也是没创建一个对象,就生成一个新函数。

3、原型方式

原型方式利用了对象的prototype属性。在object类中,每个对象都有一个prototype属性,该属性代表对象的父类。

function Person(){

}
Person.prototype.name=‘fanfan‘;
Person.prototype.say=function(){
alert(‘who is‘+this.name);
}
var person1 = new Person();
var person2 = new Person();

当new Person()被调用时,所有的prototype的属性和方法立即被分配给创建的对象,这样所有的Person实例就都包含了指向相同say()函数的指针。从语义上讲,属性和方法都属于一个对象,这就解决了前面重复生成函数的问题。此外,在这种方式中,我们还可以使用instanceof运算符检测给定变量所指向的对象类型。

alert(person1 instanceof Person);//true

但是,原型方式不能通过构造函数传递参数初始化属性值。
    4、混合构造函数和原型方式

使用构造函数方式定义对象的属性,使用原型方式定义对象的方法。这样,函数只创建一次,同时每个对象都有自己的对象属性实例。

 function Person(name){
     this.name=name;
 }
 Person.prototype.say=function(){
         alert(‘who is‘+this.name);
 }
 var person1 = new Person(‘fanfan‘);
 var persion2 = new Person(‘xiaoxiao‘);
 alert(person1.say());//fanfan
 alert(person1.say());//xiaoxiao

5、动态原型方式

function Person(name){
     this.name=name;
     if(typeof Person.initial == ‘undefined‘){
         Person.prototype.say=function(){
             alert(‘who is‘+this.name);
         }
         Person.initial = true;
     }

 }
 var person1 = new Person(‘fanfan‘);
 var persion2 = new Person(‘xiaoxiao‘);
 alert(person1.say());//fanfan
 alert(person1.say());//xiaoxiao

6、使用JSON格式创建对象

var personobj={
    firstname:‘fanfan‘,
    lastname:‘xiaoxiao‘,
    age:50,
    tellyourage:function{

         alert(‘yourage:‘+this.age)
    }
}

与工厂方式没有本质区别,只是更加快捷。
    三、对象继承实现

创建子类将继承超类的所有属性和方法,包括构造函数及方法的实现。记住,所有属性和方法都是公用的,因此子类可直接访问这些方法。子类还可添加超类中没有的新属性和方法,也可以覆盖超类中的属性和方法。

1、对象冒充

所谓对象冒充,就是新的类冒充旧的类(旧的类必须采用构造函数的方式),从而达到继承的目的,其原理如下:构造函数使用this关键字给所有属性和方法赋值(即采用类声明的构造函数方式)。因为构造函数只是一个函数,所以 可使ClassA的构造函数成为ClassB的方法,然后调用它。ClassB就会收到ClassA的构造函数中定义的属性和方法。

 function Person(name){

     this.name=name;
     this.say=function(){
             alert(‘who is‘+this.name);
         }

 }

我们知道,关键字this引用的事构造函数当前创建的对象。而在方法中,this指向的是所属的对象。这个原理是把People作为常规函数来建立继承机制,而不是作为构造函数。

function WhitePeople(name){
     this.inherit=People;//冒充
     this.inherit(name);//继承
     delete this.inherit;//删除继承
     this.area = function(){
        alert(‘我在欧洲‘);
     }
 }
 var tom=new WhitePeople(‘tom‘);
 tom.say();
 tom.area();

所以新属性和新方法必须在删除了继承后再定义,这样是为了避免覆盖父类的相关属性和方法。

对象冒充可以支持多继承,也就是说,一个类可以继承多个超类。

function Person(name){

     this.name=name;
     this.say=function(){
             alert(‘who is‘+this.name);
         }

 }
function Worker(pay,work){
    this.pay=pay;
    this.work=work;
}

function City_worker(name,pay,work){
    this.inherit = People;
    this.inherit(name);
    delete this.inherit;  

    this.inherit = Work;
    this.inherit(pay,work);
    delete this.inherit; 

}
var jerry=new City_worker(‘jerry‘,‘10000‘,‘coder‘);
jerry.say();
alert(jerry.work);

2、call方式

基类.call(对象,参数列表)

function WhitePeople(name){
     //this.inherit=People;//冒充
     //this.inherit(name);//继承
     //delete this.inherit;//删除继承
         People.call(this.name);
     this.area = function(){
        alert(‘我在欧洲‘);
     }
 }
 var tom=new WhitePeople(‘tom‘);
 tom.say();
 tom.area();

3、apply

apply()也是对象冒充一个封装函数。apply()方法有两个参数,用做this的对象和要传递给函数的参数的数组。其格式为:

基类.apply(对象,参数数组);

function City_worker(name,pay,work){
  People.apply(this,new Array(name));
  Worker.apply(this,[pay,work]);

}
var jerry=new City_worker(‘jerry‘,‘10000‘,‘coder‘);
jerry.say();
alert(jerry.work);

4、原型链

上面三种方式都是采用构造函数的方式继承,对应的,也具有原型函数方式的继承,原型链。

function Blue_collor(){

}
Blue_collor.prototype.name=‘jean‘;
Blue_collor.prototype.say=function(){
    alert(‘who is ‘+this.name);
}
function City_blue_collor(){

}
City_blue_collor.prototype = new Blue_collor();
var j1 = new City_blue_collor();
j1.say();

注意在使用原型链继承时,基类构造函数内不能有任何参数。

时间: 2024-10-08 13:42:01

Javascript基础编程の面向对象编程的相关文章

Day6 - Python基础6 面向对象编程

Python之路,Day6 - 面向对象学习 本节内容: 面向对象编程介绍 为什么要用面向对象进行开发? 面向对象的特性:封装.继承.多态 类.方法. 引子 你现在是一家游戏公司的开发人员,现在需要你开发一款叫做<人狗大战>的游戏,你就思考呀,人狗作战,那至少需要2个角色,一个是人, 一个是狗,且人和狗都有不同的技能,比如人拿棍打狗, 狗可以咬人,怎么描述这种不同的角色和他们的功能呢? 你搜罗了自己掌握的所有技能,写出了下面的代码来描述这两个角色 1 2 3 4 5 6 7 8 9 10 11

深入理解javascript中实现面向对象编程方法

介绍Javascript中面向对象编程思想之前,需要对以下几个概念有了解: 1. 浅拷贝和深拷贝:程序在运行过程中使用的变量有在栈上的变量和在堆上的变量,在对象或者变量的赋值操作过程中,大多数情况先是复制栈上的信息,这样就会出现以下情况,如果变量是对象,那么这一操作,复制的只是真正对象所在 的堆内存空间的起始地址,这就是所谓的浅拷贝,如果是深拷贝,则是在内存堆空间中重新分配一个内存,并把分配的内存的起始地址复制过去. 2. 引用类型数据和值类型数据:谈到引用类型数据和值类型数据,自然而然的联想到

javaScript设计模式之面向对象编程(object-oriented programming,OOP)(一)

面试的时候,总会被问到,你对javascript面向对象的理解? 面向对象编程(object-oriented programming,OOP)是一种程序设计范型.它讲对象作为程序的设计基本单元,讲程序和数据封装其中,以提高程序的重用性.灵活性和扩展性. 一.举个例子 有这么一个需求:做一个验证表单功能,仅需要验证用户名,邮箱,密码等 觉得在项目产品开发中,自己是这么写的 function checkName(){ //验证姓名 } function checkEmail(){ //验证邮箱 }

Python基础6-1 面向对象编程

概述 面向过程:根据业务逻辑从上到下写垒代码 函数式:将某功能代码封装到函数中,日后便无需重复编写,仅调用函数即可 面向对象:对函数进行分类和封装,让开发"更快更好更强..." 面向过程编程最易被初学者接受,其往往用一长段代码来实现指定功能,开发过程中最常见的操作就是粘贴复制,即:将之前实现的代码块复制到现需功能处. while True:     if cpu利用率 > 90%:         #发送邮件提醒         连接邮箱服务器         发送邮件     

Python基础day-16[面向对象编程(未完)]

面向对象: 相对于面向过程编程来讲,面向对象的扩展性比较强.但是同时带来的问题是可控性差,面向对象编程不像面向过程那样可以很精准的预测结果.面向对象程序一旦开始就由对象之间进行交互解决问题. 面向对象程序设计只是用来解决程序扩展性的. 什么是对象: 举一个例子:每个人都有自己特征和技能,那么每个人就是一个对象.对象就是特征与技能的结合体. 什么是类: 每个人都有自己独有特征也有和别人同样的技能或者特征.例如:基本每个人都会吃饭,都会睡觉,都会说话或者某两个人眼睛都挺大.我们可以把这些共同的技能或

Python基础-第六天-面向对象编程

本篇内容 1.面向对象编程介绍 2.类的定义及各部分的介绍 3.属性 4.方法 5.面向对象的特性-封装 6.面向对象的特性-继承 7.面向对象的特性-多态 8.新式类和经典类 一.面向对象编程介绍 1.编程的原则 无论用什么编程范式来编程都要记住的原则是,避免写重复代码,代码要易扩展.一定要遵循可读性好.易扩展的原则. 2.面向对象编程(Object-Oriented Programming)介绍 OOP编程的主要作用是使代码修改和扩展变的更容易: 面向对象编程是利用类和对象来帮助我们实现功能

python基础之面向对象编程介绍、类和对象

面向对象变成介绍 面向过程编程 核心是过程(流水线式思维),过程即解决问题的步骤,面向过程的设计就好比精心设计好一条流水线,考虑周全什么时候处理什么东西.主要应用在一旦完成很少修改的地方,如linux内核.git.apache服务器等 优点:极大的降低了程序的设计复杂度 缺点:可扩展性差,改动一个地方很可能要改多个地方,牵一发而动全身 面向对象编程:不是编程的全部,只是用来解决软件可扩展性的 核心是对象(上帝式思维),对象作为程序的基本单元,一个对象包含了数据和操作数据的函数.面向对象就是把计算

Python基础6 面向对象编程

本节内容: 面向对象编程介绍 为什么要用面向对象进行开发? 面向对象的特性:封装.继承.多态 类.方法. 引子 你现在是一家游戏公司的开发人员,现在需要你开发一款叫做<人狗大战>的游戏,你就思考呀,人狗作战,那至少需要2个角色,一个是人, 一个是狗,且人和狗都有不同的技能,比如人拿棍打狗, 狗可以咬人,怎么描述这种不同的角色和他们的功能呢? 你搜罗了自己掌握的所有技能,写出了下面的代码来描述这两个角色 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 def per

JavaScript中的面向对象编程,详解原型对象及prototype,constructor,proto,内含面向对象编程详细案例(烟花案例)

面向对象编程: 面向:以什么为主,基于什么模式 对象:由键值对组成,可以用来描述事物,存储数据的一种数据格式 编程:使用代码解决需求 面向过程编程: 按照我们分析好的步骤,按步骤解决问题 优点:性能比面向对象高,适合跟硬件联系很紧密的东西 缺点:没有面向对象那么容易维护,复用,扩展 面向对象编程: 把事务分解成一个个对象,然后由对象之间分工与合作,分工明确,每一个对象都是功能中心 面向对象特性:封装性.继承性 .多态性 封装性:将一个功能封装起来,小封装 将多个函数封装起来,整体封装起来形成一个

python基础之面向对象编程

面向对象编程思想 面向对象是一门编程思想,编程思想仅仅是一门思想,与任何技术无关 核心是对象两字,对象可以理解为特征与技能的结合体 基于该编程思想编写程序,就好比创造世界,一种造物主的思维方式 优点:可扩张性强 缺点:编写程序的复杂难度比面向过程高 以上都是纯理论,理解下用自己的话能编出来就行,下面来说说核心对象 在现实世界中,通过一个个的对象,根据相同的特征和行为,再分门别类. 但是在程序中,必须先有类,再通过调用类,创建对象. 那么,咱们如何定义类,又如何创建对象呢?(暂时还是先说理论吧,不