通用GUI编程技术——图形渲染实战(四十八)——Owner-Draw控件:让标准控件焕然一新
2026/6/7 12:00:08
作者:专注前端开发,分享JavaScript干货
更新时间:2026年4月
适合人群:有JS基础,想用现代语法写面向对象程序的开发者
ES6的class本质上还是基于原型的继承,只是提供了更清晰的语法。
会用class,才能看懂现代前端框架的源码。
// ES5写法(原型方式)functionPerson(name,age){this.name=name;this.age=age;}Person.prototype.sayHi=function(){console.log(`你好,我是${this.name},${this.age}岁`);};Person.prototype.introduce=function(){return`我叫${this.name}`;};// ES6 class写法(语法糖)classPerson{constructor(name,age){this.name=name;this.age=age;}sayHi(){console.log(`你好,我是${this.name},${this.age}岁`);}introduce(){return`我叫${this.name}`;}}// 使用constp=newPerson("张三",25);p.sayHi();// "你好,我是张三,25岁"console.log(p.introduce());// "我叫张三"classAnimal{constructor(name){this.name=name;}eat(){console.log(`${this.name}在吃东西`);}staticinfo(){console.log("这是一个动物类");}}classDogextendsAnimal{constructor(name,breed){super(name);// 调用父类构造函数(必须先调用)this.breed=breed;}bark(){console.log(`${this.name}在汪汪叫`);}// 方法重写eat(){super.eat();// 调用父类方法console.log("狗狗吃得很香");}}constdog=newDog("旺财","金毛");dog.eat();// "旺财在吃东西" + "狗狗吃得很香"dog.bark();// "旺财在汪汪叫"Dog.info();// "这是一个动物类"(静态方法)classMathUtils{// 静态方法:属于类,不属于实例staticadd(a,b){returna+b;}staticmultiply(a,b){returna*b;}// 实例方法sum(...numbers){returnnumbers.reduce((a,b)=>a+b,0);}}// 调用静态方法console.log(MathUtils.add(1,2));// 3console.log(MathUtils.multiply(3,4));// 12// 实例方法需要newconstutils=newMathUtils();console.log(utils.sum(1,2,3));// 6// 静态属性(ES2022+)classConfig{staticAPI_URL="https://api.example.com";staticTIMEOUT=5000;}console.log(Config.API_URL);// "https://api.example.com"classUser{// 公有字段(ES2022+)name="默认名字";// 私有字段(#开头,外部无法访问)#password="";#salary=0;constructor(name,password){this.name=name;this.#password=password;}// 公有方法changePassword(oldPwd,newPwd){if(this.#verifyPassword(oldPwd)){this.#password=newPwd;returntrue;}returnfalse;}// 私有方法#verifyPassword(pwd){returnpwd===this.#password;}// getter(访问器)getinfo(){return`用户:${this.name}`;}// settersetsalary(value){if(value>0){this.#salary=value;}}getsalary(){returnthis.#salary;}}constuser=newUser("张三","123456");console.log(user.name);// "张三"(公有)// console.log(user.#password); // ❌ SyntaxErroruser.salary=10000;console.log(user.salary);// 10000console.log(user.info);// "用户:张三"// JS没有原生的抽象类,可以用抛出错误模拟classShape{constructor(){if(new.target===Shape){thrownewError("不能实例化抽象类");}}// 抽象方法(子类必须实现)area(){thrownewError("子类必须实现area方法");}}classCircleextendsShape{constructor(radius){super();this.radius=radius;}area(){returnMath.PI*this.radius**2;}}// const s = new Shape(); // ❌ 报错constc=newCircle(5);console.log(c.area());// 78.5398...classProduct{static#nextId=1;constructor(name,price){this.id=Product.#nextId++;this.name=name;this.price=price;this.createdAt=newDate();}// 折扣价getdiscountedPrice(){returnthis.price*0.8;}// 格式化输出toString(){return`${this.name}(¥${this.price})`;}// 静态方法:批量创建staticcreateMany(products){returnproducts.map(p=>newProduct(p.name,p.price));}}// 使用constp1=newProduct("手机",3000);constp2=newProduct("耳机",500);console.log(p1.toString());// "手机(¥3000)"console.log(p1.discountedPrice);// 2400constproducts=Product.createMany([{name:"电脑",price:8000},{name:"平板",price:3000}]);console.log(products.length);// 2| 概念 | 说明 |
|---|---|
class | 定义类 |
constructor | 构造函数 |
extends | 继承 |
super() | 调用父类构造函数/方法 |
static | 静态方法/属性 |
#field | 私有字段(ES2022+) |
get/set | 访问器 |
Queue(队列),有enqueue、dequeue、front、size方法BankAccount类,私有字段#balance,提供deposit、withdraw、getBalance方法BaseModel基类有save、toJSON方法,UserModel继承它并添加fullName属性有问题欢迎评论区留言,大家一起讨论!
标签:JavaScript | class | 面向对象 | 继承 | 静态方法 | 私有属性 | 前端进阶