文档章节

面向对象的程序设计(一)

前端小虾
 前端小虾
发布于 2016/06/29 16:19
字数 2335
阅读 7
收藏 0
点赞 0
评论 0

js的面向对象不像其他语言的面向对象,js中没有类的概念。ECMA-262将对象定义为:无需属性的集合,其属性可以包括基本值、对象或函数。严格来说对象就是一组没有特定顺序的值。

1、理解对象

var person=new Object();

person.name="wsh";

person.age=28;

person.job="software engineer";

person.sayName=function(){alert(this.name);}

早期常用的创建对象的模式。几年后自变量方式创建对象成为首选。

var person={

    name:"wsh",

    age:28,

    job:"software engineer",

    sayName:function(){

       alert(this.name);   

    }

};

1.1属性类型

       a.数据属性

        b.访问器属性

1.2定义多个属性

1.3读取属性的特性

 

 

2 创建对象

2.1 工厂模式

function createPerson(name,age,job)

{

    var o=new Object()l;

    o.name=name;

    o.age=age;

    o.job=job;

    o.sayName=function(){alert(this.name);}

    return o;

}

var person1=new createPerson("wsh",28,"程序员");

var person2=new createPerson("Tom",30,"服务员");

工厂模式对然解决了创建多个相似对象的问题,但没有解决对象识别的问题(即怎样知道一个对象的类型)。随着js的发展有个模式出现了。

2.2 构造函数模式

    ECMAScript中的构造函数可以用来创建特定类型的对象。

    function Person(name,age,job)

    {

        this.name=name;

        this.nage=age;

        this.job=job;

        this.sayName=function(){aleft(this.name);}

    }

var person1=new createPerson("wsh",28,"程序员");

var person2=new createPerson("Tom",30,"服务员")

在这个例子中,Person函数取代了createPerson()函数。他们代码区别

    A 没有显式的创建对象

    B将属性和方法赋值给了this

    C没有return 返回语句

此外还应注意到Person()中P大写,按照惯例,构造函数始终都因该第一个字母大写。而非构造函数应该以一个小写字母开头。这个做法借鉴其他编程语言,主要是为了区别ECMAScript的其他函数;因为构造函数本身也是函数,只不过可以用了创建对象而已。

要创建Person的实例,必须使用new操作符。以这种方式创建对象都有一个constructor属性,该属性指向Person,如下代码所示:

alert(person1.constructor==Person)//ture

alert(person2.constructor==Person)//ture

这个例子中我们创建的所有对象既是object的实例,同时也是Person的实例,可以通过instanceof操作符可以得到验证。

alert(person1 instanceof  Object)//true

alert(person1 instanceof  Person)//true

alert(person2 instanceof  Object)//true

alert(person2 instanceof  Person)//true

创建自定义的构造函数意味着将来可以将它的实例作为一种特定的类型;而这正是构造函数模式胜过工厂模式的地方。

1 将构造函数作为函数

构造函数和其他函数为i的区别就在于调用他们的方式不同。不过,构造函数也是函数,不存在定义构造函数的特殊语法。任何函数只要通过mew操作符来调用他就可以作为构造函数;而任何函数如果不通过new操作符来调用,那它跟普通函数也不会有什么两样。

//当作构造函数来调用

var person=new Person("wsh",30,"程序员");

person.sayname();

//作为普通函数调用

Person("wsh",30,"程序员");//添加到window

window.syaName();//wsh

//在另一个作用域中调用

var o=new Object();

Person.call(o,"wsh",28,"程序员");

o.sayName();//wsh

2 构造函数的问题

构造函数模式的问题是,每个方法都要在每个实例上重新重建一遍。当前例子person1和person2中都定义了sayName()方法,但那两个方法不是同一个Function实例。

创建通样任务的Function实例确实没有必要,况且有this对象在,根本不用在执行代码前就把函数绑到到特定对象上面。通过把函数sayName()转移到构造函数内容可以解决这个问题。代码如下:

function Person(name,age,job){

    this.name=name;

    this.age=age;

    this.job=job;

    this.sayName=sayName;

}

function sayName(){

    alert(this.name);

}

这样做确实解决了相同函数重新创建的问题,但是新的问题出现了,函数定义为了全局,没有封装行可言。好在这些问题可以通过原型模式来解决。

2.3 原型模式

prototype:调用构造函数创建的实例对象的原型对象。使用原型对象的好处是所有实例共享它所包含的属性和方法。换句话说,不必在构造函数中定义实例的信息,而是将这些信息直接添加到原型对象中。

function Person(){}

Person.prototye.name="wsh";

Person.prototype.age=28;

Person.prototype.job="程序员";

Person.prorotype.sayName=function(){alert(this.name);};

var person1=new Person();

person1.sayName();//wsh

var person2=new Person();

person1.sayName();//wsh

 

    1 理解原型对象

    无论什么时候,只要创建一个新函数,就会根据一组特定的规则为该函数创建一个prototype属性,这个属性指向函数的原型对象。在默认情况下,所有原型对象都会自动获得一个constructor属性,这个属性包含一个指向prototype属性所在函数的指针。Person.prototype.constructor指向的是Person.

      创建了自定义的构造函数后,其原型对象默认只会取得constructor属性;其他方法都继承Object。当调用构造函数创建一个新实例后,该实例内部将包含一个指针,指向构造函数的原型对象。要明确真正重要的一点就是,这个链接存在与实例和构造函数原型对象之间,而不是存在与实例和构造函数之间。

 

       

虽然你person1,person2不包含属性和方法,但却可以调用person1.sayName()这是通过对象查找属性的过程来实现的。

虽然在所有的实现中都无法访问到[[Prototype]],但可以通过isPrototype()方法来确定对象之间是否存在这种关系。

ECMAScript5定义了新的方法,Object.getPrototypOf()返回对象的原型。

alert(Object.getPrototypeOf(person1)==Person.prototype)//true

alert(Person.getPrototypeOf(person1).name)//wsh;

每当代码读取到某个对象的属性时,都会指向一次搜索,目标是具有给定名字的属性。首先搜索对象实例本身,如果实例中有次属性,则返回该属性,如果没找到则继续搜索原型对象。

当为实例添加一个新属性时,这个属性就会屏蔽原型对象中的同名属性。使用delete操作符则可以完全删除实例属性,恢复与原型对象的连接。

 

function Person(){}

Person.prototye.name="wsh";

Person.prototype.age=28;

Person.prototype.job="程序员";

Person.prorotype.sayName=function(){alert(this.name);};

 

var person1=new Person();

var person2=new Person();

 

person1.name='lc';

alert(person1.name)//lc

alert(person2.name);//wsh

 

delete person1.name

alert(person1.name);//wsh

 

person1.sayName();//wsh

person2.sayName();//wsh

 

使用hasOwnProperty()方法可以检测一个属性是存在于实例中还是原型中。给定属性在实例中时返回true.

2 原型与in操作符

    有2中方式使用in操作符:单独使用 for-in循环使用。

    alert("name" in person1);//true

    havPrototypeProperty()属性存在原型中返回true.

 

    要取的对象上所有可以枚举的实例属性,可使用ECMAScript5中的Object.keys(),此方法接收一个对象作为参数,返回一个包含所有可枚举属性的字符串数组。

  var keys=Object.keys(Person.prototype);

  alert(keys);//name,age,job,sayName

3 更简单的原型语法

    前面例子中每添加一个属性或方法就要重新敲一遍Person.prototype,为了减少不必要的输入

,也为了从视觉上更好的封装原型,更常见的做法是用一个包含所有属性好方法的的对象自变量来重写挣个原型对象。代码:

function Person(){}

Person.prototye={

name:"wsh",

age:28,

job:"程序员",

sayName: function(){alert(this.name);}

}

此块简写代码和上面代码最终结果相同,但有个例外:constructor属性不再指向Person.本来没创建一个函数就同时会创建它的prototype对象,这个对象也会自动活动xonstructor属性,而这里使用的语法完全重写了默认的prototype对象,因此contrutctou对象也就变成了新对象的constructors属性(即object构造函数),不再指向Person.尽管instanceof操作符还能正常返回正确的结果,但是通过contructor已经无法确定对象的类型了。

var friend=new Person();

alert(friend instanceof Object)//true

alert(friend instanceof Person)//true

alert(friend.constructor == Person)//false

alert(friend.constructor==Object)//true

如果constructor的值真的很重要,可以设置回适当的值。代码:

function Person(){};

Person.prototye={

constructor:Person,

name:"wsh",

age:28,

job:"程序员",

sayName: function(){alert(this.name);}

}

注意,以这种方式重设constructor属性会导致它的[[Enumerable]]为true.默认情况下,元素的constructor属性是不可枚举的。

4  原型的动态性

function Person(){}

var friend = new Person();

Person.prototye={

constructor:Person,

name:"wsh",

age:28,

job:"程序员",

sayName: function(){alert(this.name);}

}

friend.sayName();//error

在这个例子中,我们先创建了Person的一个实例,然后又重写了其原型对象。然后在调用friend.sayName()时发生了错误,因为friend指向的原型中不包含以该名字命名的属性,friend引用的仍然是最初的原型。下图展示了这个过程的内幕。

 

5 原生对象的原型

 

6 原型对象的问题

 

原型模式最大问题是由其共享的本性所导致的。原型中包含引用类型值的时候尤为明显。

 

 

© 著作权归作者所有

共有 人打赏支持
前端小虾
粉丝 0
博文 43
码字总数 21084
作品 0
东城
软件工程——面向对象设计

说到面向对象我们都很熟悉,刚刚结束的vb就是面向对象的编程语言。对象是指类的实例,面向对象程序设计是一种程序设计范型,也是一种程序开发的方法。它把对象作为程序的基本单元,将程序和数...

邵鸿鑫 ⋅ 2013/12/07 ⋅ 0

谈谈你对面向对象的理解

Question:请你谈一下面向对象? Answer: 面向对象是相对于面向过程而言的。面向过程语言是一种基于功能分析的、以算法为中心的程序设计方法;而面向对象是一种基于结构分析的、以数据为中心...

DevShaw ⋅ 2016/01/12 ⋅ 0

1.2 面向对象语言的发展历史

Simula 面向对象技术最早是在编程语言Simula中提出的。1967年5月20日,在挪威奥斯陆郊外的小镇莉沙布举行的IFIP TC-2 工作会议上,挪威科学家Ole-Johan Dahl和Kristen Nygaard正式发布了Sim...

无寄语 ⋅ 2016/08/13 ⋅ 0

清华大学视频课件:面向对象程序设计(C++)(自主模式)

清华大学视频课件:面向对象程序设计(C++)(自主模式) 课程简介 C++是从C语言发展演变而来的一种面向对象的程序设计语言。面向对象的程序设计方法将数据及对数据的操作方法封装在一起,作...

dragonscroll ⋅ 2017/11/16 ⋅ 0

要解释什么是面向对象的程序设计,如何来进行说明?

并不是一个程序员新人。我在回过头来复习以前的知识的时候,看到面向对象程序设计时,很多编程语言都涉及到这个,但是似乎很少有将其作为一个主体来进行介绍的。 所以我现在有几个疑问。假如...

oolong ⋅ 2016/01/27 ⋅ 6

1.1 程序设计思想的发展

面向机器 最早的程序设计都是采用机器语言来编写的,直接使用二进制码来表示机器能够识别和执行的指令和数据。简单来说,就是直接编写0和1的序列来代表程序语言。例如:使用0000 代表 加载(...

无寄语 ⋅ 2016/08/13 ⋅ 0

给大家分享一些Java基础学习资料,后续会不断的更新~

每一个成功者都有一个开始,人之所以能,是因为相信能。 Java程序设计是一个庞大的、发展迅速的领域。自从Java发布以来,作为一种面向对象的程序设计语言,不论在Internet程序设计中,还是在...

Fuxiaoxiao ⋅ 2015/12/19 ⋅ 2

有必要澄清两个基本概念--算法和过程的关系以及关于程序设计方法论的一些看法

概述 前些天,在一个关于面向对象和面向过程的话题, 我的一句评论"算法说白了就是过程"引起了辩论.于是我有了写这篇随笔的想法: 一位园友善意地说这个评论太业余了.我没有为业余二字生气,因为...

mikelij ⋅ 2008/11/30 ⋅ 0

2017年10大主流编程语言最新排行榜出炉

2017-12-25 祈澈姑娘 前言 据美国科技公司Gizmodo报道,截至2014年9月24日,全世界采用IT操作系统的设备数量已经达到10亿台,IT推动中国移动互联网进入高速发展期,成为所有行业中发展前景最...

祈澈姑娘 ⋅ 2017/12/25 ⋅ 0

Python-面向对象编程

面向对象编程——Object Oriented Programming,简称OOP,是一种程序设计思想。OOP把对象作为程序的基本单元,一个对象包含了数据和操作数据的函数。 面向过程的程序设计把计算机程序视为一系...

铁扇公主1 ⋅ 2017/03/27 ⋅ 0

没有更多内容

加载失败,请刷新页面

加载更多

下一页

收集自网络的wordpress 分页导航的代码教程(全网最全版)

wordpress 分页导航是用来切换文章的一个功能,添加了 wordpress 分页导航后,用户即可自由到达指定的页面数浏览分类文章,而这样的一个很简单功能却有很多朋友在用插件:WP-PageNavi,插件的...

Rhymo-Wu ⋅ 40分钟前 ⋅ 0

微服务 WildFly Swarm 入门

Hello World 就像前面章节中的其他框架一样,我们希望添加一些基本的 Hello-world 功能,然后在其上逐步添加更多的功能。让我们从在我们的项目中创建一个 HolaResources 开始。您可以使用您的...

woshixin ⋅ 47分钟前 ⋅ 0

Maven的安装和Eclipse的配置

1. 下载Maven 下载地址 2. 解压压缩包,放到自己习惯的硬盘中 此处我将其放到了 D:\Tools 目录下。 3. 配置环境变量 右键此电脑 -> 属性 -> 高级系统设置 -> 环境变量。 在系统变量中新建,变...

影狼 ⋅ 54分钟前 ⋅ 0

python pip使用国内镜像的方法

国内源 清华:https://pypi.tuna.tsinghua.edu.cn/simple 阿里云:http://mirrors.aliyun.com/pypi/simple/ 中国科技大学 https://pypi.mirrors.ustc.edu.cn/simple/ 华中理工大学:http://......

良言 ⋅ 55分钟前 ⋅ 0

对于url变化的spa应该如何使用微信jssdk

使用vue单页面碰上微信jssdk config验证失败的坑。第一次成功 之后切换页面全部失败,找到了解决方法,第一次验证成功后保存验证信息 切换页面时验证信息直接拿来用,加一个wx.error() 失败时...

孙冠峰 ⋅ 59分钟前 ⋅ 0

Spring Cloud Gateway 一般集成

SCF发布,带来很多新东西,不过少了点教程,打开方式又和以前的不一样,比如这个SCG,压根就没有入门指导,所以这里写一个,以备后用。 一、集成 pom.xml <dependency> <groupI...

kut ⋅ 今天 ⋅ 0

建造模式

《JAVA与模式》之建造模式

Cobbage ⋅ 今天 ⋅ 0

WePY框架开发的小程序如何在微信web开发者工具中运行起来

一、首先需要安装node.js,安装步骤如下: 首先下载安装包 https://nodejs.org/en/download/ 点击下载相应的zip版本 然后将文件夹解压到任意目录 比如我这里解压到了:C:\Program Files\node...

Helios51 ⋅ 今天 ⋅ 0

使用EnumSet 代替位域(32)

1、位域(Bit field):使用or 运算将几个常量合并到一个集合中 位操作,可以有效地执行 AND 、OR 这样的位操作 但是 位域比int 常量枚举缺点更多 2、java.util 包里面的EnumSet 类是有效的替...

职业搬砖20年 ⋅ 今天 ⋅ 0

没有更多内容

加载失败,请刷新页面

加载更多

下一页

返回顶部
顶部