我的编程空间,编程开发者的网络收藏夹
学习永远不晚

JavaScript面向对象的支持怎么实现

短信预约 -IT技能 免费直播动态提醒
省份

北京

  • 北京
  • 上海
  • 天津
  • 重庆
  • 河北
  • 山东
  • 辽宁
  • 黑龙江
  • 吉林
  • 甘肃
  • 青海
  • 河南
  • 江苏
  • 湖北
  • 湖南
  • 江西
  • 浙江
  • 广东
  • 云南
  • 福建
  • 海南
  • 山西
  • 四川
  • 陕西
  • 贵州
  • 安徽
  • 广西
  • 内蒙
  • 西藏
  • 新疆
  • 宁夏
  • 兵团
手机号立即预约

请填写图片验证码后获取短信验证码

看不清楚,换张图片

免费获取短信验证码

JavaScript面向对象的支持怎么实现

本篇内容介绍了“JavaScript面向对象的支持怎么实现”的有关知识,在实际案例的操作过程中,不少人都会遇到这样的困境,接下来就让小编带领大家学习一下如何处理这些情况吧!希望大家仔细阅读,能够学有所成!

在JavaScript中,我们需要通过一个函数来声明自己的object类型:
//---------------------------------------------------------
// JavaScript中对象的类型声明的形式代码
// (以后的文档中,“对象名”通常用MyObject来替代)
//---------------------------------------------------------
function 对象名(参数表) {
 this.属性 = 初始值;

 this.方法 = function(方法参数表) {
   // 方法实现代码
 }
}

然后,我们可以通过这样的代码来创建这个对象类型的一个实例:
//---------------------------------------------------------
// 创建实例的形式代码
// (以后的文档中,“实例变量名”通常用obj来替代)
//---------------------------------------------------------
var 实例变量名 = new 对象名(参数表);

接下来我们来看“对象”在JavaScript中的一些具体实现和奇怪特性。

1). 函数在JavaScript的面向对象机制中的五重身份
------
“对象名”??如MyObject()??这个函数充当了以下语言角色:
 (1) 普通函数
 (2) 类型声明
 (3) 类型的实现
 (4) 类引用
 (5) 对象的构造函数

一些程序员(例如Delphi程序员)习惯于类型声明与实现分开。例如在delphi中,Interface节用于声明类型或者变量,而implementation节用于书写类型的实现代码,或者一些用于执行的函数、代码流程。

但在JavaScript中,类型的声明与实现是混在一起的。一个对象的类型(类)通过函数来声明,this.xxxx表明了该对象可具有的属性或者方法。

这个函数的同时也是“类引用”。在JavaScript,如果你需要识别一个对象的具体型别,你需要执有一个“类引用”。??当然,也就是这个函数的名字。instanceof 运算符就用于识别实例的类型,我们来看一下它的应用:
//---------------------------------------------------------
// JavaScript中对象的类型识别
//   语法:  对象实例 instanceof 类引用
//---------------------------------------------------------
function MyObject() {
 this.data = 'test data';
}

// 这里MyObject()作为构造函数使用
var obj = new MyObject();
var arr = new Array();

// 这里MyObject作为类引用使用
document.writeln(obj instanceof MyObject);
document.writeln(arr instanceof MyObject);

2). 反射机制在JavaScript中的实现
------
 JavaScript中通过for..in语法来实现了反射机制。但是JavaScript中并不明确区分“属性”与“方法”,以及“事件”。因此,对属性的类型考查在JS中是个问题。下面的代码简单示例for..in的使用与属性识别:
//---------------------------------------------------------
// JavaScript中for..in的使用和属性识别
//---------------------------------------------------------
var _r_event = _r_event = /^[Oo]n.*/;
var colorSetting = {
 method: 'red',
 event: 'blue',
 property: ''
}

var obj2 = {
 a_method : function() {},
 a_property: 1,
 onclick: undefined
}

function propertyKind(obj, p) {
 return  (_r_event.test(p) && (obj[p]==undefined || typeof(obj[p])=='function')) ? 'event'
   : (typeof(obj[p])=='function') ? 'method'
   : 'property';
}

var objectArr = ['window', 'obj2'];

for (var i=0; i<objectArr.length; i++) {
document.writeln('

for ', objectArr[i], '


');

 var obj = eval(objectArr[i]);
 for (var p in obj) {
   var kind = propertyKind(obj, p);
   document.writeln('obj.', p, ' is a ', kind.fontcolor(colorSetting[kind]), ': ', obj[p], '
');
 }

 document.writeln('

');
}

一个常常被开发者忽略的事实是:JavaScript本身是没有事件(Event)系统的。通常我们在JavaScript用到的onclick等事件,其实是IE的DOM模型提供的。从更内核的角度上讲:IE通过COM的接口属性公布了一组事件接口给DOM。

有两个原因,使得在JS中不能很好的识别“一个属性是不是事件”:
 - COM接口中本身只有方法,属性与事件,都是通过一组get/set方法来公布的。
 - JavaScript中,本身并没有独立的“事件”机制。

因此我们看到event的识别方法,是检测属性名是否是以'on'字符串开头(以'On'开头的是Qomo的约定)。接下来,由于DOM对象中的事件是可以不指定处理函数的,这种情况下事件句柄为null值(Qomo采用相同的约定);在另外的一些情况下,用户可能象obj2这样,定义一个值为 undefined的事件。因此“事件”的判定条件被处理成一个复杂的表达式:   ("属性以on/On开头" && ("值为null/undefined" || "类型为function"))

另外,从上面的这段代码的运行结果来看。对DOM对象使用for..in,是不能列举出对象方法来的。

最后说明一点。事实上,在很多语言的实现中,“事件”都不是“面向对象”的语言特性,而是由具体的编程模型来提供的。例如Delphi中的事件驱动机制,是由Win32操作系统中的窗口消息机制来提供,或者由用户代码在Component/Class中主动调用事件处理函数来实现。

“事件”是一个“如何驱动编程模型”的机制/问题,而不是语言本身的问题。然而以PME(property/method/event)为框架的OOP概念,已经深入人心,所以当编程语言或系统表现出这些特性来的时候,就已经没人关心“event究竟是谁实现”的了。

3). this与with关键字的使用
------
在JavaScript的对象系统中,this关键字用在两种地方:
  - 在构造器函数中,指代新创建的对象实例
  - 在对象的方法被调用时,指代调用该方法的对象实例

如果一个函数被作为普通函数(而不是对象方法)调用,那么在函数中的this关键字将指向window对象。与此相同的,如果this关键字不在任何函数中,那么他也指向window对象。

由于在JavaScript中不明确区分函数与方法。因此有些代码看起来很奇怪:
//---------------------------------------------------------
// 函数的几种可能调用形式
//---------------------------------------------------------
function foo() {
 // 下面的this指代调用该方法的对象实例
 if (this===window) {
   document.write('call a function.', '
');
 }
 else {
   document.write('call a method, by object: ', this.name, '
');
 }
}

function MyObject(name) {
 // 下面的this指代new关键字新创建实例
 this.name = name;
 this.foo = foo;
}

var obj1 = new MyObject('obj1');
var obj2 = new MyObject('obj2');

// 测试1: 作为函数调用
foo();

// 测试2: 作为对象方法的调用
obj1.foo();
obj2.foo();

// 测试3: 将函数作为“指定对象的”方法调用
foo.call(obj1);
foo.apply(obj2);

在上面的代码里,obj1/obj2对foo()的调用是很普通的调用方法。??也就是在构造器上,将一个函数指定为对象的方法。

而测试3中的call()与apply()就比较特殊。

在这个测试中,foo()仍然作为普通函数来调用,只是JavaScript的语言特性允许在call()/apply()时,传入一个对象实例来指定foo()的上下文环境中所出现的this关键字的引用。??需要注意的是,此时的foo()仍旧是一个普通函数调用,而不是对象方法调用。

与this“指示调用该方法的对象实例”有些类同的,with()语法也用于限定“在一段代码片段中默认使用对象实例”。??如果不使用with()语法,那么这段代码将受到更外层with()语句的影响;如果没有更外层的with(),那么这段代码的“默认使用的对象实例”将是window。

然而需要注意的是this与with关键字不是互为影响的。如下面的代码:
//---------------------------------------------------------
// 测试: this与with关键字不是互为影响的
//---------------------------------------------------------
function test() {
 with (obj2) {
   this.value = 8;
 }
}
var obj2 = new Object();
obj2.value = 10;

test();
document.writeln('obj2.value: ', obj2.value, '
');
document.writeln('window.value: ', window.value, '
');

你不能指望这样的代码在调用结束后,会使obj2.value属性置值为8。这几行代码的结果是:window对象多了一个value属性,并且值为8。

with(obj){...}这个语法,只能限定对obj的既有属性的读取,而不能主动的声明它。一旦with()里的对象没有指定的属性,或者with()限定了一个不是对象的数据,那么结果会产生一个异常。

4). 使用in关键字的运算
------
除了用for..in来反射对象的成员信息之外,JavaScript中也允许直接用in关键字去检测对象是否有指定名字的属性。

in关键字经常被提及的原因并不是它检测属性是否存在的能力,因此在早期的代码中,很多可喜欢用“if (!obj.propName) {}” 这样的方式来检测propName是否是有效的属性。??很多时候,检测有效性比检测“是否存有该属性”更有实用性。因此这种情况下,in只是一个可选的、官方的方案。

in关键字的重要应用是高速字符串检索。尤其是在只需要判定“字符串是否存在”的情况下。例如10万个字符串,如果存储在数组中,那么检索效率将会极差。
//---------------------------------------------------------
// 使用对象来检索
//---------------------------------------------------------
function arrayToObject(arr) {
 for (var obj=new Object(), i=0, imax=arr.length; i<imax; i++) {
obj[arr[i]]=null;
 }
 return obj;
}

var
 arr = ['abc', 'def', 'ghi']; // more and more...
 obj = arrayToObject(arr);

function valueInArray(v) {
 for (var i=0, imax=arr.length; i<imax; i++) {
if (arr[i]==v) return true;
 }

 return false;
}

function valueInObject(v) {
 return v in obj;
}

这种使用关键字in的方法,也存在一些限制。例如只能查找字符串,而数组元素可以是任意值。另外,arrayToObject()也存在一些开销,这使得它不适合于频繁变动的查找集。最后,(我想你可能已经注意到了)使用对象来查找的时候并不能准确定位到查找数据,而数组中可以指向结果的下标。

5). 使用instanceof关键字的运算
------
在JavaScript中提供了instanceof关键字来检测实例的类型。这在前面讨论它的“五重身份”时已经讲过。但instanceof的问题是,它总是列举整个原型链以检测类型(关于原型继承的原理在“构造与析构”小节讲述),如:
//---------------------------------------------------------
// instanceof使用中的问题
//---------------------------------------------------------
function MyObject() {
 // ...
}

function MyObject2() {
 // ...
}
MyObject2.prototype = new MyObject();

obj1 = new MyObject();
obj2 = new MyObject2();

document.writeln(obj1 instanceof MyObject, '
');
document.writeln(obj2 instanceof MyObject, '
');

我们看到,obj1与obj2都是MyObject的实例,但他们是不同的构造函数产生的。??注意,这在面向对象理论中正确的:因为obj2是MyObject的子类实例,因此它具有与obj1相同的特性。在应用中这是obj2的多态性的体现之一。

但是,即便如此,我们也必须面临这样的问题:如何知道obj2与obj1是否是相同类型的实例呢???也就是说,连构造器都相同?

instanceof关键字不提供这样的机制。一个提供实现这种检测的能力的,是Object.constructor属性。??但请先记住,它的使用远比你想象的要难。

好的,问题先到这里。constructor属性已经涉及到“构造与析构”的问题,这个我们后面再讲。“原型继承”、“构造与析构”是JavaScript的OOP中的主要问题、核心问题,以及“致命问题”。

6). null与undefined
------
在JavaScript中,null与undefined曾一度使我迷惑。下面的文字,有利于
你更清晰的认知它(或者让你更迷惑):
  - null是关键字;undefined是Global对象的一个属性。
  - null是对象(空对象, 没有任何属性和方法);undefined是undefined类
    型的值。试试下面的代码:
      document.writeln(typeof null);
      document.writeln(typeof undefined);
  - 对象模型中,所有的对象都是Object或其子类的实例,但null对象例外:
      document.writeln(null instanceof Object);
  - null“等值(==)”于undefined,但不“全等值(===)”于undefined:
      document.writeln(null == undefined);
      document.writeln(null == undefined);
  - 运算时null与undefined都可以被类型转换为false,但不等值于false:
      document.writeln(!null, !undefined);
      document.writeln(null==false);
      document.writeln(undefined==false);
[@more@]

“JavaScript面向对象的支持怎么实现”的内容就介绍到这里了,感谢大家的阅读。如果想了解更多行业相关的知识可以关注编程网网站,小编将为大家输出更多高质量的实用文章!

免责声明:

① 本站未注明“稿件来源”的信息均来自网络整理。其文字、图片和音视频稿件的所属权归原作者所有。本站收集整理出于非商业性的教育和科研之目的,并不意味着本站赞同其观点或证实其内容的真实性。仅作为临时的测试数据,供内部测试之用。本站并未授权任何人以任何方式主动获取本站任何信息。

② 本站未注明“稿件来源”的临时测试数据将在测试完成后最终做删除处理。有问题或投稿请发送至: 邮箱/279061341@qq.com QQ/279061341

JavaScript面向对象的支持怎么实现

下载Word文档到电脑,方便收藏和打印~

下载Word文档

猜你喜欢

JavaScript面向对象的支持怎么实现

本篇内容介绍了“JavaScript面向对象的支持怎么实现”的有关知识,在实际案例的操作过程中,不少人都会遇到这样的困境,接下来就让小编带领大家学习一下如何处理这些情况吧!希望大家仔细阅读,能够学有所成!在JavaScript中,我们需要通
2023-06-03

JavaScript面向对象怎么实现贪吃蛇游戏

本篇内容介绍了“JavaScript面向对象怎么实现贪吃蛇游戏”的有关知识,在实际案例的操作过程中,不少人都会遇到这样的困境,接下来就让小编带领大家学习一下如何处理这些情况吧!希望大家仔细阅读,能够学有所成!1 工具对象(Tools.js)
2023-06-30

JavaScript面向对象编程实现模拟

面向对象编程(ObjectOrientedProgramming)将现实世界中的复杂关系抽象成一个个对象,通过对象之间的分工合作对现实世界进行模拟
2022-11-13

JavaScript面向对象中的封装和继承怎么实现

这篇“JavaScript面向对象中的封装和继承怎么实现”文章的知识点大部分人都不太理解,所以小编给大家总结了以下内容,内容详细,步骤清晰,具有一定的借鉴价值,希望大家阅读完这篇文章能有所收获,下面我们一起来看看这篇“JavaScript面
2023-06-29

Go中怎么实现面向对象

这篇文章主要为大家展示了“Go中怎么实现面向对象”,内容简而易懂,条理清晰,希望能够帮助大家解决疑惑,下面让小编带领大家一起研究并学习一下“Go中怎么实现面向对象”这篇文章吧。在大家初识 Go 语言时,总会拿其他语言的基本特性来类比 Go
2023-06-15

​javascript的面向对象是什么

这篇文章主要介绍“javascript的面向对象是什么”,在日常操作中,相信很多人在javascript的面向对象是什么问题上存在疑惑,小编查阅了各式资料,整理出简单好用的操作方法,希望对大家解答”javascript的面向对象是什么”的疑
2023-06-05

python面向对象中类怎么实现

这篇文章主要介绍python面向对象中类怎么实现,文中介绍的非常详细,具有一定的参考价值,感兴趣的小伙伴们一定要看完!Python的优点有哪些1、简单易用,与C/C++、Java、C# 等传统语言相比,Python对代码格式的要求没有那么严
2023-06-14

java中怎么实现面向对象编程

这篇文章给大家介绍java中怎么实现面向对象编程,内容非常详细,感兴趣的小伙伴们可以参考借鉴,希望对大家能有所帮助。1:允许将子类的引用付给父类的对象,但子类中的那些不是从父类继承来的成员将不再可见。例:Bus bus=new Bus();
2023-06-17

Rust实现面向对象的方法

这篇文章主要介绍了Rust实现面向对象的方法,Rust 并不是面向对象的语言,但是面向对象的功能都可以通过自身的特点来实现,本文通过示例代码给大家详细讲解,需要的朋友可以参考下
2022-11-13

Java面向对象编程的多态怎么实现

本文小编为大家详细介绍“Java面向对象编程的多态怎么实现”,内容详细,步骤清晰,细节处理妥当,希望这篇“Java面向对象编程的多态怎么实现”文章能帮助大家解决疑惑,下面跟着小编的思路慢慢深入,一起来学习新知识吧。Java面向对象编程之多态
2023-06-26

Python面向对象的类和对象怎么使用

这篇文章主要介绍“Python面向对象的类和对象怎么使用”,在日常操作中,相信很多人在Python面向对象的类和对象怎么使用问题上存在疑惑,小编查阅了各式资料,整理出简单好用的操作方法,希望对大家解答”Python面向对象的类和对象怎么使用
2023-06-22

编程热搜

  • Python 学习之路 - Python
    一、安装Python34Windows在Python官网(https://www.python.org/downloads/)下载安装包并安装。Python的默认安装路径是:C:\Python34配置环境变量:【右键计算机】--》【属性】-
    Python 学习之路 - Python
  • chatgpt的中文全称是什么
    chatgpt的中文全称是生成型预训练变换模型。ChatGPT是什么ChatGPT是美国人工智能研究实验室OpenAI开发的一种全新聊天机器人模型,它能够通过学习和理解人类的语言来进行对话,还能根据聊天的上下文进行互动,并协助人类完成一系列
    chatgpt的中文全称是什么
  • C/C++中extern函数使用详解
  • C/C++可变参数的使用
    可变参数的使用方法远远不止以下几种,不过在C,C++中使用可变参数时要小心,在使用printf()等函数时传入的参数个数一定不能比前面的格式化字符串中的’%’符号个数少,否则会产生访问越界,运气不好的话还会导致程序崩溃
    C/C++可变参数的使用
  • css样式文件该放在哪里
  • php中数组下标必须是连续的吗
  • Python 3 教程
    Python 3 教程 Python 的 3.0 版本,常被称为 Python 3000,或简称 Py3k。相对于 Python 的早期版本,这是一个较大的升级。为了不带入过多的累赘,Python 3.0 在设计的时候没有考虑向下兼容。 Python
    Python 3 教程
  • Python pip包管理
    一、前言    在Python中, 安装第三方模块是通过 setuptools 这个工具完成的。 Python有两个封装了 setuptools的包管理工具: easy_install  和  pip , 目前官方推荐使用 pip。    
    Python pip包管理
  • ubuntu如何重新编译内核
  • 改善Java代码之慎用java动态编译

目录