javaScript-你不知道的类
Posted 火腿肠烧烤大赛冠军
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了javaScript-你不知道的类相关的知识,希望对你有一定的参考价值。
类语法的定义
基础就是对原型的操作
声明和java差不多
class User {
constructor(name) {
this.name = name;
}
getName() {
return this.name;
}
}
let hd = new User("123");
console.log(hd.getName());
类的内部工作机制就是原型操作
类就是构造函数的语法糖
实质为操作prototype而已
对象属性的声明
constructor 内外都可以声明
class User {
site = "aaa";
constructor(name) {
this.name = name;
}
changeSite(value) {
this.site = value;
}
show() {
return `${this.site}:${this.name}`;
}
}
let hd = new User("bbb");
hd.changeSite("houdunren");
console.log(hd.show());
class声明的方法为不能遍历
在继承时候 可遍历默认设置为false
在class中默认为严格模式
(部分指向windows的指针会失效)
静态属性使用
静态属性就是指构造函数自己的属性(不默认给它构造出来的对象使用)
在类中使用:大家一起可以用这个属性:
class Request {
static host = "https://www.baidu.com";
api(url) {
return Request.host + `/${url}`;
}
}
let obj = new Request();
console.log(obj.api("article"));
原理:
在当前构造函数的_proto_上加一个新的属性以便访问:
User.__proto__.name = function(){};
利用静态方法构造:
class Member {
constructor(name, age, sex) {
this.name = name;
this.age = age;
this.sex = sex;
}
static create(...args) {
return new this(...args);
}
}
let xj = Member.create("SS", 19, "男");
console.log(xj);
在类中使用访问器
设置就触发set、访问就触发get
class Requset {
constructor(host) {
this.data = {};
this.host = host;
}
set host(url) {
if (!/^https?:\\/\\//i.test(url)) {
throw new Error("地址错误");
}
this.data.host = url;
}
get host() {
return this.data["host"];
}
}
let ss = new Requset("https://sss.com");
// hd.host = "https://sss.com";
// hd.setUrl("https://sss.com");
console.log(ss);
使用命名规则保护属性
class User {
//public
_url = "https://sss.com";
constructor(name) {
this.name = name;
}
set url(url) {
if (!/^https?:/i.test(url)) {
throw new Error("非常网址");
}
this._url = url;
}
}
let hd = new User("sss");
hd.name = "李四";
hd.url = "https://sss.com";
console.log(hd);
使用Symbol定义protected属性
const protecteds = Symbol();
class Common {
constructor() {
this[protecteds] = {};
this[protecteds].host = "https://sss.com";
}
set host(url) {
if (!/^https?:/i.test(url)) {
throw new Error("非常网址");
}
this[protecteds].host = url;
}
get host() {
return this[protecteds].host;
}
}
class User extends Common {
constructor(name) {
super();
this[protecteds].name = name;
}
get name() {
return this[protecteds].name;
}
}
let hd = new User("sss");
hd.host = "https://www.sss.com";
// console.log(hd[Symbol()]);
console.log(hd);
console.log(hd.host);
使用WeakMap保护属性
const protecteds = new WeakMap();
class Comment {
constructor() {
protecteds.set(this, {
host: '"https://ssssss.com"'
});
}
set host(url) {
if (!/^https?:/i.test(url)) {
throw new Error("ssssss");
}
protecteds.set(this, { ...protecteds.get(this), url });
}
get host() {
return protecteds.get(this)["host"];
}
}
let a = new Comment();
console.log(a);
a.host = 'https://sssssssssssssssssssssssss.com'
console.log(a.host);
class User extends Comment {
constructor(name) {
super();
this.name = name;
}
set name(name) {
console.log(protecteds);
// console.log(...protecteds.get(this));
protecteds.set(this, { ...protecteds.get(this), name });
}
get name() {
return protecteds.get(this)["name"];
}
}
let ss = new User("ssssssss");
ss.name = "ssssssssssssss";
console.log(ss.name);
ss.name='123123123'
console.log();
console.log(ss.name);
pricate私有属性使用
私有属性与私有方法
class Common {
#check = () => {
if (this.name.length < 5) {
throw new Error("名子长度不能小于五位");
}
return true;
};
}
class User {
//public protected private
#host = "https://sssssssssssss.com";
constructor(name) {
this.name = name;
this.#check(name);
}
set host(url) {
if (!/^https?:/i.test(url)) {
throw new Error("sssssssssss");
}
this.#host = url;
}
}
let ss = new User("ssss");
ss.host = "https://www.ssssssssssssss.com";
// hd.#check();
console.log(ss);
继承原理
方法在原型链上
属性在实例化对象上
其实就是原型链继承的语法糖
super原理
再次强调:
super就相当于this.proto
如果直接用的话还要考虑指针要用到call等
let ss = {
name: "ss.name",
show() {
// console.log(this);
console.log(this.name);
}
};
let aa = {
__proto__: ss,
name: "xj.name",
show() {
super.show();
this.__proto__.show.call(this);
}
};
aa.show();
以上两种show方法均可
在多继承中的super
多继承中只能用super
super中的this永远都是调用者的this 方法是借用的方法 就喊舒适
子类constructor中执行super、
子类中的构造函数一定要包含super且一定要在使用this之前(避免父级优先级高于子类)-不写的话系统会默认给你写一个
原因:
从原型链的角度来考虑,由于父类的赋值是在父类中使用的所以要使用父类的赋值且把this传过去,super实现了这一语法糖
使用super访问父类方法
super后什么都不跟:直接执行父类constructor
super后跟一些方法:执行父类方法
class Common {
sum() {
return this.data.reduce((t, c) => t + c.price, 0);
}
}
class Controller extends Common { }
class Lesson extends Controller {
constructor(data) {
super();
this.data = data;
}
info() {
return {
totalPrice: super.sum(),
data: this.data
};
}
}
let data = [
{ name: "js", price: 100 },
{ name: "mysql", price: 212 },
{ name: "vue.js", price: 98 }
];
let ss = new Lesson(data);
console.log(ss.info());
方法的重写
class Common {
sum() {
return this.data.reduce((t, c) => t + c.price, 0);
}
getByKey(key) {
return this.data.filter(item => item.name.includes(key));
}
}
class Controller extends Common { }
class Lesson extends Controller {
constructor(data) {
super();
this.data = data;
}
info() {
return {
totalPrice: super.sum(),
data: this.data
};
}
getByKey(key) {
return super.getByKey(key).map(item => item.name);
}
}
let data = [
{ name: "js", price: 100 },
{ name: "mysql", price: 212 },
{ name: "vue.js", price: 98 }
];
let ss = new Lesson(data);
console.log(ss.getByKey("js"));
静态继承原理
构造函数也是类 直接往里面压入方法就是静态
class用关键字实现了这一功能
class User {
static site = "sss.com";
static show() {
console.log("user.static show");
}
}
class Admin extends User { }
instanceof的实现
function checkPrototype(obj, constructor) {
if (!obj.__proto__) return false;
if (obj.__proto__ == constructor.prototype) return true;
return checkPrototype(obj.__proto__, constructor);
}
isPrototypeOf检测继承关系
与instanceof相反:
以原型对象作为主角
CLASS使用 mixin混合模式使用技巧
与正常原型链一样,原型链也是对象直接object.assign就好
let Tool = {
max(key) {
return this.data.sort((a, b) => b[key] - a[key])[0];
}
};
let Arr = {
count(key) {
return this.data.reduce((t, c) => t + c[key], 0);
}
};
class Lesson {
constructor(lessons) {
this.lessons = lessons;
}
get data() {
return this.lessons;
}
}
const data = [
{ name: "js", price: 100, click: 188 },
{ name: "mysql", price: 212, click: 34 },
{ name: "vue.js", price: 98, click: 89 }
];
Object.assign(Lesson.prototype, Tool, Arr);
以上是关于javaScript-你不知道的类的主要内容,如果未能解决你的问题,请参考以下文章