无法在循环

时间:2017-12-30 18:35:32

标签: javascript string foreach dom-manipulation

我有"错误:无法读取属性'缩短'未定义"运行我的测试时出错。我希望我的循环运行缩短函数来检查字符串是否超过20个字符,如果是,则将其限制为。

  function ListView(list) {
    this.list = list;
    this.converted;
  }

  ListView.prototype.convert = function() {
    var output = [];
    this.list.notelist.forEach(function(element) {
      this.shorten(element);
      output += "<li><div>" + element.text + "</div></li>";
    });
    this.converted = "<ul>" + output + "</ul>";
  };

  ListView.prototype.shorten = function(string) {
    if (string.length > 20) {
      return string.substring(0, 20);
    }
    return string;
  };

list来自另一个构造函数,但我用它来模拟它;

var mockList = { notelist: [{ text: "hello" }, { text: "goodbye" }] };

5 个答案:

答案 0 :(得分:2)

您的代码存在几个问题:

enter image description here

  1. 您遇到这是什么问题,这对初学者来说是个常见问题,请查看this link。在function (element) { ..的匿名函数体中,它不会获取自定义类型的上下文,因此this是对浏览器窗口的引用。

  2. 调用您的shorten方法时,其语义使用不同。您没有获取它返回的内容,但是element根本没有使用该方法进行修改。

  3. 因此,让我们尝试更正您尝试执行的操作的代码:

    <script>
        function ListView(list) {
            this.list = list;
            this.converted;
        }
    
        ListView.prototype.convert = function () {
            var output = [];
    
            var that = this;
            this.list.notelist.forEach(function (element) {
                that.shorten(element);
                output += "<li><div>" + element.text + "</div></li>";
            });
            this.converted = "<ul>" + output + "</ul>";
        };
    
        ListView.prototype.shorten = function (el) {
            var string = el.text;
    
            if (string.length > 20) {
                el.text = string.substring(0, 20);
            }
        };
    
        var mockList = { notelist: [{ text: "hello" }, { text: "goodbye0123456789012345" }] };
        var listview1 = new ListView(mockList);
        listview1.convert();
        alert(listview1.converted);
    
    </script>
    
    有意为测试修改了

    goodbye0123456789012345,结果将缩短为goodbye0123456789012

答案 1 :(得分:1)

您在this中丢失了forEach绑定 尝试:

  ListView.prototype.convert = function() {
    var output = [];
    this.list.notelist.forEach(function(element) {
      this.shorten(element);
      output += "<li><div>" + element.text + "</div></li>";
    }.bind(this));
    this.converted = "<ul>" + output + "</ul>";
  };

this.list.notelist.forEach((element) => {
  this.shorten(element);
  output += "<li><div>" + element.text + "</div></li>";
});

类似于:Passing scope to forEach

答案 2 :(得分:0)

尝试绑定this

this.list.notelist.forEach(function(element) {
      this.shorten(element);
      output += "<li><div>" + element.text + "</div></li>";
    }.bind(this));

答案 3 :(得分:-2)

在这种情况下,您可以使用ES6 arrow function来确保在您的功能中维护this

this.list.notelist.forEach((element) => {
  this.shorten(element);
  output += "<li><div>" + element.text + "</div></li>";
});

请记住浏览器上的check the availability箭头功能。如果您想要更广泛支持的解决方案,请像其他人一样使用bind函数。

答案 4 :(得分:-2)

forEach接受第二个参数thisArg,默认情况下为undefined

试试这个:

   this.list.notelist.forEach(function(element) {
      this.shorten(element);
      output += "<li><div>" + element.text + "</div></li>";
    }, this); // <-- note the `this` argument passed here