如何在下面的示例中使用JavaScript对象表示法(JSON)中的"this"关键字?
{
firstName: "Foo",
lastName: "Bar",
fullName: function () {
return this.firstName + " " + this.lastName;
}
}
Run Code Online (Sandbox Code Playgroud)
上面的代码既不适用于this关键字也不适用于它.这是为什么?唯一可行的解决方案是将JSON对象分配给变量并在代码中使用该变量.
是否有类似于"this"关键字的东西可以用来代替它?
欢迎任何建议.
编辑:如下面的评论中所述,它不是JSON而是"javascript object literal".谢谢你的提示.不过,我的问题仍然有效(对于javascript对象文字).
invalid:上面的代码按预期工作,因此fullName()返回"Foo Bar".
如果我理解的话,这实际上可能不是一个无效的问题(只是一个问得不好的错误,有一些错误),并且确实可能有点有趣。JSON错误用语是一个不幸的分散注意力的错误,但实际上,他在问如何动态地使一个属性等于其他属性的动态结果-即为什么不
x = {
a: "hello",
b: " ",
c: "world",
d: this.a + this.b + this.c
}
Run Code Online (Sandbox Code Playgroud)
导致
x.d === "hello world"
Run Code Online (Sandbox Code Playgroud)
?
相反,您发现“ this”是指那里的窗口。这向我们展示了“这”仅是从函数内部获得的,而不是我们可以依赖于该上下文之外的内在关系引用。我不得不承认,当我意识到这一点并开始研究这个问题时,一开始我感到有些惊讶,这似乎有点太明显了。
这就是为什么问问者使用函数来访问“ this”的原因。但是,我认为问题在于,您必须要调用一个函数,而他实际上要在其中调用文本。(不确定,我可能在那里推断出一点。)
有人会想只使用IIFE,但是那也不起作用:
x = {
a: "hello",
b: " ",
c: "world",
d: (function() { this.a + this.b + this.c })()
}
x.d === NaN // undefined + undefined + undefined
Run Code Online (Sandbox Code Playgroud)
发生的事情是,当我们调用IIFE时,我们创建了一个具有新的作用域this。
因为他说过“我们必须先将对象分配给变量,然后才能使用它”,所以我认为他找到了一种变通方法,您只需对其声明两次即可;如果您引用的是全局变量的属性,则第二次它可以工作(so x.a + x.b),并提供了错误的示例。
所有这一切都表明,词汇范围在这里超过了动态范围。我的最终希望是,我们最终可以用这个得到想要的东西:
x = {
a: "hello",
b: " ",
c: "world",
d: (function() { this.x.a + this.x.b + this.x.c })()
// or maybe:
e: (function() { this.x.a + this.x.b + this.x.c }).call(this)
}
Run Code Online (Sandbox Code Playgroud)
但是不,x直到在该函数调用之后才在词法范围内定义,并且对于e,“ this”仍然是window。因此,无法在Javascript中评估对象时访问同级属性。
整齐!
结果,为了实现预期的目标,需要两个单独的语句:
x = {
a: "hello",
b: " ",
c: "world"
}
x.d = x.a + x.b + x.c;
Run Code Online (Sandbox Code Playgroud)
除非您希望让xd动态响应这些值,而不是此时添加这些值的结果-否则您将只使用问题中的原始代码,并将其作为函数进行评估。
……
完成以上内容后,我就想起了一个我从未使用过的javascript功能:getter和setter。果然,他们完全完成了我们在这里寻找的目标:
var hello = {
a: "hello",
b: "world",
get test() {
return this.a + this.b
}
}
// undefined
hello.test
// "helloworld"
hello.a = 'stuff'
// "stuff"
hello.test
// "stuffworld"
Run Code Online (Sandbox Code Playgroud)
当然,这在计算上等效于调用hello.test()并仅使test为函数,如原始代码中那样。就JSON而言,此getter不能像函数一样被序列化(尽管我们确定这不是重点,我只是想清楚一点)。最后,我们真正获得的唯一东西就是省略括号的能力。
代码存在多个问题.比问题更基本的this是JSON甚至不能包含函数(请记住JSON是由Javascript以外的语言使用的!).它纯粹是一种数据传输系统.
并非所有可以作为Javascript对象一部分的对象都可以在JSON中序列化.
“无论有没有 this 关键字,上面的代码都不起作用。为什么呢?”
尽管您谈论的是 JSON,但在阅读问题的文本时,听起来您要问的是this在使用对象字面量语法时如何在创建过程中引用对象。
原因this对您不起作用是因为它的值仅在函数内定义,而定义它的是函数的调用方式。
尽管您的代码确实提供了一个函数,但它无法在创建过程中引用该对象,因为直到文字语法之后才可以引用该对象。
“唯一可行的解决方案是将 JSON 对象分配给变量并在代码中使用该变量。”
没错,您不能使用this对象字面量语法来引用新对象,因此您需要在之后使用变量引用。
尽管作为文字语法的替代方案,您可以使用构造函数来创建对象。这样,您就不需要fullName在创建对象后使用变量来创建属性。
var obj = new function() {
this.firstName = "Foo";
this.lastName = "Bar";
this.fullName = this.firstName + " " + this.lastName;
};
Run Code Online (Sandbox Code Playgroud)
如果您将对象传递给函数,这也很有用。
my_func(new function() {
this.firstName = "Foo";
this.lastName = "Bar";
this.fullName = this.firstName + " " + this.lastName;
});
Run Code Online (Sandbox Code Playgroud)
所以你可以使用的原因this是,正如我上面所说,this它是在函数内定义的,并且是根据函数的调用方式来定义的。
在这里,我们通过使用 调用匿名函数作为构造函数new。这使得this引用正在构造的新对象,然后从构造函数自动返回该对象。
| 归档时间: |
|
| 查看次数: |
3110 次 |
| 最近记录: |