基本概念
类的所有的实例对象都从同一个原型对象上继承属性
类和构造函数
构造函数用来初始化新建对象
构造函数的prototype属性被用作新对象的原型
类名首字母大写,而普通的函数和方法首字母小写
每个JavaScript函数都拥有一个prototype属性。这个属性的值是一个对象,这个对象包含唯一一个不可枚举的属性constructor,constructor的值是一个函数对象,代指构造函数。
构造函数是类的公共标识,但原型是唯一标识
Java式继承
一个经典的继承extend方法(解决IEBUG)
var extend=(function(){ for (const p in {toString:null}) { return function extend(o){ for(var i=1;i<arguments.length;i++){ var source=arguments[i]; for (const prop in source) { o[prop]=source[prop]; } } return o; } } return function patched_extend(o){ for(var i=1;i<arguments.length;i++){ var source=arguments[i]; for (const prop in source) { o[prop]=source[prop]; } for(var j=0;j<protoprops.length;j++){ var prop=protoprops[j]; if(source.hasOwnProperty(protoprops[j])){ o[prop]=source[prop]; } } } } var protoprops=["toString","valueOf","toLocalString","isPrototypeOf","hasOwnProperty","propertyIsEnumerable"]; }())
一个用来定义类的简单函数
function defineClass( constructor,//用以设置实例属性的函数 methods,//实例的方法 statics//类属性 ){ if(methods){ extend(constructor.prototype,methods); } if(statics){ extend(constructor,statics); } return constructor; }
类和类型的检测
i instanceof o 检测左边的对象是否为右边的实例。运算符的右操作数是构造函数,但比较过程实际上是取,i.__proto__和o.prototype进行比较,可参考如下链接
https://www.ibm.com/developerworks/cn/web/1306_jiangjj_jsinstanceof/
运用constructor属性进行比较
运用name属性比较
利用鸭式辨形,即通过特有的方法及属性进行判断,类似于数组的length属性
标准转换方法
toString:Object.prototype上的toString返回[object Object],我们在定义时应当返回一个可读字符串
toLocalString:同toString类似,大多数情况知识简单调用toString方法,一些内置类型包含的该方法实际上是返回本地化相关的字符串
valueOf:用来将对象转换为原始值
具体的定义根据自己定义类的功能进行定义
定义子类
利用一个类创建它的子类,假设有一个inherit继承方法,extend采用上面的方法
//用一个简单函数创建子类 function defineSubClass( superclass,//父类构造函数 constructor,//子类构造函数 methods,//实例方法 statics//类属性 ){ constructor.prototype=inherit(superclass.prototype); constructor.prototype.constructor=constructor; if(methods){ extend(constructor.prototype,methods); } if(statics){ extend(constructor.statics); } return constructor; }
定义抽象类
//定义一个可以用作任何抽象方法的函数 function abstractmethod(){ throw new Error('This is a abstract method') } //定义一个抽象类 function AbstractObject(){ throw new Error('cant instantiate abstract classes') } //给该类定义一个抽象方法add AbstractObject.prototype.add=abstractmethod;