JS类的定义

ECMAScript6新引入了class关键字具有正式定义类的能力,类(class)是ECMAScript中新的基础性语法糖结构,类的语法可以非常方便的定义应该存在于实例上的成员,应该存在于原型上的成员,以及应该存在于类本身的成员。

1. 类定义

与函数相似,定义类也有两种主要方式:类声明和类表达式。这两种方式都使用class关键字加大括号

class Person {} // 类声明
console.log(Person) // class Person {}
console.log(typeof Person) // function
const Animal = class {} // 类表达式

注意:
类表达式与函数表达式形似,在被求值前也不能引用;
类声明式与函数声明式不同,函数表达式可以提升,但类不能;
函数受函数作用域限制,而类受块作用域限制;

console.log(FunPerson) // FunPerson () {}
function FunPerson () {}
console.log(FunPerson ) // FunPerson () {}

console.log(ClassPerson) // ReferenceReeor: ClassPerson is not  defined
class ClassPerson {}
console.log(ClassPerson ) // ClassPerson {}
{
	function FunPerson () {}
	class ClassPerson {} 
}
console.log(FunPerson) // FunPerson () {}
console.log(ClassPerson) // ReferenceReeor: ClassPerson is not  defined

2. 类的构成

类可以包含构造函数方法、实例方法、获取函数、设置函数、静态类方法,但这些都不是必须的,空的类定义照样有效

class Person {
	constructor(name) { this.name = name} // 构造函数方法
	get myName() {} // 获取函数
	static myAge() {} // 静态方法
	getName() { return this.name } // 实例方法
}
let p = new Person('tom')
console.log(p.getName() ) // tom

3. 类构造函数

类的内部工作机制就是原型操作,constructor关键字用于在类定义块内部创建类的构造函数,在使用new操作符创建类的实例时,会调用constructor函数

class Person {
	constructor(name) {
		this.name = name // 类把属性写在constructor类构造函数里
	}
	show() {} // 类把公共方法写这里
}
console.dir(Person) // 与构造函数的结构类似
console.log(Person === Person.prototype.constructor) // true

function Animal(name) {
	this.name = name // 构造函数把属性写这里
}
Animal.prototype.show = function() {} // 构造函数把公共方法写在原型上
console.dir(Animal)
console.log(Animal=== Animal.prototype.constructor) // true

使用类new调用类的构造函数会执行以下操作:

  • 在内存中创建一个新对象;
  • 这个新对象内部的[[prototype]] 指针被赋值为构造函数的prototype属性;
  • 构造函数内部的this被赋值为这个新对象,即this指向新对象;
  • 执行构造函数内部的代码,给新对象添加属性;
  • 如果构造函数返回非空对象,则返回该对象,否则,返回刚创建的新对象

4. 实例、原型和类成员

4.1 实例成员:
每次通过new调用类标识符时,都会执行类构造函数,在这个函数内部,可以为新创建的实例添加“自有”属性,在构造函数执行完毕后。仍然可以给实例继续添加新成员,每个实例都对应一个唯一的成员对象,这意味着所有成员都不会在原型上共享。

class Person {
	constructor() {
		this.name = new String('jake') // 添加到this的所有内容都会存在于不同的实例上
	}
	show() {} 
}
let p1 = new Person(),
	p2 = new Person()
console.log(p1.name === p2.name ) // false

4.2 原型方法
为了在实例间共享方法,类定义语法把在类块中定义的方法作为原型方法。
类定义也支持获取和设置访问器,与普通函数一样

class Person {
	constructor() {
		this.name = new String('jake') 
	}
	show() {} // 在类块中定义的所有内容都会定义到类的原型上
	set age(newval) { this.age = newval}
	get age() { return this.age}
}
let p1 = new Person()
console.log(p1) // {name: 'jake', __proto__: {constructor: class Person   }, show: f show(), __proto__: Object}
p1.age = 18
console.log(p1.age) // 18

4.3 静态类方法
与原型成员相似,静态成员每个类上只能有一个,使用static关键字作为前缀,常用于执行不特定于实例的而操作,不要求存在类的实例

class Person {
	constructor() {
		this.name = new String('jake')
	}
	static show() { console.log(this) } // 定义在类本身上
}
let p1 = new Person()
Person.show() // class Person {}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值