`
webcode
  • 浏览: 6104087 次
  • 性别: Icon_minigender_1
  • 来自: 上海
文章分类
社区版块
存档分类
最新评论

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

    在JavaScript中,理解面向对象编程(OOP)的概念是至关重要的,因为它是实现复杂逻辑和模块化代码的基础。以下是一些关于JavaScript面向对象的知识点: 1. 数据类型: JavaScript具有五种基本数据类型:number、...

    JavaScript的面向对象

    JavaScript的面向对象是一种重要的编程范式,它在JavaScript中通过构造函数、原型链以及类(ES6引入)来实现。这篇博文将深入探讨JavaScript中的面向对象特性,包括类的概念、对象的创建、继承机制以及封装。 首先...

    JavaScript 面向对象基础简单示例

    了解JavaScript的面向对象基础对于编写复杂的、可维护的代码至关重要。你可以通过阅读更多的JavaScript面向对象教程,学习错误调试技巧,以及数据结构和算法来深化你的理解。通过实践和不断探索,你将能够熟练掌握...

    面向对象方法在HTML编码中的应用

    首先,文章强调了面向对象设计的核心特性——封装性、继承性和多态性。封装性确保组件作为独立单元,用户只需要知道如何使用,而无需了解内部工作细节。在JavaScript中,这可以通过创建对象和对象模式实现。高内聚性...

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

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

    js面向对象之静态方法和静态属性实例分析

    在JavaScript中,面向对象编程涉及类的概念,尽管JavaScript并没有真正的类,但它提供了构造函数来模拟类的行为。在面向对象的世界里,静态方法和静态属性是类的成员,它们不归属于类的任何实例,而是直接属于类本身...

    创建js日志对象代替alert函数进行调试的例子

    首先,我们需要了解面向对象编程的基本概念。在JavaScript中,面向对象主要通过构造函数、原型和实例化来实现。我们将创建一个名为`Log`的构造函数,它能够存储日志信息而不立即显示,只在需要时显示。 ```...

    You Don't Know JS(高清带目录中文版)1-3

    《You Don't Know JS》是一套著名的JavaScript编程书籍,由Kyle Simpson撰写,旨在深入解析JavaScript的各个核心概念,帮助开发者真正理解这门语言的精髓。本资源提供了高清中文版的第1-3部分,分别是“3this与对象...

    javascript对象的创建和访问_.docx

    尽管JavaScript没有真正的类,但ES6引入了Class语法,提供了更接近传统面向对象语言的写法,其实质仍然是基于原型的: ```javascript class Person { constructor(name, age) { this.name = name; this.age = ...

    javascript学习文档

    其次,"js面向对象(pdf)"文件可能包含关于JavaScript面向对象编程的内容。在JavaScript中,面向对象编程主要体现在构造函数、原型链、对象的继承等方面。学习这部分内容,你需要理解如何创建和使用构造函数,如何...

    JavaScript讲义完整版.docx

    - JavaScript是一种面向对象、解释型的编程语言,它基于对象、事件驱动,并具有相对的安全性。它无需特定语言环境,只需在支持JavaScript的浏览器上运行。 - 主要用途包括:验证发送到服务器的数据、增加Web交互性...

    js面向对象编程之如何实现方法重载

    在JavaScript面向对象编程中,方法重载是一个常见的需求,但由于JavaScript语言的特性,它并不直接支持传统意义上的方法重载,即同一个类中多个同名函数根据参数不同而执行不同的逻辑。不过,我们可以通过一些技巧来...

    JavaScript 实例应用

    JavaScript支持基于原型的面向对象编程,包括构造函数、原型链和实例化。此外,ES6引入了类的概念,使得JavaScript的面向对象编程更接近传统语言。 7. **函数式编程** 虽然JavaScript并非纯函数式语言,但它包含...

    js网页特效demo

    6. **面向对象编程**:JS支持面向对象编程,可以通过构造函数和原型链创建对象,实现继承和多态。这对于构建可复用的代码模块和复杂的应用程序非常有用。 7. **插件和库**:有许多成熟的JS库和框架,如jQuery、...

    超实用Javascript代码

    JavaScript支持类(ES6引入)和原型链的面向对象编程。理解构造函数、`this`关键字、继承和封装的概念对编写复杂应用至关重要。 7. **Promise和异步编程** 为了处理异步操作,JavaScript引入了Promise,解决了回...

    prototype.js源码解度

    Prototype.js 是一个广泛使用的 JavaScript 库,它的设计目标是扩展JavaScript的基本功能,提供更丰富的面向对象编程体验。通过阅读和理解Prototype.js的源码,可以深入了解JavaScript语言的特性和一些高级技巧,...

    JavaScript学习之三 — JavaScript实现继承的7种方式

    在JavaScript中,面向对象编程是实现复杂功能和代码复用的关键。继承是面向对象的核心特性之一,它允许一个对象(子类)获取另一个对象(父类)的属性和方法。本篇文章将深入探讨JavaScript实现继承的七种常见方式,...

    js基本功.doc

    - **对象**:JavaScript的对象是键值对的集合,可以用来模拟面向对象编程的特性,如属性和方法。 **3. JavaScript的位置** JavaScript代码可以在以下几个位置书写: - 内联方式:直接在HTML标签内用`&lt;script&gt;`...

    21天精通JavaScript PPT

    7. **面向对象编程**:JavaScript虽然不是纯面向对象的语言,但支持构造函数、原型链和类等概念,理解这些可以帮助你更好地组织代码和实现复用。 8. **错误处理**:了解如何使用try...catch语句进行错误处理,以及...

Global site tag (gtag.js) - Google Analytics