2016-09-25 75 views
1

考慮以下代碼擴展對象類型:爲什麼Typescript Intellisense不顯示對象擴展?

interface Object 
{ 
    doSomething() : void; 
} 

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

有了這個地方,下面的兩個編譯:

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

但是:當我打字的第一線,智能感知知道的doSomething方法並將其顯示在自動完成列表中。當我輸入第二行時,它不會。

我對此感到困惑,因爲並不是每個變量都派生自Object,因此Visual Studio爲什麼不在方法列表中顯示額外的方法?

更新:

即使智能感知不提供方法,確實似乎認識到它的時候,我手動鍵入它:

enter image description here

什麼能解釋?!

回答

2

...因爲沒有每個變量從對象

沒有得到,原因有二:

1的JavaScript(和打字稿)有兩個對象和原語。 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的功能。


從下面的評論:

我想即使像原語從Objectnumber繼承。如果number沒有,number.ToString()如何工作?

基元是基元,它不會從Object繼承。但是,你是對的,他們大部分似乎來,因爲numberstringbooleansymbol有對象同行(NumberStringBooleanSymbol),這也從Object派生。但並非所有原語都這樣做:undefinednull如果嘗試將它們當作對象來對待,則會拋出TypeError。 (是的,儘管null is a primitivetypeof 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是智能感知的硬語言。 :-)

+0

我甚至認爲像'數字'這樣的基本元素是從Object繼承的。如果'number'沒有,'number.ToString()'如何工作? 'number'是否實現了它自己的''toString'方法,與'Object'無關? –

+0

另外,你可以看看我的文章的更新?爲什麼Visual Studio會顯示該工具提示,如果對可能不是「Object」的變量執行操作並不安全? –

+0

@JoshuaFrank:查看答案的更新。 Re *「爲什麼Visual Studio會顯示工具提示,如果對可能不是」Object「的變量執行操作並不安全?「* JavaScript是智能感知的一種難懂的語言,我想當你開始在Object.prototype上鍵入某個東西的名字時,它會推遲你對代碼的理解(我懷疑你是否開始輸入一些只能在' String.prototype'或'Number.prototype',它可能也會推遲給你。) –