• [翻译]扩展内置类


    扩展内置类

    javascript内置类比如数组,哈希和其他内置类等都是可扩展的。

    比如,这里的PowerArray就是从原生Array继承而来的

    // 给原生数组添加额外方法(还可以添加更多)
    class PowerArray extends Array {
        isEmpty() {
            return this.length === 0;
        }
    }

    let arr = new PowerArray(1251050);
    alert(arr.isEmpty()); // false

    let filteredArr = arr.filter(item => item >= 10);
    alert(filteredArr); // 10, 50
    alert(filteredArr.isEmpty()); // false

    请注意一个有趣的现象。内置方法,比如filter,map 和其他方法 - 都返回了继承类的新实例。这是由它们的constructor属性所导致的。

    在在上述例子中就是,

    arr.constructor === PowerArray;

    所以调用arr.filter()时, 会在方法内部为返回结果创建新数组,这个新数组确切地说是使用new PowerArray的方式而不是new Array的方式创建的。这很好,因为我们可以在返回结果上继续使用PowerArray的方法。

    甚至,我们可以定制这一行为。

    我们可以为这个类添加一个特殊的静态取值函数Symbol.species。它会返回 JavaScript 默默地用来在mapfilter等方法中创建新实例的构造函数。

    假如我们想要内置方法比如mapfilter中返回常规的数组,那么我们可以在Symbol.species返回内置数组Array,就像下面这样:

    class PowerArray extends Array {
        isEmpty() {
            return this.length === 0;
        }

        // 内置方法将使用下面函数的返回值作为构造函数
        static get [Symbol.species] {
            return Array
        }
    }

    let arr = new PowerArray(1251050);
    alert(arr.isEmpty()); // false

    // filter方法使用 arr.constructor[Symbol.species] 作为构造函数来创建返回的新数组
    let filteredArr = arr.filter(item => item >= 10);

    // filteredArray 的构造函数不是PowerArray, 而是Array
    alert(filteredArr.isEmpty()); // Error: filteredArr.isEmpty is not a function

    正如你所看到的,现在 .filter 返回了 Array 类型。因此继承的方法并没有进一步的传递下来。

    内置类中不存在静态继承

    内置对象都有自己的静态方法,比如Object.keysArray.isArray等。

    众所周知,内置类之间会彼此继承。比如,Array 继承自 Object

    一般来说,当一个类继承自另一个时,静态和常规方法都会被继承。

    所以,当Rabbit extends Animal,其结果是:

    1. 静态方法Rabbit.methods继承自Animal.methods,因为Rabbit.[[prototype]] = Animal
    2. 实例中的常规方法new Rabbit().methods也会继承,因为Rabbit.prototype.[[prototype]] = Animal.prototype

    这在 静态属性和静态方法 章节中已经仔细解释过了。

    但是,内置类除外。它们并不能在彼此之间继承静态属性和方法。

    比如,ArrayDate对象都继承自Object, 因此它们的实例拥有Object.prototype上的方法。但是Array.[[prototype]]并不指向Object。所以,存在Object.keys()方法,却并不存在Array.keys()Date.keys()方法。

    下图展示了DateObject的关系

    注意,DateObject之间并没有联系。ObjectDate两个类都是独立存在的。

    仅仅是,Date.prototype继承自Object.prototype

  • 相关阅读:
    Java正则表达式入门
    StringBuffer ,String,StringBuilder的区别
    JAVA的StringBuffer类
    容器vector的使用总结 容器stack(栈)
    c++网络通信(与服务器通信聊天)和c#网络通信
    C#与SQLite数据库
    我的vim配置文件
    在world中批量调整图片的大小
    C#判断文件及文件夹是否存在并创建(C#判断文件夹存在)
    C# Thread类的应用
  • 原文地址:https://www.cnblogs.com/rencoo/p/11902080.html
Copyright © 2020-2023  润新知