`
thecloud
  • 浏览: 890246 次
文章分类
社区版块
存档分类
最新评论

js真正了解面向对象

 
阅读更多

js的几种数据类型:number, string, boolean, object, undefined 五种数据类型

js的常见内置对象类:Date, Array, Math, Number, Boolean, String, RegExp, Function, Object

js的两个类型判断方法:typeofinstanceof

typeof:一元运算符,eg: typeof(1) 将返回number.它返回的是顶级的几种数据类型

instanceof:二元运算符 eg: myObj instanceOf MyObj 返回的是一个boolean值。应用数据类型包括自己定义的类。判断变量是不是此类的实例,它和typeof都只能应用于js内置及自定义的数据类型,不包括DOM对像,例如window,document.

我们平台声明的数据类型也就是number,string,boolean,object undefined及其object的子类型。声明的类型也就拥有所属类型的本性方法,常用的有string类型的substring,indexOf,length方法。主要的是要掌握function 定义出的类型。

我们利用function 可以声明一个函数,也可以做为创建类的关键字。当作为函数关键词使用时,没有什么好说的。但是当做为创建类的关键词时,我们需要知道js的一些特征东西。(使用function做为函数关键词还是类关键词,因自己的目的而定)。当我们使用函数关键词时js面向对象的特征基本用不到,所以就不多说了。现在就说一下function做为类关键词,我们需要常用的一些js特征,以适应我们的面向对象的

三大特性:封装、继承、多态

封装性:

类型于其它的面向对象语言一样,用大括号来限定变量的作用域。这样就有了局部变量。如果声明在最外面,那就是全局变量。那么现在还少的是什么?就是成员变量。幸好js支持闭包特性,例如:

function Person(){

var name="张三";

var sex ="";

return {

"getName":function(){

return name;

},

"getSex":function(){

return sex;

},

"setName":function(_name){

name=_name;

},

"setSex":function(_sex){

sex = _sex;

},

"aliasName":name;

};

}

var person = new Person();

alert(person.name);//undefined

alert(person.getName());//张三

person.setName("李国");

alert(person.getName());//李国

这样就有了私有成员变量。公有成员变量,就是可以直接访问的,像aliasName属性。这是很基础的。我们都知道,在像java语言里,有this关键字

来代表对像本身。而恰恰js也有这个this.但是这个this和其它面向对向语言的this是有区别的,这里先不说区别在哪。

我们先利用this实现一下类:

function Person(){

var name="王五";

var sex ="";

this.aliasName="123";

this.setName=function( _name){

name=_name;

};

this.getName=function(){

return name;

};

this.setSex=function( _sex){

sex=_sex;

};

this.getSex=function(){

return sex;

}

}

//测试

var person = new Person();

alert(person.name);//undefined

alert(person.getName());//张三

person.setName("李国");

alert(person.getName());//李国

person.aliasName="nnd";

alert(person.aliasName);

下面我们来看一下 person = new Person()执行过程:person=new Object()-->Person类型的this绑定到this-->person有什么,person就是有什么。

我们想一下,这里也是利用的闭包特性。因person的相关方法,引用了外部变量,当person不被回收时,外部变量也不会被回收,但是只能通过

person的方法才能访问的到。被包住了。但是,这一种方式,要比第一个实现起来要灵活多了。这里就要说一下,this为什么和其它语言的this

有区别,想一下,js function 即可以以函数用也可以做类用,当一个function 含有this,但被直接调用了,像Person().这时js就会把相关的方法

属性给了windowthis没有被指向一个对象,会默认指向window),执行过程:this-->window.这样的话,就有一定的凶险性了,因为这个类里的所有东西都是全局的了。比如:

Person();

alert(window.getName());

到现在为止,我们把对像的封闭性创建对象算是说完了。目前,我们看它像是一个类的,但还有一点就是每new Person(),不但属性产生副本,方法也会产生副本

属性产生副本,这个是应该的,但是方法产生副本就没有毕要了,对吧?js function 类型的数据(切记),它提供了prototype这个属性,即原型。这么写Person:

function Person(){

var name="王五";

var sex ="";

this.aliasName="123";

this.self = Person;

this.self.prototype.setName=function( _name){

name=_name;

};

this.self.prototype.getName=function(){

return name;

};

this.self.prototype.setSex=function( _sex){

sex=_sex;

};

this.self.prototype.getSex=function(){

return sex;

}

}

创建的所有Person就会有一个方法副本了。为了证明正确性,可以分别:

var person = new Person();

var person1 = new Person();

alert(person.getName===person1.getName);

看一下效果就可以了。原型为什么能提供这个效果?

下面,就说一下原型prototype及其相关应用吧

原型是Js中非常重要的概念,每个函数(Js里面函数也是对象)都有一个叫prototype即原型)的属性,不过在一般情况下它的值都是null,但它他有一项非常重要的功能就是所以实例都会共享它里面的属性和方法(这就是Js里面实现继承的基础)

还是举例吧:

function auth(){

alert(this.name);

//此处一定要加this关键字

}

auth.prototype.name='shiran';//这句可以放到对象定义之后,但必须在被调用之前

new auth();//这里一定要用new

这里需要注意三点:

第一、name前面一定要加关键字this,不然的话就会得不到任何,因为如果你不加this,他就不会到原型中查找(加上this是属性它会在上下文查找,看看前面我讲的变量的查找那一章)

第二、如果实例对象在对象中找不到属性或方法就会到对象的prototype中去查找,所以如果想在函数被调用的时候调用对象的属性或方法,就必须把调用语句放在prototype定义之后(在这里,就是new auth必须放到auth.prototype.name之后)!

第三、只有实例对象才会到原型中查找,因为对于原对象来说prototype是他的属性必需通过prototype才能访问(在这里,要用new auth()生成一个实例,而不能用auth)!

原型对于对象的实例来说是共享的,这既给程序带来方便,同时也会让人感到迷惑,出现好多让人意想不到的结果!

auth=function(){ };

auth.prototype={

name:[],

getNameLen:function(){

alert(this.name.length);

},

setName:function(n){

this.name.push(n);

}

}

var lwx=new auth();

lwx.setName('lwx');

lwx.getNameLen();

var shiran=new auth();

shiran.setName('shiran');

shiran.getNameLen();

第二次弹出的对话框显示name的长度已经是2,为什么呢?这就是原型的共享引起的,因为变量lwxshiran都是auth对象,而且name属性是在auth对象的原型中定义的,所以lwxshiran实例之间共享name这个属性!!可是这并不是我们想要看到的结果,因为我们希望,每个实例之间是相互隔离的。

这里我们可以把name属性从原型中去掉,放在auth对象的定义中即:

auth=function(){

this.name=[];//切记,一定要在前面加上this关键词

};

这样一来,每个auth的实例都会拥有自己的name属性!所以推荐大家,以后在定义对象的时候:把属性放到定义里,而把对象的方法放到原型里!

有了原型,也其实就有了类方法和类属性。完整的类有了,封装成员也有了。以后要说一下继承啦!模拟继承,我们需要熟悉jsfunction 的两个函数,它们是callapply.下面,我们介绍一下它们。知道它们了,继承也就差不多了,写信demo就可以了。

JavaScript中有一个callapply方法,其作用基本相同,但也有略微的区别。先来看看JS手册中对call的解释:

call 方法

调用一个对象的一个方法,以另一个对象替换当前对象。

call([thisObj[,arg1[, arg2[, [,.argN]]]]])

参数

thisObj

可选项。将被用作当前对象的对象。

arg1, arg2, , argN

可选项。将被传递方法参数序列。

说明

call 方法可以用来代替另一个对象调用一个方法。call 方法可将一个函数的对象上下文从初始的上下文改变为由thisObj 指定的新对象。如果没有提供 thisObj 参数,那么 Global 对象被用作 thisObj说明白一点其实就是更改对象的内部指针,即改变对象的this指向的内容。这在面向对象的js编程过程中有时是很有用的。

引用网上一个代码段,运行后自然就明白其道理。

Js代码

<input type="text" id="myText" value="input text">

<script>

function Obj(){this.value="对象!";}

var value="global 变量";

function Fun1(){alert(this.value);}

window.Fun1(); //global 变量

Fun1.call(window); //global 变量

Fun1.call(document.getElementById('myText')); //input text

Fun1.call(new Obj()); //对象! </script>

<input type="text" id="myText" value="input text">

<script>

function Obj(){this.value="对象!";}

var value="global 变量";

function Fun1(){alert(this.value);}

window.Fun1(); //global 变量

Fun1.call(window); //global 变量

Fun1.call(document.getElementById('myText')); //input text

Fun1.call(new Obj()); //对象!

</script>

call函数和apply方法的第一个参数都是要传入给当前对象的对象,及函数内部的this。后面的参数都是传递给当前对象的参数。

运行如下代码:

Js代码

<script>

var func=new function(){this.a="func"}

var myfunc=function(x){

var a="myfunc";

alert(this.a);

alert(x);

}

myfunc.call(func,"var");

</script>

<script>

var func=new function(){this.a="func"}

var myfunc=function(x){

var a="myfunc";

alert(this.a);

alert(x);

}

myfunc.call(func,"var");

</script> 可见分别弹出了funcvar。到这里就对call的每个参数的意义有所了解了。

对于applycall两者在作用上是相同的,但两者在参数上有区别的。对于第一个参数意义都一样,但对第二个参数:apply传入的是一个参数数组,也就是将多个参数组合成为一个数组传入,而call则作为call的参数传入(从第二个参数开始)。 func.call(func1,var1,var2,var3)对应的apply写法为:func.apply(func1,[var1,var2,var3])

同时使用apply的好处是可以直接将当前函数的arguments对象作为apply的第二个参数传入。我们用call,写一个继承的例子,像:

function Animal(){

this.name=“gg”;

this.getName=function(){alert(this.name)};

};

function Person(){

Animal.call(this);//构造父类

this.aliasName="";

}

function init(){

var p = new Person();

p.getName();

}

再写一个apply函数的:

function Animal(name,sex){

this.name="gg";

this.getName=function(){alert(this.name+name+sex)};

};

function Person(name,sex){

Animal.apply(this,[name,sex]);//构造父类,参数是数组

this.aliasName="";

}

function init(){

var p = new Person("wsk",'man');

p.getName();

}

到这里,继承有了。

多态性:

多态性,对于js来讲更简单了,因为,它是一个弱类型的语言,可以对一个变量付任何类型的变量。虽然不完全符合,但也能凑合用了。

js面向对象编程,还有相当长的考验,希望能给刚入门的朋友提供一个帮助。

分享到:
评论

相关推荐

    js真正了解面向对象.pdf

    js真正了解面向对象.pdf

    写给大家看的面向对象编程书(第3版).[美]Matt Weisfeld(带详细书签).pdf

    书中结合代码示例生动透彻地讲述了面向对象思想的精髓,让读者真正学会以对象方式进行思考。此外,本书还讨论了各种与面向对象概念密切相关的应用主题,包括XML、UML建模语言、持久存储、分布式计算和客户/服务器...

    workshop-maze-vr:向儿童展示如何进行目标编程并了解他们在虚拟现实中的迷宫外观的研讨会

    Devoxx4Kids工作坊-Maze VR 专为devoxx4kids研讨会设计,旨在向孩子们展示如何进行... 真正的javascript语言“更近” 它使用英语编程命令 主要提供开放式办公室格式和pdf 可以在presentation / de / workshop 1下

    XML轻松学习手册--XML肯定是未来的发展趋势,不论是网页设计师还是网络程序员,都应该及时学习和了解

    面向对象的思想方法已经非常流行了,在编程语言(例如java,js)中,都运用面向对象的编程思想。在XML中,就是要将网页也作为一个对象来操作和控制,我们可以建立自己的对象和模板。与对象进行交流,如何命令对象,...

    JAVA上百实例源码以及开源项目源代码

     Java生成密钥、保存密钥的实例源码,通过本源码可以了解到Java如何产生单钥加密的密钥(myKey)、产生双钥的密钥对(keyPair)、如何保存公钥的字节数组、保存私钥到文件privateKey.dat、如何用Java对象序列化保存私钥...

    Ajax详解.rar

    1.16 JavaScript 对象标注 150 1.17 比较序列化技术 153 第 14部分:面向 Java 开发人员的 Ajax 结合 Direct Web Remoting 使用 Ajax 154 1.1 DWR 是什么? 155 1.2 关于示例 155 1.3 实现目录 156 1.4 测试...

    互联网程序员都每天刷题嘛-dave-cs:戴夫的计算机科学课程

    面向对象设计 数据库 线性代数 Linux、zsh、VM C Python Java Javascript/HTML/CSS Node.js + Express MySQL/SQLite 基本正则表达式 移动就绪 Web 应用程序设计 如何收集需求并编写设计文档 单元测试和集成测试 序列...

    JAVA上百实例源码以及开源项目

     Java生成密钥、保存密钥的实例源码,通过本源码可以了解到Java如何产生单钥加密的密钥(myKey)、产生双钥的密钥对(keyPair)、如何保存公钥的字节数组、保存私钥到文件privateKey.dat、如何用Java对象序列化保存私钥...

    java8集合源码-jarvis_data_eng_noshin:jarvis_data_eng_noshin

    这帮助我深入了解了面向对象编程的概念。 在空闲时间,我喜欢阅读、听音乐、与朋友和家人一起出去玩,以及观光。 我的职业目标是能够用我获得的知识和经验解决现实世界的问题。 技能 精通: Java、Bash、SQL、Agile/...

    庖丁解牛纵向切入ASP.NET 3.5控件和组件开发技术.pdf

    16.2 ajax library对客户端面向对象功能支持564 16.2.1 命名空间及type和function类565 16.2.2 接口类型568 16.2.3 类类型以及面向对象继承特征569 16.2.4 枚举类型570 16.2.5 反射功能570 16.3 ajax library...

    Y分钟学习X种语言

    OCaml语言很像Miranda,是基于ML编程语言,在其中增加了面向对象结构。F#语言是基 于OCaml语言的,甚至还有它的一个兼容模式。OCaml在业内仍然有使用,例如Jane Street Capital 和 XenSource。 Web 语言 我们已经...

    AJAX 源码范例

    06/6.7.2.html 在JavaScript实现抽象类范例 06/6.8.3.html 给事件处理程序传递参数范例 06/6.8.4.html 使自定义事件支持多绑定范例 06/6.9/ 实例:使用面向对象思想处理cookie &lt;br&gt;第7章...

    ASP EXCEL导入SQL

    通过这些平台服务就可以把即时的状态消息(通过邮件、短信或者其它的IM工具)推送给用户,让用户真正了解到业务的即时与实时的状态信息。  而通常的应用服务是静态的,只有当用户登录时,才会进行相应的业务状态的...

    Android程序设计基础

     阅读本书唯一的前提条件,是具备对Java编程或类似面向对象语言(比如说C#)的基本理解,不需要拥有为移动设备开发软件的经验。实际上,如果你确实有这方面的经验,反倒应该忘记它们。Android是如此与众不同,因此...

    java源码包---java 源码 大量 实例

     Java生成密钥、保存密钥的实例源码,通过本源码可以了解到Java如何产生单钥加密的密钥(myKey)、产生双钥的密钥对(keyPair)、如何保存公钥的字节数组、保存私钥到文件privateKey.dat、如何用Java对象序列化保存私钥...

    java源码包2

     Java生成密钥、保存密钥的实例源码,通过本源码可以了解到Java如何产生单钥加密的密钥(myKey)、产生双钥的密钥对(keyPair)、如何保存公钥的字节数组、保存私钥到文件privateKey.dat、如何用Java对象序列化保存私钥...

    java源码包3

     Java生成密钥、保存密钥的实例源码,通过本源码可以了解到Java如何产生单钥加密的密钥(myKey)、产生双钥的密钥对(keyPair)、如何保存公钥的字节数组、保存私钥到文件privateKey.dat、如何用Java对象序列化保存私钥...

    java源码包4

     Java生成密钥、保存密钥的实例源码,通过本源码可以了解到Java如何产生单钥加密的密钥(myKey)、产生双钥的密钥对(keyPair)、如何保存公钥的字节数组、保存私钥到文件privateKey.dat、如何用Java对象序列化保存私钥...

    成百上千个Java 源码DEMO 4(1-4是独立压缩包)

    密钥 Java生成密钥、保存密钥的实例源码,通过本源码可以了解到Java如何产生单钥加密的密钥(myKey)、产生双钥的密钥对(keyPair)、如何保存公钥的字节数组、保存私钥到文件privateKey.dat、如何用Java对象序列化保存...

Global site tag (gtag.js) - Google Analytics