JavaScript面向对象简介
JavaScript 的核心是支持面向对象的,同时它也提供了强大灵活的OOP 语言能力。本文从对面向对象编程的介绍开始,带您探索JavaScript 的对象模型,最后描述 JavaScript 当中面向对象编程的一些概念。
复习JavaScript
如果您对JavaScript 的概念(如变量、类型、方法和作用域等)缺乏自信,您可以在重新介绍JavaScript这篇文章里学习这些概念。您也可以查阅这篇JavaScript 1.5 核心指南。
面向对象编程
面向对象编程是用抽象方式创建基于现实世界模型的一种编程模式。它使用先前建立的范例,包括模块化,多态和封装几种技术。今天,许多流行的编程语言(如Java,JavaScript,C#,C+ +,Python,PHP,Ruby 和Objective-C)都支持面向对象编程(OOP)。
面向对象编程可以看作是使用一系列对象相互协作的软件设计,相对于传统观念,一个程序只是一些函数的集合,或简单的计算机指令列表。在OOP中,每个对象能够接收邮件,处理数据和发送消息给其他对象。每个对象都可以被看作是一个独立的小机器有不同的作用和责任。
面向对象程序设计的目的是促进更好的编程灵活性和可维护性,并在大型软件工程中广为流行。凭借其十分注重的模块化,面向对象的代码开发更简单,往后维护更容易理解,使其自身能更直接的分析,编码,理解复杂的情况和过程,比非模块化编程方法省事。1
术语
Namespace 命名空间
允许开发人员在一个专用的名称下捆绑所有功能代码的容器。
Class 类
定义对象的特征。
Object 对象
类的一个实例。
Property 属性
对象的特征,比如颜色。
Method 方法
对象的能力,比如行走。
Constructor 构造函数
实例化时调用的函数。
Inheritance 继承
一个类可以继承另一个类的特征。
Encapsulation 封装
类定义了对象的特征,方法只定义了方法如何执行。
Abstraction 抽象
结合复杂的继承,方法,属性,一个对象能够模拟现实的模型。
Polymorphism 多态
多意为‘许多’,态意为‘形态’。不同类可以定义相同的方法或属性。更多关于面向对象编程的描述,请参照维基百科的面向对象编程。
原型编程
基于原型的编程不是面向对象编程中体现的风格,且行为重用(在基于类的语言中也称为继承)是通过装饰它作为原型的现有对象的过程实现的。这种模式也被称为弱类化,原型化,或基于实例的编程。
原始的(也是最典型的)基于原型语言的例子是由大卫·安格尔和兰德尔·史密斯开发的。然而,弱类化的编程风格近来变得越来越流行,并已被诸如JavaScript,Cecil,NewtonScript,IO,MOO,REBOL,Kevo,Squeak(使用框架操纵Morphic组件),和其他几种编程语言采用。1
JavaScript面向对象编程
命名空间
命名空间是一个容器,它允许开发人员在一个独特的,特定于应用程序的名称下捆绑所有的功能。在JavaScript中,命名空间只是另一个包含方法,属性,对象的对象。
需要认识到非常重要的一点,与其他面向对象编程语言中的普通对象和命名空间相比,它们在语言层面上没有区别。
创造的JavaScript命名空间背后的想法很简单:一个全局对象被创建,所有的变量,方法和功能成为该对象的属性。使用命名空间也最大程度地减少应用程序的名称冲突的可能性。
我们来创建一个全局变量叫做MYAPP
// 全局命名空间var MYAPP = MYAPP ||{};
在上面的代码示例中,我们首先检查MYAPP是否已经被定义(是否在同一文件中或在另一文件)。如果是的话,那么使用现有的MYAPP全局对象,否则,创建一个名为MYAPP的空对象用来封装方法,函数,变量和对象。
我们也可以创建子命名空间:
// 子命名空间MYAPP.event ={};
下面是用于创建命名空间和添加变量,函数和方法的代码写法:
// 给普通方法和属性创建一个叫做https://www.wendangku.net/doc/351876529.html,monMethod的容器
https://www.wendangku.net/doc/351876529.html,monMethod ={
regExForName:"", // 定义名字的正则验证
regExForPhone:"", // 定义电话的正则验证
validateName:function(name){
// 对名字name做些操作,你可以通过使用“this.regExForname”
// 访问regExForName变量
},
validatePhoneNo:function(phoneNo){
// 对电话号码做操作
}
}
// 对象和方法一起申明MYAPP.event ={
addListener:function(el, type, fn){
// 代码
},
removeListener:function(el, type, fn){
// 代码
},
getEvent:function(e){
// 代码
}
// 还可以添加其他的属性和方法
}
//使用addListner方法的写法:
MYAPP.event.addListener("yourel","type", callback);
标准内置对象
JavaScript有包括在其核心的几个对象,例如,Math,Object,Array和String对象。下面的例子演示了如何使用Math对象使用其随机()方法来获得一个随机数。
console.log(Math.random());
注意:T这里和接下来的例子都假设名为console.log的方法全局有定义。console.log实际上不是JavaScript 自带的。
查看JavaScript 参考:全局对象了解JavaScript 内置对象的列表。
JavaScript 中的每个对象都是Object对象的实例且继承它所有的属性和方法。
自定义对象
类
JavaScript是一种基于原型的语言,它没类的声明语句,比如C+ +或Java中用的。这有时会对习惯使用有类申明语句语言的程序员产生困扰。相反,JavaScript可用方法作类。定义一个类跟定义一个函数一样简单。在下面的例子中,我们定义了一个新类Person。
function Person(){}
// 或
var Person =function(){}
对象(类的实例)
我们使用new obj 创建对象obj的新实例, 将结果(obj 类型)赋值给一个变量方便稍后调用。
在下面的示例中,我们定义了一个名为Person的类,然后我们创建了两个Person的实例
(person1 and person2).
function Person(){}
var person1 =new Person();
var person2 =new Person();
有两种为对象创建实例,请参考Object.create。
构造器
在实例化时构造器被调用(也就是对象实例被创建时)。构造器是对象中的一个方法。在JavaScript,中函数就可以作为构造器使用,因此不需要特别地定义一个构造器方法. 每个声明的函数都可以在实例化后被调用执行
构造器常用于给对象的属性赋值或者为调用函数做准备。在本文的后面描述了类中方法既可以在定义时添加,也可以在使用前添加。
在下面的示例中, Person类实例化时构造器调用一个 alert函数。
function Person(){
alert('Person instantiated');
}
var person1 =new Person();
var person2 =new Person();
属性(对象属性)
属性就是类中包含的变量;每一个对象实例有若干个属性. 为了正确的继承,属性应该被定义在类的原型属性(函数)中。
可以使用关键字this调用类中的属性, this是对当前对象的引用。从外部存取(读/写)其属性的语法
是: InstanceName.Property; 这与C++,Java或者许多其他语言中的语法是一样的(在类中语
法this.Property常用于set和get属性值)
在下面的示例中,我们为定义Person类定义了一个属性firstName并在实例化时赋初值。
function Person(firstName){
this.firstName = firstName;
alert('Person instantiated');
}
var person1 =new Person('Alice');
var person2 =new Person('Bob');// Show the firstName properties of the objects alert('person1 is '+ person1.firstName); // alerts "person1 is Alice"
alert('person2 is '+ person2.firstName); // alerts "person2 is Bob"
方法
方法与属性很相似,不同的是:一个是函数,另一个可以被定义为函数。调用方法很像存取一个属性, 不同的是add ()在方法名后面很可能带着参数. 为定义一个方法, 需要将一个函数赋值给类的prototype属性; 这个赋值给函数的名称就是用来给对象在外部调用它使用的。
在下面的示例中,我们给Person类定义了方法sayHello(),并调用了它.
function Person(firstName){
this.firstName = firstName;
}
Person.prototype.sayHello =function(){
alert("Hello, I'm "+this.firstName);
};
var person1 =new Person("Alice");
var person2 =new Person("Bob");// call the Person sayHello method.
person1.sayHello(); // alerts "Hello, I'm Alice"
person2.sayHello(); // alerts "Hello, I'm Bob"
在JavaScript中方法通常是一个绑定到对象中的普通函数, 这意味着方法可以在其所在context之外被调用。思考下面示例中的代码:
function Person(firstName){
this.firstName = firstName;
}
Person.prototype.sayHello =function(){
alert("Hello, I'm "+this.firstName);
};
var person1 =new Person("Alice");
var person2 =new Person("Bob");
var helloFunction = person1.sayHello;
person1.sayHello();// alerts "Hello, I'm Alice"
person2.sayHello();// alerts "Hello, I'm Bob"
helloFunction();// alerts "Hello, I'm undefined" (or fails // with a TypeError in strict mode)
alert(helloFunction === person1.sayHello); // alerts true
alert(helloFunction === Person.prototype.sayHello); // alerts true
helloFunction.call(person1); // alerts "Hello, I'm Alice"
如上例所示, 所有指向sayHello函数的引用,包括person1, Person.prototype, 和helloFunction等,均引用了相同的函数.
在调用函数的过程中,this的值取决于我们怎么样调用函数. 在通常情况下,我们通过一个表达式
person1.sayHello()来调用函数:即从一个对象的属性中得到所调用的函数。此时this被设置为我们取得函数的对象(即person1)。这就是为什么person1.sayHello()使用了姓名“Alice”而person2.sayHello()使用了姓名“bob”的原因。
然而我们使用不同的调用方法时, this的值也就不同了。当从变量helloFunction()中调用的时候,this 就被设置成了全局对象(在浏览器中即window)。由于该对象(非常可能地) 没有firstName属性, 我们得到的结果便是"Hello, I'm undefined". (这是松散模式下的结果,在严格模式中,结果将不同(此时会产生一个error)。但是为了避免混淆,我们在这里不涉及细节) 。另外,我们可以像上例末尾那样,使用Function#call (或者Function#apply)显式的设置this的值。
更多有关信息请参考Function#call and Function#apply
继承
创建一个或多个类的专门版本类方式称为继承(Javascript只支持单继承)。创建的专门版本的类通常叫做子类,另外的类通常叫做父类。在Javascript中,继承通过赋予子类一个父类的实例并专门化子类来实现。在现代浏览器中你可以使用Object.create实现继承.
JavaScript 并不检测子类的prototype.constructor (见Object.prototype), 所以我们必须手动申明它.
在下面的例子中, 我们定义了Student类作为Person类的子类. 之后我们重定义了sayHello()方法并添加了sayGoodBye() 方法.
// 定义Person构造器
function Person(firstName){
this.firstName = firstName;
}
// 在Person.prototype中加入方法
Person.prototype.walk =function(){
alert("I am walking!");
};
Person.prototype.sayHello =function(){
alert("Hello, I'm "+this.firstName);
};
// 定义Student构造器
function Student(firstName, subject){
// 调用父类构造器, 确保(使用Function#call)"this" 在调用过程中设置正确
Person.call(this, firstName);
// 初始化Student类特有属性
this.subject = subject;
};
// 建立一个由Person.prototype继承而来的Student.prototype对象.
// 注意: 常见的错误是使用 "new Person()"来建立Student.prototype.
// 这样做的错误之处有很多, 最重要的一点是我们在实例化时
// 不能赋予Person类任何的FirstName参数
// 调用Person的正确位置如下,我们从Student中来调用它
Student.prototype = Object.create(Person.prototype); // See note below
// 设置"constructor" 属性指向Student
Student.prototype.constructor = Student;
// 更换"sayHello" 方法
Student.prototype.sayHello =function(){
alert("Hello, I'm "+this.firstName +". I'm studying "+this.subject +".");
};
// 加入"sayGoodBye" 方法
Student.prototype.sayGoodBye =function(){
alert("Goodbye!");
};
// 测试实例:
var student1 =new Student("Janet","Applied Physics");
student1.sayHello(); // "Hello, I'm Janet. I'm studying Applied Physics."
student1.walk(); // "I am walking!"
student1.sayGoodBye(); // "Goodbye!"
// Check that instanceof works correctly
alert(student1 instanceof Person); // true
alert(student1 instanceof Student); // true
对于“Student.prototype = Object.create(Person.prototype);”这一行,在不支持Object.create 方法的老JavaScript引擎中,可以使用一个"polyfill"(又名"shim",查看文章链接),或者使用一个function 来获得相同的返回值,就像下面:
function createObject(proto){
function ctor(){}
ctor.prototype = proto;
return new ctor();
}
// Usage:
Student.prototype =createObject(Person.prototype);
更多相关信息请参考Object.create,连接中还有一个老JavaScript引擎的兼容方案(shim)。
封装
在上一个例子中,Student类虽然不需要知道Person类的walk()方法是如何实现的,但是仍然可以使用这个方法;Student类不需要明确地定义这个方法,除非我们想改变它。这就叫做封装,对于所有继承自父类的方法,只需要在子类中定义那些你想改变的即可。
抽象
抽象是允许模拟工作问题中通用部分的一种机制。这可以通过继承(具体化)或组合来实现。
JavaScript通过继承实现具体化,通过让类的实例是其他对象的属性值来实现组合。
JavaScript Function 类继承自Object类(这是典型的具体化)。Function.prototype的属性是一个Object 实例(这是典型的组合)。
var foo =function(){};
alert( 'foo is a Function: ' + (foo instanceof Function) );
//alerts "foo is a Function: true"
alert( 'foo.prototype is an Object: ' + (foo.prototype instanceof Object) );
// alerts "foo.prototype is an Object: true"
多态
就像所有定义在原型属性内部的方法和属性一样,不同的类可以定义具有相同名称的方法;方法是作用于所在的类中。并且这仅在两个类不是父子关系时成立(继承链中,一个类不是继承自其他类)。
注意
本文中所展示的面向对象编程技术不是唯一的实现方式,在JavaScript中面向对象的实现是非常灵活的。同样的,文中展示的技术没有使用任何语言hacks,它们也没有模仿其他语言的对象理论实现。JavaScript中还有其他一些更加先进的面向对象技术,但这些都超出了本文的介绍范围。
参考
维基百科.“面向对象程序设计”,https://www.wendangku.net/doc/351876529.html,/wiki/面向对象程序设计
Javascript 语言本身也可以进行面向对象的编程,如下是最近几天对javascript面向对象编程的总结。 对象的创建 javascript对象有两种创建方式 1.使用对象初始器: objName = { prop1:value_1, prop2:value_2, ... } 该方法直接创建实例对象,而无需声明。 2.使用构造函数: 如:fuction Engineer(para1,para2){ this.para1 = para1; this.para2 = para2; ... } my Bill = new Engineer("Bill","24"); 该方法需要用new()来创建实例。 为一个object类型添加新的属性: 如:Bill.prototype.sex = "man"; 这样,所有Engineer类型的对象都有属性sex,其value为"man", 而如下语句: Bill.sex = "man"; 则只是为Bill对象本身添加一个属性。 为对象定义一个方法: function draw(){ ... } fuction Engineer(para1,para2){ this.para1 = para1; this.para2 = para2; this.draw = draw; ... } my Bill = new Engineer("Bill","24"); Bill.draw();
也可以使用如下的定义方式: objName = { prop1:value_1, prop2:value_2, draw:function(num){ ... } ... } 引用时用objName.draw(); 删除对象的一个属性: //Creates a new property, myobj, with two properties, a and b. myobj = new Object; myobj.a=5; myobj.b=12; //Removes the a property, leaving myobj with only the b property. delete myobj.a;//删除myobj实例对象的a属性 删除对象的一个方法: delete objName.draw;//删除objNmae实例对象的draw函数 ===================================================================== ======= 在JavaScript中可以使用function关键字来定义一个“类”,如何为类添加成员。在函数内通过this指针引用的变量或者方法都会成为类的成员,例如: function class1(){ var s="abc"; this.p1=s; this.method1=function(){ alert("this is a test method"); } } var obj1=new class1(); 通过new class1()获得对象obj1,对象obj1便自动获得了属性p1和方法
潍坊科技学院 JavaScript课程设计 报告书 设计题目基于javascript的电子商务网站开发 专业班级11软件一 学生姓名江京翔 学号201101080002 指导教师陈凤萍 日期2012.12.24~2012.1.11 成绩
课程设计任务书 院系:软件学院专业:软件技术班级:11软1 学号:201101080002 一、课程设计时间 2012年12月24日至2013年1月11日,共计3周。 二、课程设计内容 使用html+javascript+css 完成以下任务: 1、能够熟练使用css结合html实现网页布局。 2、熟练使用文档对象模型和事件驱动,能够很好的实现web表单的交互式操作。 3、熟练使用javascrip中的对象,实现网页的动态效果。 三、课程设计要求 1. 课程设计质量: ?贯彻事件驱动的程序设计思想,熟练使用javascript中的对象,实现网页特效。 ?网页设计布局合理,色彩搭配合理,网页操作方便。 ?设计过程中充分考虑浏览器兼容等问题,并做适当处理。 ?代码应适当缩进,并给出必要的注释,以增强程序的可读性。 2. 课程设计说明书: 课程结束后,上交课程设计报告书和相关的网页。课程设计报告书的格式和内容参见提供的模板。 四、指导教师和学生签字 指导教师:学生签名:江京翔 五、教师评语:
基于javascript的电子商务网站开发 摘要 JavaScript是开发WEB应用程序不可或缺的一种语言,无论是为web页面增加交互性还是创建整个应用程序,如果没有Javascript,今天的web就不是现在这个样子了。JavaScript是具有正式规范的基于标准语言;然而,正如任何一个web开发人员所告诉你的那样,几乎每个web浏览器对这个规范的解释都不同。 本网站充分的结合了HTML与CSS的结合充分显示了网站的动态效果,是客户与网站能够充分的结合,进行信息的交换信息不断的进行更新。 基于新闻管理网站,国外新闻页面更具有代表性,是网站最标准型之一,通过Javascript 脚本的交互式该页面更好与其他的页面相互结合。 同时通常页面的下载是按照代码的排列顺序,而表格布局代码的排列代表从上向下,从左到右,无法改变。而通过CSS控制,您可以任意改变代码的排列顺序,比如将重要的右边内容先加载出来。 关键字:节假日、日历、Javascript脚本
学习群76650734 深入认识JavaScript中的this指针 this指针是面向对象程序设计中的一项重要概念,它表示当前运行的对象。在实现对象的方法时,可以使用this指针来获得该对象自身的引用。 和其他面向对象的语言不同,JavaScript中的this指针是一个动态的变量,一个方法内的this指针并不是始终指向定义该方法的对象的,在上一节讲函数的apply和call方法时已经有过这样的例子。为了方便理解,再来看下面的例子: 以下是引用片段: <script language="JavaScript" type="text/javascript"> <!-- //创建两个空对象 var obj1=new Object(); var obj2=new Object(); //给两个对象都添加属性p,并分别等于1和2 obj1.p=1; obj2.p=2; //给obj1添加方法,用于显示p的值 obj1.getP=function(){ alert(this.p); //表面上this指针指向的是obj1 } //调用obj1的getP方法 obj1.getP(); //使obj2的getP方法等于obj1的getP方法 obj2.getP=obj1.getP; //调用obj2的getP方法 obj2.getP(); //--> </script> 从代码的执行结果看,分别弹出对话框显示1和2。由此可见,getP函数仅定义了一次,在不同的场合运行,显示了不同的运行结果,这是有this指针的变化所决定的。在obj1的getP方法中,this就指向了obj1对象,而在obj2的getP方法中,this就指向了obj2对象,并通过this指针引用到了两个对象都具有的属性p。 由此可见,JavaScript中的this指针是一个动态变化的变量,它表明了当前运行该函数的对象。由this指针的性质,也可以更好的理解JavaScript中对象的本质:一个对象就是由一个或多个属性(方法)组成的集合。每个集合元素不是仅能属于一个集合,而是可以动态的属于多个集合。这样,一个方法(集合元素)由谁调用,this指针就指向谁。实际上,前
1,用户名不能包含空格,第一个字母不能为数字,长度控制 2,密码和验证码要相同,不能为空,等等,一些很基本的功能,但是确实挺烦人的。 javascript调试起来确实比较麻烦。
JavaScript 能改变 HTML 元素的内容。
转载请注明出处-中国设计秀https://www.wendangku.net/doc/351876529.html, /* -------------- 函数检索-------------- trim函数: trim() lTrim() rTrim() 校验字符串是否为空: checkIsNotEmpty(str) 校验字符串是否为整型: checkIsInteger(str) 校验整型最小值: checkIntegerMinValue(str,val) 校验整型最大值: checkIntegerMaxValue(str,val) 校验整型是否为非负数: isNotNegativeInteger(str) 校验字符串是否为浮点型: checkIsDouble(str) 校验浮点型最小值: checkDoubleMinValue(str,val) 校验浮点型最大值: checkDoubleMaxValue(str,val) 校验浮点型是否为非负数: isNotNegativeDouble(str) 校验字符串是否为日期型: checkIsValidDate(str) 校验两个日期的先后: checkDateEarlier(strStart,strEnd) 校验字符串是否为email型: checkEmail(str) 校验字符串是否为中文: checkIsChinese(str) 计算字符串的长度,一个汉字两个字符: realLength() 校验字符串是否符合自定义正则表达式: checkMask(str,pat) 得到文件的后缀名: getFilePostfix(oFile) -------------- 函数检索-------------- */ /** * added by LxcJie 2004.6.25 * 去除多余空格函数 * trim:去除两边空格lTrim:去除左空格rTrim: 去除右空格 * 用法: * var str = " hello "; * str = str.trim(); */ String.prototype.trim = function() { $)/g,return this.replace(/(^[\s]*)|([\s]* ""); } String.prototype.lTrim = function() { return this.replace(/(^[\s]*)/g, ""); } String.prototype.rTrim = function() { $)/g,return this.replace(/([\s]* ""); } /********************************** Empty **************************************/ /** *校验字符串是否为空 *返回值: *如果不为空,定义校验通过,返回true *如果为空,校验不通过,返回false 参考提示信息:输入域不能为空! */