Javascript chapter9 classes
9.1 class 和prototype
自己定义函数并使用Object.create()函数就相当于定义了一个javascript类。
*[Symbol.iterator](){
for(let x=Math.ceil(this.from);x<=this.to;x++)yield x;
}
上述代码实现了迭代器,类可以迭代可以使用for/of循环和...操作符
ES6之前的类实现如下
function Range(from,to){
this.from=from;
this.to=to;
}//构造函数
Range.prototype={
includes:function(x){return this.from<=x&&x<=this.to},//return x
//迭代器实现
[symbol.iterator]:function*(){
let x=Math.ceil(this.from);x<=this.to;x++)yield x;
},
toString:function(){return "("+this.from+"..."+this.to+")";}
};
//调用:
let r=new Range(1,3);
r.includes(2);//true
r.toString();//(1,2,3)
[...r]//[1,2,3]
9.2.1
instanceof
r instance of Range;//判断r是不是Range类的对象。左操作数是被检测的对象,右操作数是构造函数名
o instanceof C 实际检查的是o是否继承于C.prototype,下例说明问题。
function Strange(){};
Strange.prototype=Range.prototype;
new Strange() instanceof Range;//true
isPrototypeOf()方法。也是用来检测对象是否是某类的对象
range.methods.isPrototypeOf(r);//range.methods is the prototype object.
9.2.2
let F=function(){};//函数对象
let p=F.prototype;//p是F的原型
let c=p.constructor;//c是p的构造函数
c===F;//true F.protype.constructor===F
9.3类
class Range{
constructor(from,to){
this.from=from;
this.to=to;
}
//return true if x in the range,false otherwise;
includes(x){return this.from<=x && x<=this.to;}
//class迭代器
*[symbol.iterator](){
for(let x=Math.ceil(this.from);x<=this.to;x++)yield x;
}
//toString方法实现。
toString(){return `(${this.from}...${this.to})`;}
}
使用extends关键字实现继承。
class Span extends Range{
constructor(start,length){
super(start,length);
}
}
两点:1.在class类定义的代码是严格模式
2.必须先定义后使用类代码。
9.3.1静态方法
使用static 关键字定义静态方法。
注意:static方法是类方法,不存在实例,所以不要使用this关键字。
9.3.3私有变量
代表私有变量。外部不可见,不可直接访问,是Immutable的变量。
class Buffer{
#size=0;
get size(){return this.#size;}
}
例:复数类
class Complex{
#r=0;
#i=0;
constructor(real,imaginary){
this.r=real;
this.i=imaginary;
}
plus(that){
return new Complex(this.r+that.r,this.i+that.i);
}
times(that){
return new Complex(this.r*that.r-this.i*that.i,this.r*that.i+this.i*that.r);
}
static sum(c,d){return c.plus(d);}
static product(c,d){return c.times(d);}
get real(){return this.r;}
get imaginary(){return this.i;}
get magnitude(){return Math.hypot(this.r,this.i);}
toString(){return `{${this.r},${this.i}}`};
equals(that){
return that instanceof Complex &&
this.r===that.r&&this.i===that.i;
}
}
9.4给类添加方法。
给原型添加方法。
Complex.prototype.conj=function(){return new Complex(this.r,-this.i);};
9.5子类
ES6之前子类的定义 ,下例span类继承于range类
//span的构造函数
function Span(start,span){
if(span>=0){
this.from=start;
this.to=start+span;
}else{
this.to=start;
this.from=start+span;
}
}
//保证span类继承于Range类
Span.prototype = Object.create(Range.prototype);
//构造函数不是Range的构造函数,把它设定为Span的构造函数。
Span.prototype.constructor=Span;
//覆盖父类的对应函数
Span.prototype.toString=function{
....
}
ES6之后的继承
class EZArray extends Array{
get first(){return this[0];}
get last(){return this[this.length-1];}
}
子类调用父类的函数使用super关键字。
1.如果你使用了extends表示继承,构造函数中必须调用父类的构造函数
2.如果你没有对子类设定构造函数,那么会生成默认的构造函数
3.你也许不能使用this关键字在你的构造函数中,直到你调用了父类的构造函数。

浙公网安备 33010602011771号