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();

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

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

  1. Java基础-初识面向对象编程(Object-Oriented-Programming)

    Java基础-初识面向对象编程(Object-Oriented-Programming) 作者:尹正杰 版权声明:原创作品,谢绝转载!否则将追究法律责任. Java是一门面向对象的程序设计语言.那么什 ...

  2. 2018.3.5 Java语言基础与面向对象编程实践

    Java语言基础与面向对象编程实践 第一章 初识Java 1.Java特点 http://www.manew.com/blog-166576-20164.html Java语言面向对象的 Java语言 ...

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

    介绍Javascript中面向对象编程思想之前,需要对以下几个概念有了解: 1. 浅拷贝和深拷贝:程序在运行过程中使用的变量有在栈上的变量和在堆上的变量,在对象或者变量的赋值操作过程中,大多数情况先是 ...

  4. Day7 - Python基础7 面向对象编程进阶

    Python之路,Day7 - 面向对象编程进阶   本节内容: 面向对象高级语法部分 经典类vs新式类 静态方法.类方法.属性方法 类的特殊方法 反射 异常处理 Socket开发基础 作业:开发一个 ...

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

    接上一篇 面向对象编程的理解? 答:面向对象编程,就是将你的需求抽象成一个对象,然后针对这个对象分析其特征(属性)与动作(方法).这个对象我们称之为类.面向对象编程思想其中一个特点就是封装,就是把你需 ...

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

    面试的时候,总会被问到,你对javascript面向对象的理解? 面向对象编程(object-oriented programming,OOP)是一种程序设计范型.它讲对象作为程序的设计基本单元,讲程 ...

  7. 02_python基础(面向对象编程)

    面向对象编程: 把一组数据结构和处理它们的方法组成对象(object),把相同行为的对象归纳为类(class),通过类的封装(encapsulation)隐藏内部细节,通过继承(inheritance ...

  8. Python基础之面向对象编程

    面向对象编程 —— Object Oriented Programming 简写 OOP 01. 面向对象基本概念 我们之前学习的编程方式就是 面向过程 的 面向过程 和 面向对象,是两种不同的 编程 ...

  9. ndk学习之c++语言基础复习----面向对象编程

    关于面向对象编程对于一个java程序员那是再熟悉不过了,不过对于C++而言相对java还是有很多不同点的,所以全面复习一下. 类 C++ 在 C 语言的基础上增加了面向对象编程,C++ 支持面向对象程 ...

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

    Python之路,Day6 - 面向对象学习   本节内容:   面向对象编程介绍 为什么要用面向对象进行开发? 面向对象的特性:封装.继承.多态 类.方法.     引子 你现在是一家游戏公司的开发 ...

随机推荐

  1. CentOS7.6安装JDK(Openjdk) - mvn package报错汇总

    错误一: No compiler is provided in this environment. Perhaps you are running on a JRE rather than a JDK ...

  2. 使用Tor创建.onion域名网站(创建暗网服务和暗网的网站)

    使用Tor 的.onion域名创建匿名服务器 Tor不仅可以提供客户端的匿名访问,Tor还可以提供服务器的匿名.通过使用Tor网络,用户可以维护位置不可知的服务器.当然如果要访问这个隐蔽的服务,客户端 ...

  3. aws s3 python sdk

    http://boto3.readthedocs.io/en/latest/reference/services/s3.html#S3.Client.get_object abort_multipar ...

  4. Render Texture

    [Render Texture] Render Textures are special types of Textures that are created and updated at runti ...

  5. Python解释器种类以及特点 (经典概括, 便于理解和记忆)

    CPython c语言开发的 使用最广的解释器 IPython 基于cpython之上的一个交互式计时器 交互方式增强 功能和cpython一样 PyPy 目标是执行效率 采用JIT技术 对pytho ...

  6. 小程序动态生成二维码,生成image图片

    前端: <image src="{{img_usrl}}" style="width:100%;height:104px;" bindlongtap=&q ...

  7. 通过args数组获取数据

    ----------siwuxie095                     通过 main 方法的 args数组 可以从控制台获取一组字符串数据     如:     package com.s ...

  8. Python入门之 字符串操作,占位符,比较大小 等

    Python  字符串 常用的操作 切片 左包括右不包括的原则 ________________ 比较字符串大小 eg: cmp("a",'b')   -1第一个比第二个小  0 ...

  9. Windows 安装 Maven 及 Eclipse 安装Maven插件

    环境说明: window 8.1 64bit Eclipse Version: Luna Release (4.4.0) Maven 3.0.5 Windows Maven 安装: 1.确保安装了JD ...

  10. xargs在linux中的使用详解-乾颐堂

    xargs在linux中是个很有用的命令,它经常和其他命令组合起来使用,非常的灵活. xargs是给命令传递参数的一个过滤器,也是组合多个命令的一个工具.它把一个数据流分割为一些足够小的块,以方便过滤 ...