编写一些代码,我想做类似的事情:
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();
或者它们是否有效等效?
答案 0 :(得分:2)
这里的基本观点是,在给定Text
的实现 时,这一行是错误的:
var text = Text('hello').trim().bold();
...因为在Text
内this
存储了Text
的属性,但当您按照上面的方式调用this
时,undefined
或者是全局对象(在松散模式下)或value
(在严格模式下)。在松散模式下,您创建/覆盖名为trim
,bold
和undefined
的全局(因为您正在向全局对象写入属性,并且全局对象的所有属性都是全局的);在严格模式下,您会收到异常,因为您无法将属性分配给var text = new Text('hello').trim().bold();
// Note ---^^^
。
相反,你必须这样称呼它:
trim
这应该回答您关于bold
和new
的问题(例如,您需要第二个版本,即使用return this;
的版本)。另外,如果使用new
调用函数,则最后Text
是不必要的。
如果你想在不使用new
的情况下调用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); }
};
}
或更简洁:
new
注意我更改了名称,因此它不再以大写字母开头;在JavaScript中,压倒性的约定是以大写字母开头的函数是构造函数(在正常情况下通过{{1}}调用的函数)。
答案 1 :(得分:1)
存在根本区别。第一种方法是使用共享实例。
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'(jsfiddle)
while:
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'。 (jsfiddle)
我认为你真正打算做的是:(jsfiddle)
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);
答案 2 :(得分:0)
我认为最好将此方法添加到标准的Javascript String对象中,例如javascript: add method to string class
答案 3 :(得分:0)
当使用new
调用时没有区别,构造函数隐式返回this
。
如果在没有new
的情况下调用这些函数,则第一个函数将返回全局上下文,而第二个函数将返回undefined
。
答案 4 :(得分:0)
如果要为后续调用实现链接,您将要执行的操作如下所示。
function Text(text) {
this.value = text;
this.trim = function() { /* trim code */ return this; }
this.bold = function() { /* bold code */ return this; }
}
话虽如此,我想解释一下你的两个代码在做什么。
在你的第一个代码中。您正在调用没有new关键字的构造函数,这使得默认上下文传递为this
,即窗口。所以你有效地在窗口上添加属性,并且调用的第二个方法.bold()
将在窗口上,因为你从.trim()
返回相同的对象。
在您的第二个代码中,当您说new Text
时实际上是在创建新对象,因此您丢失了之前已调用.trim()
方法的对象,并且第二次调用.bold
是对从.trim()
返回的新对象进行了制作。