【JavaScript】使用面向对象的技术创建高级 Web 应用程序
本文讨论:
|
本文使用了以下技术: JavaScript |

- var userObject = new Object();
- userObject.lastLoginTime = new Date();
- alert(userObject.lastLoginTime);
的功能与下面的代码段完全相同:
- var userObject = {}; // equivalent to new Object()
- userObject[“lastLoginTime”] = new Date();
- alert(userObject[“lastLoginTime”]);
我们还可以直接在 userObject 的定义中定义 lastLoginTime 属性,如下所示:
- var userObject = { “lastLoginTime”: new Date() };
- alert(userObject.lastLoginTime);
- function func(x) {
- alert(x);
- }
- func(“blah”);
这就是通常在 JavaScript 中定义函数的方法。但是,还可以按以下方法定义该函数,您在此创建匿名函数对象,并将它赋给变量 func
- var func = function(x) {
- alert(x);
- };
- func(“blah2”);
甚至也可以像下面这样,使用 Function 构造函数:
- var func = new Function(“x”, “alert(x);”);
- func(“blah3”);
- function sayHi(x) {
- alert(“Hi, “ + x + “!”);
- }
- sayHi.text = “Hello World!”;
- sayHi[“text2”] = “Hello World... again.”;
- alert(sayHi[“text”]); // displays “Hello World!”
- alert(sayHi.text2); // displays “Hello World... again.”

- // assign an anonymous function to a variable
- var greet = function(x) {
- alert(“Hello, “ + x);
- };
- greet(“MSDN readers”);
- // passing a function as an argument to another
- function square(x) {
- return x * x;
- }
- function operateOn(num, func) {
- return func(num);
- }
- // displays 256
- alert(operateOn(16, square));
- // functions as return values
- function makeIncrementer() {
- return function(x) { return x + 1; };
- }
- var inc = makeIncrementer();
- // displays 8
- alert(inc(7));
- // functions stored as array elements
- var arr = [];
- arr[0] = function(x) { return x * x; };
- arr[1] = arr[0](2);
- arr[2] = arr[0](arr[1]);
- arr[3] = arr[0](arr[2]);
- // displays 256
- alert(arr[3]);
- // functions as object properties
- var obj = { “toString” : function() { return “This is an object.”; } };
- // calls obj.toString()
- alert(obj);
- var myDog = {
- “name” : “Spot”,
- “bark” : function() { alert(“Woof!”); },
- “displayFullName” : function() {
- alert(this.name + “ The Alpha Dog”);
- },
- “chaseMrPostman” : function() {
- // implementation beyond the scope of this article
- }
- };
- myDog.displayFullName();
- myDog.bark(); // Woof!

- function displayQuote() {
- // the value of “this” will change; depends on
- // which object it is called through
- alert(this.memorableQuote);
- }
- var williamShakespeare = {
- “memorableQuote”: “It is a wise father that knows his own child.”,
- “sayIt” : displayQuote
- };
- var markTwain = {
- “memorableQuote”: “Golf is a good walk spoiled.”,
- “sayIt” : displayQuote
- };
- var oscarWilde = {
- “memorableQuote”: “True friends stab you in the front.”
- // we can call the function displayQuote
- // as a method of oscarWilde without assigning it
- // as oscarWilde’s method.
- //”sayIt” : displayQuote
- };
- williamShakespeare.sayIt(); // true, true
- markTwain.sayIt(); // he didn’t know where to play golf
- // watch this, each function has a method call()
- // that allows the function to be called as a
- // method of the object passed to call() as an
- // argument.
- // this line below is equivalent to assigning
- // displayQuote to sayIt, and calling oscarWilde.sayIt().
- displayQuote.call(oscarWilde); // ouch!
- alert(“NaN is NaN: “ + isNaN(NaN));
- function x() {
- this.isNaN = function() {
- return “not anymore!”;
- };
- }
- // alert!!! trampling the Global object!!!
- x();
- alert(“NaN is NaN: “ + isNaN(NaN));
- Dog spot = new Dog();
将返回一个对象,该对象是 Dog 类的实例。但在 JavaScript 中,本来就没有类。与访问类最近似的方法是定义构造函数,如下所示:
- function DogConstructor(name) {
- this.name = name;
- this.respondTo = function(name) {
- if(this.name == name) {
- alert(“Woof”);
- }
- };
- }
- var spot = new DogConstructor(“Spot”);
- spot.respondTo(“Rover”); // nope
- spot.respondTo(“Spot”); // yeah!
那么,结果会怎样呢?暂时忽略 DogConstructor 函数定义,看一看这一行:
- var spot = new DogConstructor(“Spot”);
- // create an empty object
- var spot = {};
- // call the function as a method of the empty object
- DogConstructor.call(spot, “Spot”);
正如在 DogConstructor 主体中看到的那样,调用此函数将初始化对象,在调用期间关键字“this”将引用此对象。这样,就可以为对象创建模板!只要需要创建类似的对象,就可以与构造函数一起调用“new”,返回的结果将是一个完全初始化的对象。这与类非常相似,不是吗?实际上,在 JavaScript 中构造函数的名称通常就是所模拟的类的名称,因此在上面的示例中,可以直接命名构造函数 Dog:
- // Think of this as class Dog
- function Dog(name) {
- // instance variable
- this.name = name;
- // instance method? Hmmm...
- this.respondTo = function(name) {
- if(this.name == name) {
- alert(“Woof”);
- }
- };
- }
- var spot = new Dog(“Spot”);
- function respondTo() {
- // respondTo definition
- }
- function Dog(name) {
- this.name = name;
- // attached this function as a method of the object
- this.respondTo = respondTo;
- }
- var buddy = new Dog(“Buddy“);
buddy 所引用的对象将从它的原型继承属性和方法,尽管仅从这一行可能无法明确判断原型来自哪里。对象 buddy 的原型来自构造函数(在这里是函数 Dog)的属性。
.gif)

- var spot = new Dog(“Spot”);
- // Dog.prototype is the prototype of spot
- alert(Dog.prototype.isPrototypeOf(spot));
- // spot inherits the constructor property
- // from Dog.prototype
- alert(spot.constructor == Dog.prototype.constructor);
- alert(spot.constructor == Dog);
- // But constructor property doesn’t belong
- // to spot. The line below displays “false”
- alert(spot.hasOwnProperty(“constructor”));
- // The constructor property belongs to Dog.prototype
- // The line below displays “true”
- alert(Dog.prototype.hasOwnProperty(“constructor”));
.gif)
- Dog.prototype = new Object();
.gif)
- 继承原型对象的对象上可以立即呈现对原型所做的更改,即使是在创建这些对象之后。
- 如果在对象中定义了属性/方法 X,则该对象的原型中将隐藏同名的属性/方法。例如,通过在 Dog.prototype 中定义 toString 方法,可以改写 Object.prototype 的 toString 方法。
- 更改只沿一个方向传递,即从原型到它的派生对象,但不能沿相反方向传递。

- function GreatDane() { }
- var rover = new GreatDane();
- var spot = new GreatDane();
- GreatDane.prototype.getBreed = function() {
- return “Great Dane”;
- };
- // Works, even though at this point
- // rover and spot are already created.
- alert(rover.getBreed());
- // this hides getBreed() in GreatDane.prototype
- spot.getBreed = function() {
- return “Little Great Dane”;
- };
- alert(spot.getBreed());
- // but of course, the change to getBreed
- // doesn’t propagate back to GreatDane.prototype
- // and other objects inheriting from it,
- // it only happens in the spot object
- alert(rover.getBreed());
- function DateTime() { }
- // set static method now()
- DateTime.now = function() {
- return new Date();
- };
- alert(DateTime.now());

- function filter(pred, arr) {
- var len = arr.length;
- var filtered = []; // shorter version of new Array();
- // iterate through every element in the array...
- for(var i = 0; i < len; i++) {
- var val = arr[i];
- // if the element satisfies the predicate let it through
- if(pred(val)) {
- filtered.push(val);
- }
- }
- return filtered;
- }
- var someRandomNumbers = [12, 32, 1, 3, 2, 2, 234, 236, 632,7, 8];
- var numbersGreaterThan100 = filter(
- function(x) { return (x > 100) ? true : false; },
- someRandomNumbers);
- // displays 234, 236, 632
- alert(numbersGreaterThan100);
- var greaterThan300 = filter(
- function(x) { return (x > 300) ? true : false; },
- someRandomNumbers);
- function makeGreaterThanPredicate(lowerBound) {
- return function(numberToCheck) {
- return (numberToCheck > lowerBound) ? true : false;
- };
- }
这样,您就可以编写以下代码:
- var greaterThan10 = makeGreaterThanPredicate(10);
- var greaterThan100 = makeGreaterThanPredicate(100);
- alert(filter(greaterThan10, someRandomNumbers));
- alert(filter(greaterThan100, someRandomNumbers));
- function Person(name, age) {
- this.getName = function() { return name; };
- this.setName = function(newName) { name = newName; };
- this.getAge = function() { return age; };
- this.setAge = function(newAge) { age = newAge; };
- }
- var ray = new Person(“Ray”, 31);
- alert(ray.getName());
- alert(ray.getAge());
- ray.setName(“Younger Ray”);
- // Instant rejuvenation!
- ray.setAge(22);
- alert(ray.getName() + “ is now “ + ray.getAge() +
- “ years old.”);
- function Person(name, age) {
- var occupation;
- this.getOccupation = function() { return occupation; };
- this.setOccupation = function(newOcc) { occupation =
- newOcc; };
- // accessors for name and age
- }
注意,这些私有成员与我们期望从 C# 中产生的私有成员略有不同。在 C# 中,类的公用方法可以访问它的私有成员。但在 JavaScript 中,只能通过在其闭包内拥有这些私有成员的方法来访问私有成员(由于这些方法不同于普通的公用方法,它们通常被称为特权方法)。因此,在 Person 的公用方法中,仍然必须通过私有成员的特权访问器方法才能访问私有成员:
- Person.prototype.somePublicMethod = function() {
- // doesn’t work!
- // alert(this.name);
- // this one below works
- alert(this.getName());
- };
.gif)
- // class Pet
- function Pet(name) {
- this.getName = function() { return name; };
- this.setName = function(newName) { name = newName; };
- }
- Pet.prototype.toString = function() {
- return “This pet’s name is: “ + this.getName();
- };
- // end of class Pet
- var parrotty = new Pet(“Parrotty the Parrot”);
- alert(parrotty);

- // class Dog : Pet
- // public Dog(string name, string breed)
- function Dog(name, breed) {
- // think Dog : base(name)
- Pet.call(this, name);
- this.getBreed = function() { return breed; };
- // Breed doesn’t change, obviously! It’s read only.
- // this.setBreed = function(newBreed) { name = newName; };
- }
- // this makes Dog.prototype inherits
- // from Pet.prototype
- Dog.prototype = new Pet();
- // remember that Pet.prototype.constructor
- // points to Pet. We want our Dog instances’
- // constructor to point to Dog.
- Dog.prototype.constructor = Dog;
- // Now we override Pet.prototype.toString
- Dog.prototype.toString = function() {
- return “This dog’s name is: “ + this.getName() +
- “, and its breed is: “ + this.getBreed();
- };
- // end of class Dog
- var dog = new Dog(“Buddy”, “Great Dane”);
- // test the new toString()
- alert(dog);
- // Testing instanceof (similar to the is operator)
- // (dog is Dog)? yes
- alert(dog instanceof Dog);
- // (dog is Pet)? yes
- alert(dog instanceof Pet);
- // (dog is Object)? yes
- alert(dog instanceof Object);
- var MSDNMagNS = {};
- MSDNMagNS.Pet = function(name) { // code here };
- MSDNMagNS.Pet.prototype.toString = function() { // code };
- var pet = new MSDNMagNS.Pet(“Yammer”);
- var MSDNMagNS = {};
- // nested namespace “Examples”
- MSDNMagNS.Examples = {};
- MSDNMagNS.Examples.Pet = function(name) { // code };
- MSDNMagNS.Examples.Pet.prototype.toString = function() { // code };
- var pet = new MSDNMagNS.Examples.Pet(“Yammer”);
可以想象,键入这些冗长的嵌套命名空间会让人很累。 幸运的是,库用户可以很容易地为命名空间指定更短的别名:
- // MSDNMagNS.Examples and Pet definition...
- // think “using Eg = MSDNMagNS.Examples;”
- var Eg = MSDNMagNS.Examples;
- var pet = new Eg.Pet(“Yammer”);
- alert(pet);
- function object(o) {
- function F() {}
- F.prototype = o;
- return new F();
- }
然后,由于 JavaScript 中的对象是可延展的,因此可以方便地在创建对象之后,根据需要用新字段和新方法增大对象。
【JavaScript】使用面向对象的技术创建高级 Web 应用程序的更多相关文章
- 使用面向对象技术创建高级 Web 应用程序
作者: 出处: 使用面向对象技术创建高级 Web 应用程序 来源:开源中国社区 作者:oschina 最近,我面试了一位具有5年Web应用开发经验的软件开发人员.她有4年半的JavaScript编程经 ...
- javascript面向对象创建高级 Web 应用程序
目录 JavaScript 对象是词典 JavaScript 函数是最棒的 构造函数而不是类 原型 静态属性和方法 闭包 模拟私有属性 从类继承 模拟命名空间 应当这样编写 JavaScript ...
- 用 Java 技术创建 RESTful Web (服务 JAX-RS:一种更为简单、可移植性更好的替代方式)
作者: Dustin Amrhein, 软件工程师, IBM Nick Gallardo, 软件工程师, IBM 出处: http://www.ibm.com/developerworks/cn/we ...
- Jmeter(五) - 从入门到精通 - 创建网络计划实战和创建高级Web测试计划(详解教程)
1.简介 上一篇中宏哥已经将其的理论知识介绍了一下,这一篇宏哥就带着大家一步一步的把上一篇介绍的理论知识实践一下,然后再说一下如何创建高级web测试计划. 2.网络计划实战 通过上一篇的学习,宏哥将其 ...
- jQuery Mobile 是创建移动 web 应用程序的框架。
jQuery Mobile jQuery Mobile 是创建移动 web 应用程序的框架. jQuery Mobile 适用于所有流行的智能手机和平板电脑. jQuery Mobile 使用 HTM ...
- 002.Create a web API with ASP.NET Core MVC and Visual Studio for Windows -- 【在windows上用vs与asp.net core mvc 创建一个 web api 程序】
Create a web API with ASP.NET Core MVC and Visual Studio for Windows 在windows上用vs与asp.net core mvc 创 ...
- IDEA 2017.3 新版本中创建 JSF Web 应用程序缺少 web.xml 的解决办法
IDEA 2017.3 新版本中默认创建一个 Web 应用程序很可能不会自动创建 web.xml 文件.虽然说从 JavaEE 6.0 开始 Servlet 3.0 规范中就新增了一些注解可以免去传统 ...
- IIS首次发布VS2012创建的web应用程序时注册.net4.0
最近用VS2012创建的web应用程序,.net环境设置成了4.0,在用IIS发布的时候发现需要注册下.net4.0才能配置应用程序. 首先确保配置的电脑上已经安装了.net4,找到.net4所在文件 ...
- 用 Java 技术创建 RESTful Web 服务
JAX-RS:一种更为简单.可移植性更好的替代方式 JAX-RS (JSR-311) 是一种 Java™ API,可使 Java Restful 服务的开发变得迅速而轻松.这个 API 提供了一种基于 ...
随机推荐
- javascript --- jQuery --- Deferred对象
javascript --- jQuery --- Deferred对象 javascript的函数式编程是多么引人入胜,jQuery使代码尽可能的精简,intelligent! defer - 必应 ...
- Intellij IDEA开发第一个Android应用
1.创建一个项目 File——>New Project——>.......——>Finish 2.创建模块 3.MyActivity.java package com.example ...
- ListView真的蛮好用
老规矩,今晚学过的,明天,依靠回忆写出来. 打个卡,占个版面.
- Mac OS10.9 下python开发环境(eclipse)以及自然语言包NLTK的安装与注意
折腾了大半天,终于把mbp上python自然语言开发环境搭建好了. 第一步,安装JDK1.7 for mac MacOS10.9是自带python2.7.5的,够用,具体的可以打开终端输入python ...
- LeetCode(1) -Two Sum
题目要求很简单,给你一个数组(例如,nums = [2,7,11,15])和一个target(target = 9),找到数组里两个数相加后能得到target的这两个数的index.在本例中,返回的应 ...
- HDU1227:Fast Food
题目链接:Fast Food 题意:一条直线上有n个饭店,问建造k个原料厂(仍旧在商店位置)得到的最小距离 分析:见代码 //一条直线上有n个饭店,问建造k个原料厂(仍旧在商店位置)得到的最小距离 / ...
- openstack network
- Dagger学习笔记
@Inject 提供依赖的构造函数,或者需要依赖的成员变量 @Module 提供依赖,实例化的地方( 使用module实例化,方便测试的时候替换成其他对象,而这也是和构造方法注入的区别,如果用构造方法 ...
- Unity3D Script KeynoteII
[Unity3D Script KeynoteII] 1.使用代码操作Particle. //粒子对象 GameObject particle = null; //粒子X轴方向速度 float vel ...
- visualC/C++连接MySql数据库
vs连接数据库其实就是将mysql数据库.h头文件接口.lib链接文件和dll执行文件加入到项目中.下面是配置如何加入. 转于http://www.cnblogs.com/justinzhang/ar ...