《悟透JavaScript》之 甘露模型(2)
作者:李战 来源:软件真谛 发布时间:2008-06-09 14:03:00
类定义中名为Create的函数是特别对待的,因为这就是构造函数。如果没有定义Create构造函数,Class()函数也会创建一个默认构造函数。事实上,这个构造函数就代表了类。除此之外,我们还为其定义了一个Base属性,以方便追溯继承关系。
在本例中的根类object的原型中,我们定义了一个base方法。有了这个方法之后,在类定义的构造函数中,就可以使用“this.base()”这样的方式来调用基类的构造函数。这种调用基类的方式和C#的base及Java的super就非常相似了。
不过,Class()函数中还是有个小问题,那就是不支持toString()方法的覆写。也就是说,如果我们为一个类定义了自己的toString()方法,调用Class()函数来生成类时,toString()方法会丢失。
原来toString()方法被JavaScript规定为不可枚举的内置方法。除此之外还有还有toLocaleString(), valueOf(), hasOwnProperty(), isPrototypeOf(), propertyIsEnumerable()等,都是不能枚举的内置方法。这样在Class()函数中的那个for(…in…)语句就不能遍历到这些属性,导致问题的产生。
因此,这个Class()语法甘露还不能支持不可枚举内置方法的覆写。这不能不说是一个小小的遗憾。当然,遇到需要完全覆写这些内置方法的情况并不多。顶多偶尔会有toString(), toLocaleString(), valueOf()这三个方法的覆写,其他几个几乎不会有覆写的情况。
除此之外,object根类的base()方法也还有个小问题。这个方法用到了函数的caller属性,以此判断构造函数的层次。而Opera浏览器不支持函数的caller属性,因此base方法不适合于Opera浏览器,这不能不说是另一个更大的遗憾。
如果在甘露模型中留有这样的问题,想必观音姐姐也会遗憾。我们还需要继续努力,别让观音姐姐失望啊。
其实,要解决不能覆写非枚举属性的问题也并非难事。既然这些属性是特殊的,我们就可以对其进行特殊处理。我们可以在复制完可枚举的属性之后,加上类似下面的特殊判断处理语句:
if(aDefine.toString != Object.prototype.toString)
aPrototype.toString = aDefine.toString;
因为,如果覆写了toString方法,那么它就肯定不等于原生的toString方法,这时就可复制toString方法。当然,我们也可以不通过比较,而是用hasOwnProperty来判断是否覆写了toString方法:
if(aDefine.hasOwnProperty("toString"))
aPrototype.toString = aDefine.toString;
使用哪种判断方式可以任选。我们建议采用直接比较方式,这样可以避免万一遇到覆写Object.prototype.hasOwnProperty的情况,也不至于出问题。当然,这也似乎有点太钻牛角尖了。
在实际的应用中,我们建议根据具体应用情况来决定是否需要支持特殊属性的覆写。如果在应用中根本不会覆写这些特殊属性,就无需加上这样的特殊处理。如果是打造专业的AJAX类库,最多支持toString(), toLocaleString(), valueOf()这三个方法的覆写就可以了。千万不要玩画蛇添足的游戏。
最头痛的是对base()函数的重写,也就要兼容不支持caller属性的Opera浏览器。虽然Opera浏览器目前只占很小的市场范围,但也算有名的四大浏览器之列。如果甘露模型不支持Opera浏览器,显然无法彰显观音菩萨的法力,也更不好意思说自己是观音老师的弟子。


猜你喜欢
- 在技术更新的进程中, 仍然有一些人死抱着已经过了气的东西不放. 也有一些人虽然进入到新的世界, 但仍摆脱不了陈
- 根据菜鸟教程Django教程学习,运行"python manage.py migrate" 报错,出现django.db
- 有时候使用Pytorch训练完模型,在测试数据上面得到的结果令人大跌眼镜。这个时候需要检查一下定义的Model类中有没有 BN 或 Drop
- 方法一:def commaSpiltList(self, listData): listData = list(listData) strs
- 有的时候我们在学习或者工作中会使用到SQL语句,那么介绍一下limit和offset的使用方法。mysql limit与offset用法my
- 一、 封装的JS文件 //********************************************************
- Python中编码问题:u'\xe6\x97\xa0\xe5\x90\x8d' 类型的转为utf-8的解决办法相信小伙伴们遇
- declare @name varchar(50)exec sp_executesql N'select @value=姓名 fro
- 需要准备环境:python3.6、vultr(或者其他服务器)、xshell第一步:python安装必备环境Django库Xshell链接远
- 废话就不多说了,直接上内容。<form action="/home/search" method="ge
- FSO中除了可以对驱动器、文件夹的操作以外,功能最强大的就是对文件的操作了。它可以用来记数、内容管理、搜索还可生成动态HTML页面等等。一、
- 本文实例讲述了Python编程判断这天是这一年第几天的方法。分享给大家供大家参考,具体如下:题目:输入某年某月某日,判断这一天是这一年的第几
- 在python3中按数据类型的可变与不可变大致分为如下几种类型:不可变数据(3个):Number(数字)、String(字符串)、Tuple
- 一、导出数据。 先说明一下自己的环境:Mac OS X 10.8.3, MySQL Community Server 5.6.10, MyS
- cron 简介在 Unix-like 操作系统中,有一个大家都很熟悉的 cli 工具,它能够来处理定时任务,周期性任务,这就是:
- MySQL 查询合并如果我们需要将两个select语句的结果作为一个整体显示出来,我们就需要用到union或者union all关键字。un
- 无限循环如果条件判断语句永远为 true,循环将会无限的执行下去。如下实例#!/usr/bin/python# -*- coding: UT
- 1、什么是版本控制系统版本控制是一种记录一个或若干个文件内容变化,以便将来查阅特定版本修订情况的系统。版本控制系统不仅可以应用于软件源代码的
- 事务日志文件Transaction Log File是用来记录数据库更新情况的文件,扩展名为ldf。在 SQL Server 7.0 和 S
- 公司服务器的mysql和redis连接都需要有跳板机,网上有很多python ssh远程连接mysql的,那天我研究了下,利用sshtunn