`
king_tt
  • 浏览: 2124403 次
  • 性别: Icon_minigender_1
  • 来自: 深圳
社区版块
存档分类
最新评论

JavaScript prototype属性与修改对象

 
阅读更多

JavaScript prototype属性


定义与用法

prototype 属性使您有能力向对象添加属性和方法。

语法

object.prototype.name=value

实例

在本例中,我们将展示如何使用 prototype 属性来向对象添加属性:

<script type="text/javascript">
	function employee(name,job,born) {
		this.name=name;
		this.job=job;
		this.born=born;
	}

	var bill=new employee("Bill Gates","Engineer",1985);
	employee.prototype.salary=null;
	bill.salary=20000;

	document.write(bill.salary);
</script>

示例:

<html>
<head>
<title>test prototype</title>
</head>

<body>

<script type="text/javascript">
	function employee(name, job, born) {
		this.name = name;
		this.job = job;
		this.born = born;
	}

	var bill = new employee("Bill Gates", "Engineer", 1985);

	employee.prototype.salary = null;
	bill.salary = 20000;

	document.write(bill.salary);
</script>

</body>

</html>

输出:

20000

================================================================================

JavaScript prototype修改对象

通过使用 ECMAScript,不仅可以创建对象,还可以修改已有对象的行为。

prototype 属性不仅可以定义构造函数的属性和方法,还可以为本地对象添加属性和方法。

创建新方法(通过已有的方法创建新方法)

可以用 prototype 属性为任何已有的类定义新方法,就像处理自己的类一样。例如,还记得 Number 类的 toString() 方法吗?如果给它传递参数 16,它将输出十六进制的字符串。如果这个方法的参数是 2,那么它将输出二进制的字符串。我们可以创建一个方法,可以把数字对象直接转换为十六进制字符串。创建这个方法非常简单:

Number.prototype.toHexString = function() {
  return this.toString(16);
};

在此环境中,关键字 this 指向 Number 的实例,因此可完全访问 Number 的所有方法。有了这段代码,可实现下面的操作:

var iNum = 15;
alert(iNum.toHexString());	//输出 "F"

由于数字 15 等于十六进制中的 F,因此警告将显示 "F"。

重命名已有方法

我们还可以为已有的方法命名更易懂的名称。例如,可以给 Array 类添加两个方法 enqueue() 和 dequeue(),只让它们反复调用已有的 push() 和 shift() 方法即可:

Array.prototype.enqueue = function(vItem) {
  this.push(vItem);
};

Array.prototype.dequeue = function() {
  return this.shift();
};

添加与已有方法无关的方法

当然,还可以添加与已有方法无关的方法。例如,假设要判断某个项在数组中的位置,没有本地方法可以做这种事情。我们可以轻松地创建下面的方法:

Array.prototype.indexOf = function (vItem) {
  for (var i=0; i<this.length; i++) {
    if (vItem == this[i]) {
	  return i;
	}
  }

  return -1;
}

该方法 indexOf() 与 String 类的同名方法保持一致,在数组中检索每个项,直到发现与传进来的项相同的项目为止。如果找到相同的项,则返回该项的位置,否则,返回 -1。有了这种定义,我们可以编写下面的代码:

var aColors = new Array("red","green","blue");
alert(aColors.indexOf("green"));	//输出 "1"

为本地对象添加新方法

最后,如果想给 ECMAScript 中每个本地对象添加新方法必须在 Object 对象的 prototype 属性上定义它。前面的章节我们讲过,所有本地对象都继承了 Object 对象,所以对 Object 对象做任何改变,都会反应在所有本地对象上。例如,如果想添加一个用警告输出对象的当前值的方法,可以采用下面的代码:

Object.prototype.showValue = function () {
  alert(this.valueOf());
};

var str = "hello";
var iNum = 25;
str.showValue();		//输出 "hello"
iNum.showValue();		//输出 "25"

这里,String 和 Number 对象都从 Object 对象继承了 showValue() 方法,分别在它们的对象上调用该方法,将显示 "hello" 和 "25"。

重定义已有方法

就像能给已有的类定义新方法一样,也可重定义已有的方法。如前面的章节所述,函数名只是指向函数的指针,因此可以轻松地指向其他函数。如果修改了本地方法,如 toString(),会出现什么情况呢?

Function.prototype.toString = function() {
  return "Function code hidden";
}

前面的代码完全合法,运行结果完全符合预期:

function sayHi() {
  alert("hi");
}

alert(sayHi.toString());	//输出 "Function code hidden"

也许你还记得,Function 对象这一章中介绍过 Function 的 toString() 方法通常输出的是函数的源代码。覆盖该方法,可以返回另一个字符串(在这个例子中,可以返回 "Function code hidden")。不过,toString() 指向的原始函数怎么了呢?它将被无用存储单元回收程序回收,因为它被完全废弃了。没有能够恢复原始函数的方法,所以在覆盖原始方法前,比较安全的做法是存储它的指针,以便以后的使用。有时你甚至可能在新方法中调用原始方法:

Function.prototype.originalToString = Function.prototype.toString;

Function.prototype.toString = function() {
  if (this.originalToString().length > 100) {
    return "Function too long to display.";
  } else {
    return this.originalToString();
  }
};

在这段代码中,第一行代码把对当前 toString() 方法的引用保存在属性 originalToString 中。然后用定制的方法覆盖了 toString() 方法。新方法将检查该函数源代码的长度是否大于 100。如果是,就返回错误信息,说明该函数代码太长,否则调用 originalToString() 方法,返回函数的源代码。

极晚绑定(Very Late Binding)

从技术上讲,根本不存在极晚绑定。本书采用该术语描述 ECMAScript 中的一种现象,即能够在对象实例化后再定义它的方法。例如:

var o = new Object();

Object.prototype.sayHi = function () {
  alert("hi");
};

o.sayHi();

在大多数程序设计语言中,必须在实例化对象之前定义对象的方法。这里,方法 sayHi() 是在创建 Object 类的一个实例之后来添加进来的。在传统语言中不仅没听说过这种操作,也没听说过该方法还会自动赋予 Object 对象的实例并能立即使用(接下来的一行)。

注意:不建议使用极晚绑定方法,因为很难对其跟踪和记录。不过,还是应该了解这种可能。

转载声明: 本文转自 http://www.w3school.com.cn/js/pro_js_object_modifying.asp


分享到:
评论

相关推荐

    JavaScript详解(第2版)

     8.5.1 使用prototype属性为对象添加属性   8.5.2 原型查找链   8.5.3 使用原型为对象添加方法   8.5.4 所有对象都有的属性和方法   8.5.5 创建子类及继承   8.6 应知应会   练习   第9章 ...

    关于javascript原型的修改与重写(覆盖)差别详解

    每个JavaScript函数都有prototype属性(javascript对象没有这个属性),这个属性引用了一个对象,这个对象就是原型对象。javascript允许我们修改这个原型对象。 修改有2种方式: 方式1:在原有的原型对象上增加属性...

    JavaScript完全自学宝典 源代码

    4.2.html 作为关联数组的对象与数组对象实现方式比较。 4.3.html prototype的用法。 4.4.html prototype实现继承机制。 4.5.html try-catch-finally语句执行流程。 第5章(\c05) 示例描述:介绍...

    cezve.js:在所有对象上定义伪属性而不修改 Object.prototype

    cezve.js 在所有对象上定义伪属性而不修改 Object.prototype

    Javascript数组操作高级心得整理

    2. 修改对象 18 (1) 创建新方法 18 (2) 重命名已有方法 19 (3) 添加与已有方法无关的方法 19 (4) 为本地对象添加新方法 19 3. 对象类型转换 19 (1) 转换成字符串 19 (2) 转换成数字 20  parseInt() 20  ...

    Javascript的构造函数和constructor属性

    真正的原因是:一个对象的constructor是它的构造函数的prototype.constructor,而每一个函数都有一个prototype,默认情况下,这个prototype有一个constructor属性,指向的是它自己。 我觉得Javascript的设计本意是让...

    程序天下:JavaScript实例自学手册

    1.21 用JavaScript随机修改页面的标题 1.22 判断网页加载完毕 1.23 嵌入网页的播放器 1.24 设置指定网页为主页 1.25 使用JavaScript传递页面参数 1.26 页面被冻结 第 2章 按钮特效 2.1 页面刷新按钮 2.2 按回车调用...

    《程序天下:JavaScript实例自学手册》光盘源码

    第1章 页面特效 ...1.2 页面自动最大化 1.3 页面自动刷新 1.4 页面的后退、刷新、前进 1.5保护网页源代码 ...22.15 用prototype实现JavaScript的继承 22.16 JavaScript制作哈希表 第23章 其他技巧及特效 23.1 ...

    JavaScript面向对象之Prototypes和继承

    一、前言 本文翻译自微软的牛人Scott Allen Prototypes and Inheritance in JavaScript ,本文对到底什么是Prototype和为什么通过Prototype能实现继承做了详细的分析和阐述,是理解JS OO 的佳作之一。翻译不好的地方...

    JavaScript中创建对象和继承示例解读

    假设函数F F用new方式构造对象时,对象的constructor被设置成这个F.prototype.constructor 如果函数在创建对象前修改了函数的prototype,会影响创建出来对象的construtor属性 如: 代码如下: function F(){};...

    程序员面试刷题的书哪个好-FrontEnd--Interview:自己收集整理的一些关于前端面试的问题

    特点:JavaScript对象是通过引用来传递的,我们创建的每个新对象实体中并没有一份属于自己的原型副本,当我们修改原型时,与之相关的对象也会继承这一改变。当我们需要一个属性时,JavaScript引擎会先看当前对象中...

    深入浅析JavaScript中的constructor

    这里有一点需要注意的是,每个函数都有一个prototype属性,这个prototype的constructor指向这个函数,这个时候我们修改这个函数的prototype时,就发生了意外。如 function Person(name,age){ this.name = name; this...

    浅谈javascript中的constructor

    这里有一点需要注意的是,每个函数都有一个prototype属性,这个prototype的constructor指向这个函数,这个时候我们修改这个函数的prototype时,就发生了意外。如 function Person(name,age){ this.name = name; ...

    大名鼎鼎SWFUpload- Flash+JS 上传

     SWFUpload是一个客户端文件上传工具,最初由Vinterwebb.se开发,它通过整合Flash与JavaScript技术为WEB开发者提供了一个具有丰富功能继而超越传统标签的文件上传模式。 [编辑本段]SWFUpload的主要特点  * 可以...

    Auntion TableSort(最新修改,支持Float,支持锁定不排序行)

    继续网上搜索,仍然没有找到合适的答案,为了适应要求,特自己动手修改如下,也方便大家, 望指教. 1、修正一个Float类型数据排序问题,老版本把Float当String排序了。 2、增加一个锁定合计栏不参与排序的功能 ...

    ironmon-prototypes:作业 17 - Ironmon 原型

    这是我们将用来帮助我们学习面向对象 JavaScript 的多日作业的第二天。 以这种方式搭建复杂的代码可以让我们更好地理解专业风格的迭代开发过程。 目标 完成此作业后,您应该有信心使用: 面向对象的 JavaScript,...

    在JavaScript中模拟类(class)及类的继承关系

    Javascipt语法不支持”类”(class)[es6已经支持],但是有模拟类的方法。今天我主要谈谈Javascipt中...类的属性和方法,还可以定义在构造函数的prototype对象之上。 function Person(name,age,job){ this.name=na

    DhtmlxTree-dhtmlxmenu实现在节点上右键弹出菜单

    但是dhtmlXTree不能满足"每个节点都有各自的URL地址,单击不同的节点框架页的右侧跳转到该节点所对应的URL"这点需求,因次想到了对dhtmlXTree进行一个小的扩展,即在其节点对象原有属性的基础上,再添加两个扩展...

    vue-demo:1.vue原始解析2.从0开始实现一个vue

    vue源码简析 阅读vue的字节数可以深入了解vue中的问题,还可以学习vue的程序设计;简析的版本为v2.5.16 ...直接在一个对象上定义一个新属性,或者修改一个对象的现有属性 Object.getOwnPropertyDescriptor

    jquery插件使用方法大全

    从这个版本开始,jQuery的性能达到了Prototype、Mootools以及Dojo等同类JavaScript库的水平。 jQuery 1.2(2007年9月):这一版去掉了对XPath选择符的支持,原因是相对于CSS语法它已经变得多余了。这一版能够支持对...

Global site tag (gtag.js) - Google Analytics