class
js中类的类型也是function
class Person {}
console.log(typeof Person);
constructor 构造器
构造器中实例化的属性配置 是 私有属性
class Person {
constructor(name = 'zhangsan', age = '18') {
this.name = name;
this.age = age;
}
}
console.log(typeof Person);
原型上的方法 是公有方法 直接写在类中
class Person {
constructor(name = 'zhangsan', age = '18') {
this.name = name;
this.age = age;
}
say() {
console.log(`my name is ${this.name} and age is ${this.age}`);
}
}
console.log(new Person());
类内部的方法是不可枚举的
class Person {
constructor(name = 'zhangsan', age = '18') {
this.name = name;
this.age = age;
}
say() {
console.log(`my name is ${this.name} and age is ${this.age}`);
}
drink() {
console.log('I can drink');
}
eat() {
console.log('I can eat');
}
}
console.log(Object.keys(Person.prototype));
当我们什么都不指定 只有一个空的class new出来也不会报错 会自动加一个constructor在原型上
class Person {}
console.log(new Person());
js中的类与函数非常相似
function Person() {}
console.log(new Person() instanceof Person);
class Person {}
console.log(new Person() instanceof Person);
class Person {
constructor() {
return Object.create(null);
}
}
console.log(new Person() instanceof Person);
当我们创建一个函数时 如果把它赋值给一个变量 那么函数名就无意义了
此时test1是可以省略的
let test = function test1() {};
let test = function () {};
那对于类有没有这种特殊情况的
let Person = class Person1 {
say() {
console.log(1);
}
};
我们尝试省略Person1
发现是可以的
let Person = class {
say() {
console.log(1);
}
};
console.log(new Person().say());
必须通过new 的方式执行 class
这个样子是会报错的
let Person = class {
say() {
console.log(1);
}
}();
console.log(Person.say());
let person = new (class {
say() {
console.log(1);
}
})();
console.log(person.say());
let person = new (class {
constructor(name = 'zhangsan', age = '18') {
this.name = name;
this.age = age;
}
say() {
console.log(1);
}
})('lisi', '19');
console.log(person);
类不能提升
不存在暂时性死区(TDZ)
console.log(new Person());
class Person {}
没有公有属性
公有函数私有化
方式一 symbol
const eat = Symbol();
class Person {
constructor(name, age) {
this.age = age;
this.name = name;
}
say() {
console.log(1);
}
[eat]() {
console.log(2);
}
}
console.log(new Person().say());
console.log(new Person().eat());
方式二
class Person {
constructor(name, age) {
this.age = age;
this.name = name;
}
say(baz) {
children.call(this, baz);
}
}
function children(baz) {
return (this.baz = baz);
}
static定义静态属性与静态方法
通过当前的类调用 不通过实例调用
class Person {
static a = 1;
static foo() {
return 2;
}
}
console.log(Person.a);
console.log(Person.foo());
对象的get set 与类的get set
对象的get set 直接使用.运算符使用
var obj = {
get a() {
console.log(1);
},
set a(value) {
console.log(value);
},
};
console.log(obj.a);
obj.a = 3;
类的get 与set需要new 实例化后使用
class Person {
get a() {
console.log(1);
}
set a(value) {
console.log(value);
}
}
let person = new Person();
console.log(person.a);
person.a = 2;
extends
继承
继承的是父级共有属性的默认值
class Parent {
constructor(name = 'zhangsan') {
this.name = name;
}
}
class Child extends Parent {}
console.log(new Child());
静态属性不继承
class Parent {
constructor(name = 'zhangsan') {
this.name = name;
}
say() {
console.log(1);
}
static a() {
console.log(2);
}
}
class Child extends Parent {}
console.log(new Child().a());
派生类
必须在派生类中this前 使用super改变this指向
如果不用就会报错
class Parent {
constructor(name = 'zhangsan') {
this.name = name;
}
say() {
console.log(1);
}
static a() {
console.log(2);
}
}
class Child extends Parent {
constructor(age = '19') {
this.age = age;
}
}
console.log(new Child().age);
class Parent {
constructor(name = 'zhangsan') {
this.name = name;
}
say() {
console.log(1);
}
static a() {
console.log(2);
}
}
class Child extends Parent {
constructor(name = 'lisi', age = '19') {
super(name);
this.type = 'child';
this.age = age;
}
}
console.log(new Child());
let proto = {
y: 20,
z: 40,
};
let obj = {
x: 10,
foo() {
console.log(super.y);
},
};
Object.setPrototypeOf(obj, proto);
obj.foo();
super
1.在对象当中 指代对象的原型
2.在静态方法中 指向自己的父类
class源码
类的写法
class Person {
constructor(name = 'zhangsan', age = '18') {
this.name = name;
this.age = age;
}
say() {
console.log('hello word');
}
drink() {
console.log('drink');
}
static eat() {
console.log('eat');
}
}
源码转为es5
'use strict';
var _createClass = (function () {
function defineProperties(target, props) {
for (var i = 0; i < props.length; i++) {
var descriptor = props[i];
descriptor.enumerable = descriptor.enumerable || false;
descriptor.configurable = true;
if ('value' in descriptor) descriptor.writable = true;
Object.defineProperty(target, descriptor.key, descriptor);
}
}
return function (Constructor, protoProps, staticProps) {
if (protoProps) defineProperties(Constructor.prototype, protoProps);
if (staticProps) defineProperties(Constructor, staticProps);
return Constructor;
};
})();
function _classCallCheck(instance, Constructor) {
if (!(instance instanceof Constructor)) {
throw new TypeError('Cannot call a class as a function');
}
}
var Person = (function () {
function Person() {
var name = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : 'zhangsan';
var age = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : '18';
_classCallCheck(this, Person);
this.name = name;
this.age = age;
}
_createClass(
Person,
[
{
key: 'say',
value: function say() {
console.log('hello word');
},
},
{
key: 'drink',
value: function drink() {
console.log('drink');
},
},
],
[
{
key: 'eat',
value: function eat() {
console.log('eat');
},
},
]
);
return Person;
})();