一.类
(1).基础
class Person{}
log(new Person());//Person{}
log(typeof Person);function
class Person{
constructor(name = "zhangsan",age = "18"){
//私有属性
this.name = name;
this.age = age;
}
//公有属性
say(){
log(`my name is ${this.name}`)
}
}
console.log(new Person());
Person{
age:"18"
name:"zhangsan"
__proto__
constructor: class Person
say: f say()
}
class Person{
constructor(name = "zhangsan",age="18"){
this.name = name;
this.age = age;
}
say(){
console.log(`my name is ${this.name},my age is ${this.age}`)
}
eat(){
console.log('I can eat')
}
drink(){
console.log('I can drink')
}
}
new Person().eat();//I can eat
new Person().drink();//I can drink
Object.assign(Person.prototype,{
eat: function(){
console.log('I can eat')
},
drink:function(){
console.log('I can drink')
}
},)
拓展出来的对象是可以枚举的
log(Object.keys(Person.prototype))//["say","eat","drink"]
class Person{
constructor(){
}
}
log(new Person() instanceof Person);//true和之前一样,继承于Person
class Person{
constructor(){
return Object.create(null)
}
}
log(new Person() instanceof Person);
如果返回新的对象则false
(2).特殊写法
let Person = class{
say(){
console.log(1)
}
}
new Person.say()
执行方式必需为New 像直接立即执行函数就会报错,但是下面通过new就可以
let person = new class{
say(){
log(1)
}
}()
person.say();//1
let person = new class{
constructor(name = 'zhangsan',age = '18'){
this.name = name;
this.age = age;
}
say(){
log(1)
}
}('lisi','19')
(3).拓展
console.log(new Person());
class Person{
}
es7中你在外层直接申明属性,其实系统就是默认通过constror构建的私有属性
class Person{
a = 1
等价于
constructor(){
this.a = 1
}
}
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());//1
console.log(new Person().eat())//报错
通过压缩后,方法名会变更,而普通的函数可以用.去访问,而symbol由于.是访问不到原本变量名的,所以就实现了公有函数的私有化
class Person{
constructor(name,age){
this.age = age;
this.name = name;
}
say(baz){
children.call(this,baz)
}
}
function children(baz){
return this.bar = baz
}
class Person{
static a(){
log(1)
}
}
console.log(Person.a)//打印1
class Person{
static name1 = 'cc';
}
var per = new Person()
console.log(Person.name1);//打印cc
class Person{
get a(){
log(1)
}
set b(value){
log(2)
}
}
var person = new Person();
person.a; //1
person.b = 3;//2
(4).总结
二.继承
(1).基本
class Parent{
constructor(name = 'zhangsan'){
this.name = name;
}
say(){
console.log(1)
}
}
class Child extends Parent{
constructor(age = '19')
this.age = age;
}
}
console.log(new Child().age)
必需指定super,在派生类里面this的指向并不是当前对象
这时候可以通过super把父级的整个实例继承过来,才能用父类的this
class Child extends Parent{
constructor(age = '19')
super('lisi');
this.age = age;
}
}
console.log(new Child())
child{
age:"19"
name:"lisi"
}
(2).super方法
let proto = {
y: 20,
z: 40
}
let obj = {
x: 10,
foo(){
log(super.y)
}
}
Object.setPrototypeOf(obj,proto);
obj.foo();20
三.类的实现
(1).实现方式
//2.只能通过new实例化调用属性或方法 :通过传入当前作用域 和本函数 来通过instanceof来判断
//4.公有方法不可枚举: 通过传入得第二个参数设置属性描述符
//5.默认constructor :通过difineProperty实现
(2).class源码
"use strict"
function _classCallBack(instance,Constructor){
if(!(instance instanceof Constructor)){
throw new TypeError('Cannot call a class as a function')
}
}
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;
}
}
}();
var Person = function(){
function Person(){
var name = arguments[0] !== undefined && arguments.length > 1 ? arguments[0]:'xx';
var test = arguments[0] !== undefined && arguments.length > 1 ? arguments[1]:'dd';
_classCallBack(this,Person)
this.name = name
this.age = age
}
_createClass(Person,[{
key:"test",
value:function test(){
console.log('hahahahahha');
}
}],[{
key:'fuck',
value:function fuck(){
console.log(2);
}
}])
return Person;
// }();
四.类的修饰
(1).基本
class Person{
@readOnly()
say(){
console.log('ad is show');
}
}
function readOnly(target,name,descriptctor){
三个参数打印如下
类本体,指定属性名称,属性描述符
}
(2).转译
index页面引用bundle.js编译后的,这样就可以通过浏览器语法编译了
(3).埋点操作
let log = (type) =>{
return function(target,name,descriptor){
let src_methiod = descriptor.value;
descriptor.value = (...arg)=>{
src_methiod.apply(target,arg);
console.log(type);
}
}
}
class Person{
@log('show')
say(){
console.log('ad is show');
}
@log('click')
click(){
console.log('ad is click');
}
}
ad is show
show
ad is click
click
本文围绕ES6/ES7中JavaScript的类与继承展开。介绍了类的基础、特殊写法、拓展及总结,如暂时性死区、公有属性不可枚举等;阐述了继承的基本情况和super方法的作用;说明了类的实现方式和源码;还提及类的修饰,包括基本用法、转译步骤和埋点操作,遵循开放封闭原则。




2万+

被折叠的 条评论
为什么被折叠?



