考虑使用此代码扩展Object类型:
interface Object
{
doSomething() : void;
}
Object.prototype.doSomething = function ()
{
//do something
}
有了这个,下面两个编译:
(this as Object).doSomething();
this.doSomething();
但是:当我输入第一行时,Intellisense知道doSomething
方法并将其显示在自动完成列表中。当我输入第二行时,它没有。
我对此感到困惑,因为并非每个变量都来自Object,因此Visual Studio为什么不在方法列表中显示额外的方法?
即使Intellisense没有提供该方法,但当我手动输入时, 似乎识别出来了:
有什么可以解释的?!
答案 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
继承。但是你很正确,他们中的大多数似乎,因为number
,string
,boolean
和symbol
都有对象(从Number
派生的String
,Boolean
,Symbol
和Object
)。但并非所有原语都可以:undefined
和null
如果您尝试将它们视为对象,则会抛出TypeError
。 (是的,null
is a primitive即使typeof null
是"object"
。)
对于其中四个具有对象对应物的人,当你使用像这样的对象这样的原语时:
var a = 42;
console.log(a.toString());
...通过规范中的抽象ToObject
operation从原语创建并初始化适当类型的对象,并调用生成的对象的方法;然后,除非该方法返回该对象引用(我不认为任何内置方法,但你可以添加一个),临时对象立即有资格进行垃圾回收。 (当然,JavaScript引擎会在toString
和valueOf
等常见情况下优化此过程。)
你可以通过这样的方式告诉对象是暂时的:
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的一种硬语言。 : - )