ES6~ES12 类的混入 mixin 多态 letconstvar等

ES6~ES12 类的混入 mixin 多态 letconstvar等,第1张

1、混入 mixin

JavaScript的类只支持单继承: 也就是只能有一个父类,我们在开发中如果需要添加多个类的功能,可以使用混入(mixin)

class Student {
  styding() {
    console.log("styding");
  }
}
class Runner {
  running() {
    console.log("running");
  }
}

class Eater {
  eating() {
    console.log("eating");
  }
}
// 实现混入:新建一个函数(开发中不常见): 因为如果想要混入一些属性个传入构造函数新的参数,就不太行了
function mixinRunner(BaseClass) {
  class NewClass extends BaseClass {
    running() {
      console.log("running");
    }
  }
  return NewClass;
}

function mixinEater(BaseClass) {
  return class extends BaseClass {
    eating() {
      console.log("eating~");
    }
  };
}

// 在JS类中只能有一个父类:单继承
// class Student extends Person {}

// 使用
// var NewStudent = mixinRunner(Student);
// var ns = new NewStudent();
// ns.running()
// 继续扩展上面的功能
var NewStudent = mixinEater(mixinRunner(Student));
var ns = new NewStudent();
ns.eating();
2、多态
// 传统面向对象多态三个前提:
// 1.必须有继承(是多态的前提)
// 2.必须有重写(子类重写父类的方法)
// 3.父类引用指向创建出来的子类对象

class Shape {
  getArea() {}
}

class Rectangle extends Shape {
  getArea() {
    return 100;
  }
}

class Circle extends Shape {
  getArea() {
    return 200;
  }
}

var r = new Rectangle();
var c = new Circle();
// 多态:当对不同的数据类型执行同一个 *** 作时,如果表现出来的行为(形态)不一样,那么就是多态的体现
function calcArea(shape: Shape) {
  console.log(shape.getArea());
}

calcArea(r);
calcArea(c);

// js相对宽松一点
// 下面这个也是多态的体现
function sum(m, n) {
  return m + n;
}
sum(20, 30);
sum("20", "30");
3、字面量增强的写法
var name = "chen";
var age = 23;

var obj = {
  name,
  age,

  foo: function () {},
  bar() {},
  // 计算属性名
  [name + 123]: 'hahaha'
};
console.log(obj);
// {
//   name: 'chen',
//   age: 23,
//   foo: [Function: foo],
//   bar: [Function: bar],
//   chen123: 'hahaha'
// }
4、let-const-var

window与var声明的保持关联, window就是早期的 go

区别:
1.作用域提升的区别
2.let const 不允许重复声明变量
3.let、const是不会添加到window对象里面的
4.let、const、var 块级作用域

// 1、es5中没有块级作用域
// 快代码block code
// {
//   // 声明一个变量
//   var foo = "foo";
// }
// console.log(foo);//foo

// 2、在es5中只有两个东西会形成作用域
// a. 全局作用域
// b. 函数作用域
// function foo2(){
//   var foo = "foo";
// }

// console.log(foo);



// es6的代码块级作用域
// 对let/const/function/class声明的类型是有效的
{
  let foo = "foo";
  function demo() {
    console.log("demo function");
  }
  class Person {}
}
// console.log(foo);//报错
demo(); //可以打印,不同浏览器有不同的实现,为了兼容以前的代码,让function是没有块级作用域的
// var p = new Person(); //报错

// 注: if/switch/for写出来的语句,作用域,其实是块作用域
if (true) {
  var foo = "foo";
  let bar = "bar";
}
console.log(foo); //foo, 可以访问
// console.log(bar);// 报错

5、暂时性死区
var foo = "foo";

if (true) {
  console.log(foo); // 报错, 无法访问,暂时性死区

  let foo = "abc";
}
6、Symbol的基本使用

// es6之前,对象的属性名key
// var obj = {
//   name: "chen",
//   age: 23,
// };

// obj["name"] = "liu";
// console.log(obj); //{ name: 'liu', age: 23 }

// 1、es6中的symbol的使用
const s1 = Symbol();
const s2 = Symbol();
console.log(s1, s2, s1 === s2); //Symbol() Symbol() false

// 2、es10中,Symbol还有一个描述
const s3 = Symbol("aaa");
console.log(s3.description);

// 3、Symbol值作为key, 在定义对象字面量时使用
const obj = {
  [s1]: "abc",
  [s2]: "cba",
};
console.log(obj);

// 4、新增属性
obj[s3] = "aaa";

// 5、Object.defineProperty方式
const s4 = Symbol();
Object.defineProperty(obj, s4, {
  enumerable: true,
  configurable: true,
  writable: true,
  value: "bbb",
});

// 注意: 不能通过.语法来获取
console.log(obj.s1); //undefined
console.log(obj[s1]); //abc

// 6、使用Symbol作为key的属性名,在遍历/Object.keys()等中是获取不到这些Symbol的,
console.log(Object.keys(obj));
console.log(Object.getOwnPropertyNames(obj));
console.log(Object.getOwnPropertySymbols(obj));

// 遍历所有Symbol中的key
const keys = Object.getOwnPropertySymbols(obj);
for (const key of keys) {
  console.log(obj[key]);
}

// 7、Symbol.for(key)
const sa = Symbol.for("aaa");
const sb = Symbol.for("aaa");
console.log(sa === sb); //true

const key = Symbol.keyFor(sa);
console.log(key);
const sc = Symbol.for(key);
console.log(sa === sc); // true

7、weakSet 、Set
// 区别:
// 1、WeakSet只能存放对象类型,不能存放基本类型
// 2、WeakSet对元素的引用是弱引用,如果没有其他引用对某个对象进行引用,会被GC回收

// 这个对象是不会被销毁的
// let obj = {
//   name: "chen",
//   friend: {
//     name: "john",
//   },
// };
let obj = {
  name: "chen",
};
const weakSet = new WeakSet();
const set = new Set();
weakSet.add(obj);
set.add(obj); //强引用

8、Map

8.1、map的使用

const obj1 = { name: "chen" };
const obj2 = { name: "kobe" };

// 1、javascript中对象是不能使用对象来作为key的
const info = {
  [obj1]: "aaa",
  [obj1]: "ccc",
};

// 转成字符串'[object Object]', 两个key是一样的,后面的覆盖了前面的key
console.log(info); //{ '[object Object]': 'ccc' }

// 2、Map允许对象类型来作为key
const map = new Map();
map.set(obj1, "aaa");
map.set(obj2, "aaa");
map.set(1, "ccc");
console.log(map);

8.2、WeakMap的使用

const obj1 = {
  name: "chen",
  age: 23,
};
function obj1NameF1() {
  console.log("obj1NameF1被执行");
}
function obj1NameF2() {
  console.log("obj2NameF2被执行");
}
function obj1AgeF1() {
  console.log("obj1AgeF1被执行");
}
function obj1AgeF2() {
  console.log("obj1AgeF2被执行");
}
// vue3响应式原理
// 1.创建weakMap
const weakmap = new WeakMap();

// 2.收集obj1的数据结构
const obj1Map = new Map();
obj1Map.set("name", [obj1NameF1, obj1NameF2]);
obj1Map.set("age", [obj1AgeF1, obj1AgeF2]);
weakmap.set(obj1, obj1Map);

// 3.如果obj1.name发生改变,
obj1.name = "james";
const targetMap = weakmap.get(obj1);
const fns = targetMap.get("name");
fns.forEach((item) => item());

9、padStart、padEnd

const message = "hello world!";

const newMessage = message.padStart(15, "*");
console.log(newMessage); //***hello world!

// 身份z, 当然,可以使用replace
const card = "333555555555554444";
const firstThree = card.slice(0, 3);
console.log(firstThree);
// 截取后四位
const lastFour = card.slice(-4);
console.log(lastFour);
const final = firstThree + lastFour.padStart(card.length - 3, "*");
console.log(final); //**************4444

10、flatMap

const messages = ["hello world", "hello lyh", "my name is fuyi"];

const words = messages.flatMap((item) => {
  return item.split(" ");
});
console.log(words);
// [
//   'hello', 'world',
//   'hello', 'lyh',
//   'my',    'name',
//   'is',    'fuyi'
// ]

11、大数字bigInt的使用

// es11之前
const maxInt = Number.MAX_SAFE_INTEGER;
console.log(maxInt); //9007199254740991
console.log(maxInt + 1); //9007199254740992
console.log(maxInt + 2); //9007199254740992, 表示错误了

// es11之后: Bigint
const big = 9007199254740991n;
console.log(big + 19n); // 9007199254741010n

const num = 100;
console.log(big + BigInt(num));//9007199254741091n

// 大转小
const smallsum = Number(big);
console.log(smallsum);//9007199254740991

12、可选链

const info = {
  name: "chen123",
};
// 不会因为某个变量为undefined报错
// console.log(info.friend.name); // 报错
console.log(info?.friend?.name);//undefined

13、FinalizationRegistry 对象回收之前执行一些东西

const finalRegistry = new FinalizationRegistry((value) => {
  console.log("注册对象,某个对象呗销毁" + value);
});

let obj = {
  name: "chen1",
};
let obj1 = {
  name: "chen1",
};
// 需要在浏览器查看
finalRegistry.register(obj, 'obj');
finalRegistry.register(obj1, 'ifo');
obj = null;
obj1 = null;

14、||= 和 ??=

// 1、 ||= 逻辑或赋值运算
let message = undefined;
// message = message || '空值';

message ||= "空值";
console.log(message); // 空值

// 2、&&= 逻辑与赋值运算,用得很少
// 3、??= 逻辑空赋值运算, 跟 ||=有区别,||=中如果是''/undefined,会是false
let message1 = 0; //这不是undefined和null
let message2 = "";
message1 ??= "空值";
console.log(message1);//0
console.log(message2);

欢迎分享,转载请注明来源:内存溢出

原文地址: http://outofmemory.cn/web/1297559.html

(0)
打赏 微信扫一扫 微信扫一扫 支付宝扫一扫 支付宝扫一扫
上一篇 2022-06-10
下一篇 2022-06-10

发表评论

登录后才能评论

评论列表(0条)

保存