类、符号、对象和装饰器

本文深入探讨了JavaScript中的类,包括类的声明、属性和方法,如constructor、get和set关键字,以及静态方法的使用。同时,介绍了符号这一独特数据类型,强调其唯一性和在对象属性中的应用。此外,还讲解了如何通过Object.assign扩展对象和使用Object.setPrototypeOf改变对象的原型。最后,类的继承通过extends关键字和super关键字得以实现。
摘要由CSDN通过智能技术生成

类、符号、对象和装饰器

  1. 类的使用

    // 类的声明
    class Fruit {
    
    }
    // 等价于构造函数的声明
    function Fruit() {
        
    }
    

    注意: 类的声明与构造函数的声明不同点:类的声明没有作用域的提前

  2. 类的属性和方法

    • constructor方法:在类的实例化的时候,constructor方法会自动调用。并且实例化时的参数都会被constructor方法接收

      class Log {
          constructor(...args) {
              console.log(args);
          }
      }
      new Log('a', 'b', 'c') // ['a', 'b', 'c']
      
    • get 关键字

      class Counter {
          constructor(start) {
              this.count = start;
          }
          get next() {
              return this.count++
          }
      }
      // get next(){}:get关键词修饰的方法表示Counter实例会有一个next属性。访问该属性时会返回该方法的调用结果
      const counter = new Counter(2);
      console.log(counter.next);  // 2
      console.log(counter.next);  // 3
      console.log(counter.next);  // 4
      
    • set关键字:set关键词修饰的方法表示LocalStorage实例设置data属性时。设置该属性时会返回该方法的调用结果

      class LocalStorage {
          constructor(key) {
              this.key = key;
          }
          get data() {
              return JSON.parse(localStorage.getItem(this.key));
          }
          set data(data) {
              localStorage.setItem(this.key, JSON.stringify(data));
          }
      }
      const ls = new LocalStorage('groceries');
      ls.data = ['apples', 'bananas', 'grapes']
      console.log(ls.data); // ['apples', 'bananas', 'grapes']
      
    • static关键字

      • static关键字修饰的方法表示这个方式是静态方法。

      • static关键字可以修饰其他关键字。static get\static set 表示是静态属性存取器

      • 注意class 没有静态属性,只有静态方法。

        class MathHelper {
            static sum(...numbers) {
                return numbers.reduce((a,b) => a+b)
            }
        }
        console.log(MathHelper.sum(1,2,3,4,5));  // 15
        
  3. 类的继承: 关键字extends

    在constructor函数中调用super。可以实现继承父类。super中接受的参数传递到父类的构造函数或class中。父类中的方法也可以使用super.方法名的形式调用。

    class Fruit {
        constructor(type, weight) {
            this.type = type;
            this.weight = weight;
        }
        chop() {
            console.log(this.type, this.weight);
        }
    }
    class Banana extends Fruit {
        constructor() {
            super('banana', 105);
        }
        slice(){
            this.pieces = 12;
            super.chop();
            return 111
        }
    }
    const banana = new Banana();
    banana.slice() // banana 105
    

符号

符号是ES新增的基本值类型,是JS中第7中数据类型。

  1. 本地符号

    • 符号的使用

      const first = Symbol()
      
    • 创建符号时添加描述或说明

      const first = Symbol('my first')
      
    • 符号是独一无二的,即使创建符号时,两者的描述相同

      Symbol('my first') === Symbol('my first')   /// false
      
    • typeof 符号

      typeof Symbol('my first')  // symbol
      
    • 符号可以用作对象的属性名,访问符号对应的值时,必须使用同样的符号

      const weapon = Symbol('weapon');
      const character = {
          name: 'Penguin',
          [weapon]: 'umbrella',
      }
      console.log(Object.getOwnPropertySymbols(character[weapon]); // 'umbrella'
      
    • 传统方法【for…in,Object.keys,Object.getOwnPropertyNames】从对象读取属性名时,无法获取符号类型的属性名。

    • 获取对象中用作属性名的符号值:Object.getOwnPropertySymbols

      const weapon = Symbol('weapon');
      const character = {
          name: 'Penguin',
          [weapon]: 'umbrella',
      }
      console.log(Object.getOwnPropertySymbols(character)); // [Symbol(weapon)]
      
  2. 符号的实际用法

    JavaScript库可以用**符号**将对象映射到DOM元素上。之前的方法:在DOM元素上添加一个指向API的属性,但这样做会污染DOM元素。而且还要小心其他库使用这个属性,否则会导致冲突。

    使用**符号**的好处是符号是独一无二的,不用担心污染DOM元素,且符号是独一无二的,不用担心与其它库产生冲突。

    // 如果el元素存在日历API,则返回。如果不存在,则给el元素赋予日历API
    function createCalendar(el) {
        if(cache in el) { // 检测Symbol值cache是否存在于el元素中
            return el[cache] // 直接使用cache,避免重新实例化
        }
        const api = el[cache] = {
            // 在这里编写日历API
        }
        return api
    }
    

对象的内置改进

  1. 使用Object.assign扩展对象:使用方式为Object.assign(target,…source);每个source都会将自己本身的值复制到target中。为了不影响target原对象,一般都会设置target为{}。因此Object.assign的使用方式为

    Object.assign({}, source1, source2,[...source3]);
    
  2. Object。setProtorypeOf,设置一个对象的原型

    const baseCat = {type: 'cat', legs: 4};
    const cat = Object.create(baseCat); // cat: {},原型为baseCat。创建了一个空对象,并为其指定原型。
    cat.name = 'Milanesita';
    
    const baseCat = {type: 'cat', legs: 4};
    const cat = Object.setPrototypeOf({name: 'Milanesita'}, baseCat); // cat: {name: 'Milanesita'},原型为baseCat。创建了一个对象并为它赋值,并为其指定原型。
    
    // 两者的区别:create只能在创建新对象时为其指定原型。而setPrototypeOf可以改变任意对象的原型
    
  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值