为什么Typescript Intellisense没有显示对象扩展?

时间:2016-09-25 12:11:31

标签: visual-studio typescript visual-studio-2015

考虑使用此代码扩展Object类型:

interface Object  
{
    doSomething() : void;
}

Object.prototype.doSomething = function ()
{
    //do something
}

有了这个,下面两个编译:

(this as Object).doSomething();
this.doSomething();

但是:当我输入第一行时,Intellisense知道doSomething方法并将其显示在自动完成列表中。当我输入第二行时,它没有。

我对此感到困惑,因为并非每个变量都来自Object,因此Visual Studio为什么不在方法列表中显示额外的方法?

更新

即使Intellisense没有提供该方法,但当我手动输入时, 似乎识别出来了:

enter image description here

有什么可以解释的?!

1 个答案:

答案 0 :(得分:3)

  

...因为并非每个变量都来自Object

不,有两个原因:

1。 JavaScript(和TypeScript)具有对象和基元。 this可以保存任何值(在严格模式下),因此可以是原语:



"use strict";
foo();
foo.call(42);

function foo() {
  console.log(typeof this);
}




Here's that same code in the TypeScript playground.在这两种情况下(此处和那里),上述输出:

undefined
number

......两者都不是来自Object

2。并非所有对象都继承自Object.prototype



var obj = Object.create(null);
console.log(typeof obj.toString); // undefined
console.log("toString" in obj);   // false




如果对象的原型链植根于一个根本没有原型的对象(如上面的obj),它就不具备{{Object.prototype的特征。 1}}。

根据您的评论:

  

我认为甚至像number这样的原始人也会继承Object。如果number没有,number.ToString()如何运作?

原语是原始的,不会从Object继承。但是你很正确,他们中的大多数似乎,因为numberstringbooleansymbol都有对象(从Number派生的StringBooleanSymbolObject)。但并非所有原语都可以:undefinednull如果您尝试将它们视为对象,则会抛出TypeError。 (是的,null is a primitive即使typeof null"object"。)

对于其中四个具有对象对应物的人,当你使用像这样的对象这样的原语时:

var a = 42;
console.log(a.toString());

...通过规范中的抽​​象ToObject operation从原语创建并初始化适当类型的对象,并调用生成的对象的方法;然后,除非该方法返回该对象引用(我不认为任何内置方法,但你可以添加一个),临时对象立即有资格进行垃圾回收。 (当然,JavaScript引擎会在toStringvalueOf等常见情况下优化此过程。)

你可以通过这样的方式告诉对象是暂时的:



var a = 42;
console.log(a);         // 42
console.log(typeof a);  // "number"
a.foo = "bar";          // temp object created and released
console.log(a.foo);     // undefined, the object wasn't assigned back to `a`

var b = new Number(42);
console.log(b);         // (See below)
console.log(typeof b);  // "object"
b.foo = "bar";          // since `b` refers to an object, the property...
console.log(b.foo);     // ... is retained: "bar"




(重新"见下文":在Stack Snippets控制台中,您看到{};在Chrome的真实控制台中,您看到的内容取决于您是否拥有控制台打开:如果你不打开,稍后再打开它会显示42;如果你这样做,你会看到▶ Number {[[PrimitiveValue]]: 42}你可以用▶扩展。)

  

number是否实施了自己的toString方法,与Object无关?

Yes,但对于原语以及与Object的奇怪关系,这并不重要。

所以要收集:

  • this可能包含一个原语,虽然某些原语可以像对象一样对待,但并非所有原语都可以。
  • this可能包含对象的对象引用,该对象不是从Object派生的(也就是说,在其原型链中没有Object.prototype )。

JavaScript是IntelliSense的一种硬语言。 : - )