Javascript 什么';这两种对象构造方法的区别是什么?
在编写一些代码时,我想做如下工作:Javascript 什么';这两种对象构造方法的区别是什么?,javascript,Javascript,在编写一些代码时,我想做如下工作: var text = Text('hello').trim().bold(); 所以,我做了以下几点 function Text(text) { this.value = text; this.trim = function() { /* trim code */ return Text(this.value); } this.bold = function() { /* bold code */ return Text(this.
var text = Text('hello').trim().bold();
所以,我做了以下几点
function Text(text) {
this.value = text;
this.trim = function() { /* trim code */ return Text(this.value); }
this.bold = function() { /* bold code */ return Text(this.value); }
return this;
}
这与下面的有什么不同吗
function Text(text) {
this.value = text;
this.trim = function() { /* trim code */ return new Text(this.value); }
this.bold = function() { /* bold code */ return new Text(this.value); }
}
并使用以下命令调用它
var text = new Text('hello').trim().bold();
或者它们实际上是等效的?我认为最好将此方法添加到标准Javascript字符串对象中,例如,当使用
new
调用时,构造函数隐式返回此
如果调用这些函数时不使用
new
,则第一个函数将返回全局上下文,而第二个函数将返回undefined
,这里的基本点是,这一行对于Text
的给定实现都是错误的:
var text = Text('hello').trim().bold();
…因为在Text
中,您正在this
上存储属性,但是当您以上面的方式调用Text
时,this
要么是全局对象(在松散模式下),要么是未定义的
(在严格模式下)。在松散模式下,您正在创建/覆盖名为value
、trim
、和bold
(因为您正在向全局对象写入属性,而全局对象的所有属性都是全局的)的globals;在严格模式下,您会得到一个异常,因为您无法将属性分配给未定义的
相反,你必须这样称呼它:
var text = new Text('hello').trim().bold();
// Note ---^^^
这应该可以回答您关于修剪
和粗体
的问题(例如,您需要第二个版本,即使用新
的版本)。另外,会返回此信息如果使用new
调用函数,则末尾的code>是不必要的
如果您想在不使用new
的情况下调用Text
,您可以,但实现必须不同-它必须创建它返回的对象,因为new
不会为它这样做:
function makeText(text) {
var obj = {};
obj.value = text;
obj.trim = function() { /* trim code */ return makeText(this.value); };
obj.bold = function() { /* bold code */ return makeText(this.value); };
return obj;
}
或者更简洁地说:
function makeText(text) {
return {
value: text,
trim: function() { /* trim code */ return makeText(this.value); },
bold: function() { /* bold code */ return makeText(this.value); }
};
}
注:我更改了名称,使其不再以大写字母开头;在JavaScript中,压倒性的惯例是以大写字母开头的函数是构造函数(在正常情况下,通过new
调用函数)。如果要实现后续调用的链接,则需要执行以下操作
function Text(text) {
this.value = text;
this.trim = function() { /* trim code */ return this; }
this.bold = function() { /* bold code */ return this; }
}
话虽如此,我还是想解释一下你的两个代码都在做什么
在您的第一个代码中。您正在调用构造函数而不使用new关键字,这将使默认上下文作为this
传递,这是一个窗口。因此,有效地在窗口上添加属性,调用的第二个方法.bold()
将在窗口上,因为您从.trim()
返回相同的对象
在第二个代码中,当您说newtext
时,实际上是在创建新对象,因此您正在丢失以前调用.trim()
方法的对象,并且第二次调用。bold
是在从返回的新对象上进行的。trim()
有一个根本性的区别。第一种方法是使用共享实例
function Text(text) {
this.value = text;
this.trim = function() { /* trim code */ return Text(this.value); }
this.bold = function() { /* bold code */ return Text(this.value); }
return this;
}
var text = Text('hello').trim().bold();
var text2 = Text('hello2').trim().bold();
alert(text.value);
这将输出“hello2”()
而:
function Text(text) {
this.value = text;
this.trim = function() { /* trim code */ return new Text(this.value); }
this.bold = function() { /* bold code */ return new Text(this.value); }
}
var text = new Text('hello').trim().bold();
var text2 = new Text('hello2').trim().bold();
alert(text.value);
将按预期输出“hello”。()
我想你真正想做的是:()
函数文本(文本){
this.value=文本;
this.duplicate=函数(){
this.value=this.value+this.value;
归还这个;
}
this.bold=函数(){
this.value=“”+this.value+”;
归还这个;
}
}
var text=新文本('hello').duplicate().bold();
var text2=新文本('hello2').duplicate().bold();
警报(text.value);
谢谢,我意识到我本来可以做到的。不过,这只是我所问的概念的一个例子。谢谢。我将它插入一个测试中,您对共享实例的看法是正确的。我在我的答案中添加了小提琴,以及您可能需要的解决问题的方法。感谢您花时间将其打印出来。在链接调用时,只返回this
overmakeText(this.value)是否更好代码>?@Frank:这里没有一般的答案,这取决于该方法是否是一个mutator方法(修改您调用它的对象的方法)。让我们以您的bold
为例,假设它将
放在文本周围(我知道,但这只是一个示例)。如果bold
直接修改this.value
(this.value=''+this.value+'';
),则它是一个变体,返回一个新的文本
对象可能没有意义。但是如果bold
保持原始实例的状态不变,那么您需要类似returnmaketext(“”+this.value+“”)的内容代码>好的,这是有道理的。非常感谢你的帮助!我不知道你为什么被否决了。似乎是一个完全正确的答案。谢谢。实际上我犯了一个错误,然后把它删掉了。但在编辑后,downvoter没有出现。。。
function Text(text) {
this.value = text;
this.duplicate = function() {
this.value = this.value+this.value;
return this;
}
this.bold = function() {
this.value = "<b>"+this.value+"</b>";
return this;
}
}
var text = new Text('hello').duplicate().bold();
var text2 = new Text('hello2').duplicate().bold();
alert(text.value);