Warning: file_get_contents(/data/phpspider/zhask/data//catemap/1/typescript/8.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Javascript/Typescript-使用新方法扩展日期对象_Javascript_Typescript - Fatal编程技术网

Javascript/Typescript-使用新方法扩展日期对象

Javascript/Typescript-使用新方法扩展日期对象,javascript,typescript,Javascript,Typescript,我试图扩展Date对象以添加有用的方法 ,这应该是有效的: Date.prototype.removeTime = () => { // some awesome code to remove the timestamp } 但是Typescript抱怨removeTime不是Date对象的已知属性。(技术上是正确的) 所以,我试过这个: Object.defineProperty(Date.prototype, "removeTime", { enumerable: f

我试图扩展Date对象以添加有用的方法

,这应该是有效的:

Date.prototype.removeTime = () => {
    // some awesome code to remove the timestamp
}
但是Typescript抱怨
removeTime
不是
Date
对象的已知属性。(技术上是正确的)

所以,我试过这个:

Object.defineProperty(Date.prototype, "removeTime", {
    enumerable: false,
    configurable: false,
    writable: false,
    value: function() {
        // Do some magic
        return null;
    }
});
但同样,在代码中使用它时:

类型“Date”上不存在属性“removeTime”

我不明白,因为我这样做是为了给数组原型添加一个方法,如下所示:

Object.defineProperty(Array.prototype, "unique", {
    enumerable: false,
    configurable: false,
    writable: false,
    value: function() {
        const a = this.concat();
        for (let i = 0; i < a.length; ++i) {
            for (let j = i + 1; j < a.length; ++j) {
                if (a[i] === a[j]) {
                    a.splice(j--, 1);
                }
            }
        }

        return a;
    }
});
interface Date {
    removeTime(): Date;
}

这里有两种不同的东西:

  • 添加运行时方法

  • 添加类型信息

  • 您所做的是添加运行时,但不是更新类型

    您可以添加如下类型信息:

    Object.defineProperty(Array.prototype, "unique", {
        enumerable: false,
        configurable: false,
        writable: false,
        value: function() {
            const a = this.concat();
            for (let i = 0; i < a.length; ++i) {
                for (let j = i + 1; j < a.length; ++j) {
                    if (a[i] === a[j]) {
                        a.splice(j--, 1);
                    }
                }
            }
    
            return a;
        }
    });
    
    interface Date {
        removeTime(): Date;
    }
    
    这将添加到
    日期
    界面

    (另外,在添加运行时方法时,请使用
    defineProperty
    方法,而不是使用带箭头的赋值函数。)

    下面是一个完整的示例:

    // Type
    interface Date {
        removeTime(): Date;
    }
    
    // Runtime
    Object.defineProperty(Date.prototype, "removeTime", {
        enumerable: false,   // This is the default, you can leave it off if you like
        configurable: true,  // Normally, method properties are configurable
        writable: true,      // Normally, method properties are writable
        value: function() {
            // Do some magic
            this.setHours(0, 0, 0, 0);
            return this;
        }
    });
    
    let d = new Date();
    console.log(d.toISOString());
    d.removeTime();
    console.log(d.toISOString());
    


    FWIW,关于扩展内置的几个注意事项:

    • 对于将用于您不直接控制的项目的代码(您正在编写的库代码将用于其他人的项目等),这通常不是最佳实践
    • 通常最佳做法是使用
      defineProperty
      定义不可枚举的属性(但通常是可写和可配置的)
    • 选择真正特定于您的项目的名称,这样,如果在规范的后面添加了内置项,您的名称就不太可能被使用。有可能在某个时候将
      removeTime
      方法添加到
      Date
      (虽然不太可能),但不可能使用
      myRemoveTime
      方法

    修改内置类型是一个非常糟糕的主意。你最好创建一个函数,它接受一个日期对象并返回一个新的日期对象。这是可行的,我可以在代码中使用它,Typescript不抱怨对我不起作用,我得到
    属性“unique”在类型“number[]”上不存在。
    。我不认为TS可以自动推断它(正确或完全),因为添加的属性不是静态的,而是在运行时的特定点添加的。“根据W3Schools,这应该可以”呃,这是W3Schools出错的另一个例子。从W3Schools的观点来看,Prototype是一个可用于所有JavaScript对象的全局对象构造函数。我不知道这是错误的还是有人试图扭曲文字使其正确。我想这个网站的名字很奇怪,听起来像是一个学生在接受考试。他们实际上不知道答案,但尽量使用模糊的措辞,不要直接说出错误的答案。为什么使用
    defineProperty
    方法更好?谢谢@JohnArcher-OP问题中带箭头函数的赋值有两个不同的错误:1。直接赋值创建可枚举属性。最好不要在原型对象上具有可枚举属性。使用
    defineProperty
    ,可以定义不可枚举的属性。2.箭头函数关闭
    this
    而不是通过调用方式设置
    this
    ,因此它不是方法的好选择,因为方法需要通过调用方式设置
    this
    。:-)