本文是学习和总结ECMAScript5.1规范形成的。是对规范中所提及的Javascript类型进行剖析后的个人观点的表达(如有Bug望各位道友指正)。主要是各类型的实例方法,不包含任务构造函数的方法。剖析的切入点如下:
1. 是否可以继承
2.通用方法、非通用方法,以及通用方法的使用。
名词解释: 通用:表示此方法可以被其他类型调用,也就是this指针可以改变 非通用:不可被其他类型调用,this指针只能是当前类型
一、Function与Object
var Cn = new Function("alert('1');this.a='a';");
var _cn = new Cn(); //_cn:Object类型;Cn:Function类型,new的Function,他的类型都是Object
new Function和关键字function是相同的作用,创建一个Function的实例。
实例方法 | 是否通用 | 说明 |
constructor | 非通用 | |
toString | 非通用 | |
toLocalString | 非通用 | 为派生类提供接口 |
valueOf | 非通用 | |
hasOwnProperty | 非通用 | 不考虑原型链 |
isPrototypeOf | 非通用 | 判断对象是否存在于指定对象的原型链上 |
propertyIsEnumerable | 非通用 | 不考虑原型链 |
二、Array可以继承
every返回第一个为false的元素
实例方法 | 是否通用 | 说明 |
constructor | 非通用 | |
toString | 通用 | |
toLocaleString | 通用 | |
concat | 通用 | |
join | 通用 | |
pop | 通用 | |
push | 通用 | |
reverse | 通用 | 反转数组 |
shift | 通用 | 删除数据第一个位置的元素,并返回 |
slice | 通用 | 返回start和end之间的元素,start不被包含 |
sort | 通用 | |
splice | 通用 | 删除数据元素,以索引下标开始,个数 |
unshift | 通用 | 在数组第一个位置插入元素 |
indexOf | 通用 | |
lastIndeOf | 通用 | |
every | 通用 | 返回第一个为false的元素 |
some | 通用 | 返回第一个为true的元素 |
forEach | 通用 | |
map | 通用 | |
filter | 通用 |
通用使用方法示例代码:
function CustomFn(){
this["0"] = "asfd";
this["1"] = "第二个";
this["2"] = "第三个";
this.length = 3;
}
var pt = CustomFn.prototype;
pt.join = Array.prototype.join;
pt.shift = Array.prototype.shift;
var cu = new CustomFn();
console.log(cu.join("-"));
cu.shift();
console.log(cu.join("-"));
注意:想要利用Array的通用方法,类的结果就得构建得像一个数组,所以我们必须满足数组两个必要的条件:
- 下标:用0,1,2是为了表示数组索引下标;
- 长度:length是为了表示数组的长度;
三、Number、String、Boolean、Date
String类型有些许的通用性方法,但Number、Boolean和Date却未能明确标记出通用性方法。方法细节此处就不存赘述,如想具体了解可查看ECMAScript5.1的规范。这里只给出一个Number使用String通用方法的示例代码:
function CustomNumber(){
}
var pt = CustomNumber.prototype;
pt.toString = function(){
return 134;
}
pt.ct = String.prototype.charAt;
var _num = new CustomNumber();
console.log(_num.ct(1)); Number.prototype.cCharAt = String.prototype.charCodeAt;
console.info((10).cCharAt(1));
注意点:
- 能被其他对象的引用的只有通用方法
- 重写基类的原型方法,如CustomNumber类的原型方法toString(重写的Object类的),为什么要重写toString,这个可从ecmaScript规范中获得,因为他在调用charAt、charCodeAt等方法是会先调用toString方法获取值。
- 类型转换:CheckObjectCoercible方法,内部还会调用ToObject方法,将基本类型转换为引用类型。
四、Error
用于显示或抛出程序运行时的异常信息,主要name、message等实例属性(可以设置的),Stack(只读,异常的堆栈信息)。
ECMAScript5.1派生类实现代码:
function Inherit(Sup, Chid){
Chid.prototype = Object.create(Sup.prototype); //作为函数或者类时的原型
Object.defineProperty(Chid,'constructor',{
value: Chid,
enumerable:false,
writable:true,
configurable:true
}); //构造函数
Chid.__proto__ = Sup; //作为对象的原型(构建原型链)
} var CustomError = function(_error){
Inherit(_error, CustomError);
function CustomError(){
var applyCustructor = (CustomError.__proto__ || Object.getPrototypeOf(CustomError)).call(this); //执行父级的构造函数
//父类构造函数有返回值,就有返回值,否则就用this
var _this = ( typeof applyCustructor == 'object' || typeof applyCustructor == 'function' ) ? applyCustructor : this;
_this.name = 'sdf';
return _this;
}
return CustomError;
}(Error); var _error = new CustomError();
throw _error;
重点理解:var applyCustructor = (CustomError.__proto__ || Object.getPrototypeOf(CustomError)).call(this);
这句代码,表示执行CustomError原型上的构造函数(也就是Error),与var applyCustructor = Error.call(this);
是等效的
ES6的派生类实现:
class CError extends Error{
constructor(){
super();
this.name = '子类';
}
}
var _e = new CError();
V8环境下运行的区别: