我正在尝试构建自己的对象并为其创建函数。我有以下对象,它从字符串中取出字母:
var Letters = function( word ) {
this.letters = word.split('');
this.length = this.letters.length;
return this;
};
然后我创建了一个函数,允许将字母/字符串添加到 Letters 对象的实例中:
Letters.prototype.addLetter = function(toAdd) {
for( var i = 0; i < this.length; i++ ) {
this.letters[i] += toAdd;
}
return this;
};
我的问题是,当我尝试创建一个自定义的每个函数,它迭代 Letters 对象的一个实例时,我应用了方法 addLetter 到 Letter 实例的当前迭代,我收到一条错误消息,指出当前迭代没有方法 addLetter 。
这是我到目前为止所写的:
Letters.prototype.each = function(callback){
for( var i = 0; i < this.length; i++ ) {
console.log(this.letters[i]);
this.push(callback.call(this, this.letters[i], i));
}
return this;
};
我想传递的测试如下:
var test = new Letters('dude');
console.log('test1', test); //should return d, u, d, e
var test2 = test.addLetter('x');
console.log('test2', test2); //should return dx, ux, dx, ex
var test3 = test.each(function(e){
e.addLetter('y');
});
console.log(test3);//should return dxy, uxy, dxy, exy
关于如何实现这一目标的任何想法? 感谢
这是代码的小提琴(打开控制台以查看结果):http://jsfiddle.net/cJqqb/
答案 0 :(得分:1)
这部分:
callback.call(this, this.letters[i], i)
...说要调用callback
函数将其this
设置为this
函数中的.each()
(Letter
的实例callback
),并传递this.letters[i]
两个参数i
和function(e){
e.addLetter('y');
}
- 也就是说,传递数组中的当前项及其索引。到目前为止一切都那么好,因为每种方法通常都是如此。但是在你的回调中:
e
... this.letters[i]
实际上是e
- 一个字符串。因此.addLetter()
没有var test3 = test.each(function(){
this.addLetter('y');
});
方法。如果您将回调更改为如下所示,那部分将在“不工作”的意义上“起作用”:
this.push()
虽然您因使用this
而收到错误,因为Letter
是.push()
的实例且没有push()
方法。如果你移除了.addLetter()
,你会得到一些“有用”的东西:http://jsfiddle.net/cJqqb/1/
但是你会发现在循环中调用现有的.addLetter()
是没有意义的,因为var test3 = test.each(function(v,i){
this.letters[i] += 'y';
});
本身有一个循环。你可以这样做来获得预期的输出:
for
...但你会注意到这并不比使用.each()
循环更好。问题是,尽管您的letters
实现将当前i
项的值传递给第一个参数中的回调,但您实际上无法对其进行修改,因为它是通过值而不是通过引用传递的字符串,所以要实际更改当前项目,你必须访问它所包含的数组,你可以从中为索引{{1}}的元素设置一个新值。
答案 1 :(得分:0)
this.letters
是String
的集合,而非Letters
。因此,当您调用回调函数时,第一个参数将是一个字符串,而不是Letters
的实例,因此未定义addLetter
:
var test3 = test.each(function(e){
e.addLetter('y'); // e is a string! Try this.addLetter('y') instead
});
答案 2 :(得分:0)
e
是一个字符串(this.letters
数组中的一个项目),也就是说,内置String对象的一个实例,你试图调用{{1它上面的方法,由于addLetter
不存在,显然会失败。也就是说,这是我对你的尝试的解释,希望它可以帮助:
String.prototype.addLetter
用法:http://jsfiddle.net/wared/WLt4L/。
Bonus:这是Letters继承自Array的另一个演示:http://jsfiddle.net/wared/kEG56/(尚未经过深度测试)。