一丶 class.js
js作为一个基于对象的语言,本身并没有提供class这一概念,通过上一篇文章javascript类于继承详解 我们明白了类的继承原理,为此我们可以实现一个属于的简单的OO原型继承。
/**
* 提供简单的OO原型继承
*/
(function(global) {
"use strict"
global.Class = {
/**
* @param superclass 父类
* @param definition 类的属性设置
* @returns {_Object} 返回生成好的类
*/
create : function(superclass, definition) {
if(arguments.length === 1) {
definition = superclass;
superclass = Object;
}
if(typeof superclass !== "function") {
throw new Error("superclass must be fun");
}
var _super = superclass.prototype;
//删去静态方法(静态方法不能被继承)
var statics = definition.statics;
delete definition.statics;
// 用于返回的中间类,调去deinition对象中的内容
function _Object() {
this.init.apply(this, arguments);
}
_Object.prototype = Object.create(_super);
//_super 属性保存父类原型
_Object.prototype._super = _super;
_Object.prototype.constructor = _Object;
//copy对象内容到原型中
for(var name in definition) {
_Object.prototype[name] = definition[name];
}
//绑定静态内容
_Object.statics = statics;
return _Object;
}
}
})(this);
二丶 使用说明:
1. 创建类:
通过Class.create([properties])
创建类,properties
为属性对象;
init
初始化方法,会在创建实例是被调用
statics
类的静态方法,ClassName.fn()
例子:
var Person = Class.create({
init : function(name, age) {
this.name = name;
this.age = age;
},
statics : function() {
console.log("我是Person类");
}
})
var per = new Person("phantom", 1);
2. 继承类
使用Class.create(superClass, properties)
继承父类superClass
this._super 保存有父类属性,可以用于子类中调用父类方法
var Teacher = Class.create(Person, {
init : function(name, age, school) {
this._super.init.call(this, name, age); //调用父类init
this.school = school;
},
teach : function() {
console.log(this.name + "上课呢");
}
})
var te = new Teacher("cjk", 30, 't_hot');
3.另一种建议
ClassName.prototype._super
上保持对父类原型的引用,所以可以利用这个访问父类方法,但是注意有this的要保证this指向。
这里的this._super.fn.call(this, […]) 似乎有点麻烦,下面提供一个改进方法。
/*
* 参考simple-inherittance
* 利用fnText检测函数中是否含有_super,来判断是否需要临时改变this._super值重写方法。
*/
var fnText = /xyz/.text(function() {
xyz;
}) ? /\b_super\b/ : /.*/
for(var name in definition) {
_Object.prototype[name] = typeof definition[name] === 'function' && typeof _super[fn] === 'function' && fnText.test(definition[name]) ?
(function(name, fn) {
return function() {
var tmp = this._super;
this._super = _super[name];
var ret = fn.apply(this, arguments);
this._super = tmp;
return ret;
}
})(name, definition[fn])
}
三丶 ES6的类扩展
ES6提供了更接近传统语言的写法,引入了Class(类)这个概念,作为对象的模板。通过class关键字,可以定义类。
1.定义一个类:
//定义类
class Point {
constructor(x, y) {
this.x = x;
this.y = y;
}
toString() {
return '(' + this.x + ', ' + this.y + ')';
}
}
上面代码定义了一个“类”,可以看到里面有一个constructo
r方法,这就是构造方法,而this关键字则代表实例对象。
2.继承类:
基本用法:
Class之间可以通过extends关键字实现继承,这比ES5的通过修改原型链实现继承,要清晰和方便很多。
class ColorPoint extends Point {}
上面代码定义了一个ColorPoint类,该类通过extends关键字,继承了Point类的所有属性和方法。但是由于没有部署任何代码,所以这两个类完全一样,等于复制了一个Point类。下面,我们在ColorPoint内部加上代码。
class ColorPoint extends Point {
constructor(x, y, color) {
super(x, y); // 调用父类的constructor(x, y)
this.color = color;
}
toString() {
return this.color + ' ' + super.toString(); // 调用父类的toString()
}
}
关于ES6中类的使用在这里就不多说明了,有兴趣的可以参考阮一峰大大的ECMAScript6入门
类工厂的构建已经有很多成熟的代码了,大家都可以去观看学习,远离都是一样的呦。
四丶题外话
这些内容其实好早以前就有了,但是我比较懒没写博客的习惯哈哈。本人开学就大三下学期了,也要该找实习了。所以呢,嗯哼,就过来吧以前学过的内容写成博客啥的。就当是为了面试加分吧。当然我也希望以后也能多坚持吧博客写下去,督促自己呗。