JavaScript学习笔记——进阶的对象创建方式P5-原型链(原型继承原型):原型链的终点-Object、利用继承来重写\扩展内置对象

要点

  • 通过构造函数的属性prototype可以访问其原型
  • 构造函数有默认的原型Object,但也可将原型(prototype)设置为其他(自定义的)原型对象
  • 归根结底,所有原型和对象都是从Object派生而来的
  • object包含所有对象都将继承的属性和方法,如toStringhasOwnProperty
  • 可给内置对象(如Object和String)添加属性,也可重写它们的既有属性
    例如,重写内置的Object对象的toString方法;
    为内置的String对象新增hasKeyWord方法;
    但这样做时必须小心,因为你所作的修改可能带来深远的影响。

原型链的终点是Object,而非小狗原型

前面介绍的两个原型链(这里的“原型链”实际上是一个简化版本):

  • 小狗原型<-小狗实例;
  • 小狗原型<-表演犬原型<-表演犬实例;

真正的原型链:

  • Object<-小狗原型<-小狗实例;
  • Object<-小狗原型<-表演犬原型<-表演犬实例;

真正的原型链
真正的原型链

何为Object

  • Object可视为对象始祖,所有对象都是从它派生而来的。
  • ①每个对象都有原型,该原型默认为Object;
    ②可将对象原型设置为其他对象,如表演犬的原型是小狗实例;
  • 但无论如何,所有原型链的终点都是Object
    i.e. 任何对象都继承了"Object原型"的属性和方法
  • Object实现了多个重要的方法,它们是JavaScript对象系统的核心部分
  • Object的常用方法:hasOwnPropertytoString(但实例通常会重写它)等

一、利用继承来重写内置的Object行为

由上,所有对象都是从Object派生而来的,即 任何对象都继承了"Object原型"的属性和方法
因此,我们可以对任何对象调用hasOwnPropertytoString等方法

不仅如此,我们还可以根据自己的需要重写这些内置方法

继承内置对象时,可重写内置对象自带的方法。
一种常见的情形是,重写Object定义的方法toString。所有对象都可使用方法toString来获取对象的字符串表示,我们可根据需要来重写该方法

例子:重写toString方法

从Object继承而来的toString方法,在显示对象时做得并不好:

function Robot(name, year, owner) {
    this.name = name;
    this.year = year;
    this.owner = owner;
}

var robby = new Robot("Robby", 1956, "Dr. Morbius");
console.log(robby.toString());

输出[object Object]

这样的输出意义不大,我们可以根据需要重写toString方法,得到想要的字符串表示

function Robot(name, year, owner) {
...
}
Robot.prototype.toString = function(){
	return "Robot " + this.name + ", belonging to " + this.owner;
}

var robby = ...
console.log(robby.toString());

输出 Robot Robby, belonging to Dr. Morbius

谨慎重写Object的属性和方法

重写内置对象的属性和方法时,一定要特别小心;
若随意重写某些Object的属性和方法,可能改变一些依赖于这些属性来完成工作的代码的行为,以意想不到的方式破坏既有的代码、引发难以发现的bug

可以重写的Object的属性和方法
toString
toLocaleString类似于toString,提供描述对象的本地化的(用母语表示的)字符串
valueOf默认返回当前对象,可重写并让它返回你希望的其他值

不可重写的Object的属性和方法
constructor指向与该原型相关的构造函数
hasOwnProperty
isPrototypeOf判断一个对象是否是另一对象的原型
propertyIsEnumerable判断对象中指定的属性是否可以被 for…in 循环枚举,但是通过原型链继承的属性除外

二、利用继承来扩展内置对象的行为

可以对内置对象添加新的方法,从而让所有对象实例都可使用该方法

例子:为内置的String对象新增hasKeyWord方法

我们知道,对于所有字符串对象都可使用substring等方法;
但如果想添加更多自定义的新方法,且让任何字符串(String实例)都能使用它,可以利用继承来扩展内置对象

为String原型扩展一个hasKeyWord方法,在字符串包含某些关键字时返回true
代码如下:
注意,这里是直接对内置对象String的原型String.prototype进行操作

String.prototype.hasKeyWord= function() {
	var keyWord= ["load","touch", "open"];

	for (var i = 0; i < keyWord.length; i++) {
		var index = this.indexOf(keyWord[i]);
		//this指向调用hasKeyWord方法的对象(字符串实例)
		
		if (index >= 0) {//字符串中包含关键字
			return true;
		}
	}
	return false;
};

例子2:为内置的String对象新增palindrome方法

为String原型扩展一个palindrome方法,判断是否为回文串
代码如下:
注意,这里是直接对内置对象String的原型String.prototype进行操作

String.prototype.palindrome= function() {
	var rvs = this.split("").reverse().join("");
	//字符串对象没有reverse方法,数组才有
	return (rvs===this.valueOf());
};

要注意,在为内置对象扩展新方法时,我们操作的始终是一个对象,而非作为基本类型的字符串
因此,始终应该用this来表示调用该方法的字符串对象

  • 必须用this.valueOf()表示字符串,因为this是一个对象,而非字符串(基本类型),需要valueOf方法返回 String 对象的原始值。

谨慎扩展内置对象

为String等内置对象添加方法时,要小心:

  • 编写自己的代码,确保新方法的名称不与对象的既有方法冲突
  • 使用他人的代码,即 链接其他代码时,一定要清楚这些代码包含的自定义扩展,以防名称冲突
  • 有些内置对象(如Array)不能扩展
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值