javascript中的类
function PersonType(name){
this.name = name;
}
PersonType.prototype.sayName = function(){
console.log(this.name)
}
var person = new PersonType("Nicholas")
person.sayName(); // outputs "Nicholas"
console.log(person instanceof PersonType) // true
console.log(person instanceof Object) // true
类声明
class PersonClass {
// 等价于PersonType构造函数
constructor(name){
this.name = name
}
// 等价于PersonType.prototype.sayName
sayName(){
console.log(this.name)
}
}
let person = new PersonClass("Nicholas");
person.sayName(); // outputs "Nicholas"
console.log(person instanceof PersonClass) //true
console.log(person instanceof Object) // true
console.log(typeof PersonClass) // function
console.log(typeof PersonClass.prototype.sayName) // function
class
是语法糖,PersonClass声明实际上创建了一个具有构造函数方法行为的函数。通过Symbol.iterator
定义生成器方法即可为定义默认迭代器
class Collection {
constructor(){
this.items = [];
}
*[Symbol.iterator](){
yield *this.items.values()
}
}
var collection = new Collection();
collection.items.push(1);
collection.items.push(2);
collection.items.push(3);
for(let x of collection){
console.log(x);
}
// 输出:
// 1
// 2
// 3
静态成员
ES6类语法简化了创建静态成员的过程,在方法或访问器属性名前使用正式的静态注释即可。
class PersonClass {
// 等价于PersonType构造函数
constructor(name){
this.name = name
}
// 等价于PersonType.prototype.sayName
sayName(){
console.log(this.name)
}
// 等价于等价于PersonType.create
static create(name){
return new PersonClass(name)
}
}
let person = PersonClass.create("Nicholas")
继承与派生类
实现继承与自定义类型是一个不小的工作,严格意义上的继承需要多个步骤实现
function Rectangle(length,width){
this.length = length;
this.width = width;
}
Rectangle.prototype.getArea = function(){
return this.length*this.width
}
function Square(length){
Rectangle.call(this,length,length)
}
Square.prototype = Object.create(Rectangle.prototype,{
constructor:{
value:Square,
enumerable:true,
writable:true,
configurable:true
}
})
var square = new Square(3)
console.log(square.getArea()); // 9
console.log(square instanceof Square) // true
console.log(square instanceof Rectangle) // true
ES6使用extends
关键字可以指定类继承的函数。原型会自动调整,通过调用super()方法即可访问基类的构造函数
class Rectangle {
constructor(length,width){
this.length = length;
this.width = width
}
getArea(){
return this.length*this.width;
}
}
class Square extends Ractangle {
constructor(length){
// Rectangle.call(this,length,length)
super(length,length)
}
}
var square = new Square(3)
console.log(square.getArea()); // 9
console.log(square instanceof Square) // true
console.log(square instanceof Rectangle) // true
继承自其的类我们称之为派生类,如果在派生类中指定了构造函数必须调用super(),如果不这样做程序就会报错。
- super
- 只可在派生类的构造函数中使用super(),非派生类不可使用
- 在构造函数中访问this之前一定要调用super,它负责初始化this,
- 如果不想调用super(),则唯一的方法是让类的构造函数返回一个对象。
类方法遮蔽
派生类中的访问总会覆盖基类中的同名方法,如果想调用基类中的方法,我们可以使用super.getArea()
class Square extends Rectangle {
constructor(length){
super(length,length)
}
//覆盖并遮蔽Rectangle.prototype.getArea()方法
getArea(){
return this.length*this.length
}
}
派生自表达式的类
ES6最强大的一面或许是从表达式导出类的功能了。只要表达式可以被解析为一个函数并且具有[[Construct]]
属性和原型,那么就可以用extends进行派生。
内建对象的继承
class MyArray extends Array {
// 空
}
var colors = new MyArray();
colors[0]="red"
console.log(colors.length) // 1
colors.length = 0
console.log(colors[0]); // undefined
MyArray直接继承自Array,其行为与Array也很相似,操作数值型属性会更新length属性,操作length属性也会更新数值型属性。于是可以正确地继承Array对象来创建自己的派生数组类型
Symbol.species属性
内建对象继承的一个实用之处是,原本在内建对象中返回实例自身的方法将自动返回派生类的实现。如你有一个继承自Array的派生类MyArray,那么像slice()这样的方法也会返回一个MyArray的实例
class MyArray extends Array{
// 空
}
let items = new MyArray(1,2,3,4),
subitems = items.slice(1,3);
console.log(items instanceof MyArray); //true
console.log(subitems instanceof Myarray); // true
Symbol.species
是诸多内部Symbol中的一个,它被用于定义返回函数的静态访问器属性。被返回的函数是一个构造函数,每当要在实例方法中(不是构造函数中)创建类的实例时必须使用这个构造函数。以下这些都是实现该属性定义的Symbol.species
- Array
- ArrayBuffer
- Map
- Promise
- RegExp
- Set
- Typed arrays
// 几个内建类型像这样使用
class MyClass {
static get [Symbol.species](){
return this
}
constructor(value){
this.value = value
}
clone(){
return new this.constructor[Symbol.species](this.value)
}
}
在构造函数中使用new.target
class Shape {
constructor(){
if(new.target === Shape){
throw new Error("这个类是不能直接被实例化的")
}
}
}
class Rectangle extends Shape {
constructor(length,width){
super();
this.length = length;
this.width = width;
}
}
let x = new Shap(); // 抛出错误
let y = new Rectangle(3,4) // 正常执行
console.log(y instanceof Shape) //true
主题测试文章,只做测试使用。发布者:Walker,转转请注明出处:https://joyjs.cn/archives/4335