我正在讨论关于强类型和静态类型语言的基本论点。另一个辩论者是纯粹的javascript爱好者。虽然我喜欢使用c#和javascript。关于TypeScript的讨论及其如何比纯js更好的对话产生了对话,因为它是强类型的。 (主观已经)。因此,我向他提供了一个论点,即TypeScript在尝试使用以下示例时已经失败了。
class Greeter {
greeting: string;
constructor(message: string) {
this.greeting = message;
}
greet() {
return "Hello, " + this.greeting;
}
}
var greeter = new Greeter("world");
var greetWorld = greeter.greet;
alert(greetWorld()); //undefined, unexpected for strongly typed languages
我已经说过这是JS的预期。事实上,我喜欢这个。这就是为什么它是动态类型的语言是如此强大。但是,这个'这个'关键字只不过是JS中的一个属性,为什么TypeScript只是一个额外的层,增加了混乱并使其变得更好。
"创建函数时,会创建一个名为this的关键字(在幕后),该关键字链接到函数所在的对象。"(JS)。
那么这真的只是函数/对象的属性。强类型的定义:"每种类型的数据(例如整数,字符,十六进制,压缩十进制等)都预定义为编程语言的一部分,并且必须使用其中一种数据类型来描述为给定程序定义的所有常量或变量。&# 34;所以数据类型函数/对象是分开的,关键字" ONE"数据类型。
我似乎无法把争论推回家。事实上,我甚至可能是错的。但是对我来说,上面的问题是运行时类型错误,它们不是greeting
,即使它应该是预期的,如果' this'关键字真正受编程语言的束缚。
我错过了什么吗?
答案 0 :(得分:1)
在JavaScript中,关键字this
是指当前 调用上下文 ,而不是 当前实例 在C#中。
以下几行:
var greetWorld = greeter.greet;
greetWorld(); //returns "Hello, " + Window.greeting
您使用greetWorld()
上下文呼叫Window
,因此this
将引用Windows
对象。
如果您想模拟C#行为,您必须绑定您的欢迎对象上下文到该函数:
var greetWorld = greeter.greet.bind(greeter);
greetWorld(); //returns "Hello, " + greeter.greeting
可替换地:
var greetWorld = greeter.greet;
greetWorld.bind(greeter)();
答案 1 :(得分:0)
在C#中,this关键字在任何类方法中都可用,并引用用于调用该方法的当前对象。当我第一次开始编写JavaScript时,我认为它会是相同的,但很快发现我错了。这在JavaScript中有不同的行为。
查看此Link
答案 2 :(得分:0)
在 JS 中,所有对象都是引用类型,而函数是对象。这意味着当你在另一个对象中分配一个对象的方法(一个函数定义)时,最初定义的方法被调用(它不会被克隆到新对象中)。这也意味着,我们需要根据调用它的人来区分驻留在方法中的 this
。
var o = { name: "A"
, sing: function(){console.log(this.name)}
},
p = { name: "B"
, sing: o.sing // we refer to o.sing and the this in o.sing should now become p
},
q = { name: "C"}; // does not even have a sing method
o.sing(); // <- A
p.sing(); // <- B
o.sing.call(q); // <- C -- the call function shifts the context of o.sing to q
因此,this
中的 o.call
会浮动到调用它的对象。