Javascript 将数组放入自定义对象

Javascript 将数组放入自定义对象,javascript,arrays,object,Javascript,Arrays,Object,我正在尝试构建我的第一个自定义对象,它看起来像这样: function URLObject() { this.syllables = new Array(); etc... this.AddtoSyllables = AddtoSyllables; function AddtoSyllables(AWord) { var SylCount = this.syllables.length; alert("This is SylCount

我正在尝试构建我的第一个自定义对象,它看起来像这样:

function  URLObject()
{
   this.syllables = new Array();
   etc...

   this.AddtoSyllables = AddtoSyllables;
   function AddtoSyllables(AWord)
   {
       var SylCount = this.syllables.length;
       alert("This is SylCount: " + SylCount);
   }
}

var myobj = new URLObject();
myobj.AdtoSyllables("text");
执行上述代码会导致JS引擎打印出以下内容:

我是西尔伯爵:南

-或-

这是SylCount:未定义

我看过头优先Javascript、Javascript圣经和各种JS网站上的信息。它们都详尽地介绍了对象数组的使用,但没有一个讨论对象中的数组

然而,我在这里做错了什么,我不知道是什么。有人能帮忙吗?

您需要这样做:

function URLObject()
{
var that = this;
that.AddtoSyllables = AddtoSyllables;
function AddtoSyllables(AWord)  
等等。。。 这样,您可以向一个对象添加方法和属性。

您需要执行以下操作:

function URLObject()
{
var that = this;
that.AddtoSyllables = AddtoSyllables;
function AddtoSyllables(AWord)  
等等。。。 像这样,您可以向一个对象添加方法和属性。

这里:

function  URLObject()
{
   this.syllables = [];
   etc...
}

URLObject.prototype.addToSyllables = function(aWord) {
  var SylCount = this.syllables.length;
  alert("This is SylCount: " + SylCount);
}

var myobj = new URLObject();
myobj.adtoSyllables("text");
.prototype将在其之后声明的函数添加到构造函数构造的每个对象中。在您的例子中,由新的URLObject实例化的每个对象都是:

function  URLObject()
{
   this.syllables = [];
   etc...
}

URLObject.prototype.addToSyllables = function(aWord) {
  var SylCount = this.syllables.length;
  alert("This is SylCount: " + SylCount);
}

var myobj = new URLObject();
myobj.adtoSyllables("text");

.prototype将在其之后声明的函数添加到构造函数构造的每个对象中。在您的例子中,由新的URLObject实例化的每个对象都有一个问题,即函数AddtoSyllables不是URLObject的成员函数或方法。它只是一个没有对象附件的嵌套函数,因此所有使用它的操作都会返回dom窗口对象。声明AddtoSyllables函数的正确方法如下:

function  URLObject()
{
    //...
}

URLObject.prototype.AddtoSyllables = function (AWord)
{
    var SylCount = this.syllables.length;
    alert("This is SylCount: " + SylCount);
}
为了解释问题中行为的原因,我想澄清一下,javascript中的对象被视为映射、字典或键值对,使用最适合您的术语。使用语法x.y=value;等价于使用键y将值放入映射x中。具有以下代码:

this.AddtoSyllables = AddtoSyllables;
function AddtoSyllables(AWord)
{
    var SylCount = this.syllables.length;
    alert("This is SylCount: " + SylCount);
}
将AddtoSyllables函数作为条目添加到此指向的对象。 代码

myobj.AdtoSyllables(...)
相当于

myobj["AdtoSyllables"](...) // now a retreiaval operation
甚至

var fn = myobj["AdtoSyllables"];
fn (...);
在AdtoSyllables函数中,使用了此选项。与大家的期望相反,它并不是指向myobj的指针

原因是AddtoSyllables被视为URLObject类的一个静态方法,正如OOP人员所理解的,甚至是一个松散的静态函数,如C中所述。要使JS将其视为URLObject对象的一个成员作为OOP人员的一个实例方法,必须告诉JS这样做。这是通过URLObject.prototype.AddtoSyllables=..实现的。。。。这相当于实例方法的声明

从另一个角度来看:

function foo() { /* some code using `this` */ }
var bar = {};
var baz = {};

bar.foo = foo; // same as bar["foo"] = foo;
baz.foo = foo; // same az baz["foo"] = foo;

在上面的代码中,foo中的这个用法既不指向bar,也不指向baz。同时,bar.foo将指向与baz.foo完全相同的实例,因为foo也是一个对象。

您遇到的问题是函数AddtoSyllables不是URLObject的成员函数或方法。它只是一个没有对象附件的嵌套函数,因此所有使用它的操作都会返回dom窗口对象。声明AddtoSyllables函数的正确方法如下:

function  URLObject()
{
    //...
}

URLObject.prototype.AddtoSyllables = function (AWord)
{
    var SylCount = this.syllables.length;
    alert("This is SylCount: " + SylCount);
}
为了解释问题中行为的原因,我想澄清一下,javascript中的对象被视为映射、字典或键值对,使用最适合您的术语。使用语法x.y=value;等价于使用键y将值放入映射x中。具有以下代码:

this.AddtoSyllables = AddtoSyllables;
function AddtoSyllables(AWord)
{
    var SylCount = this.syllables.length;
    alert("This is SylCount: " + SylCount);
}
将AddtoSyllables函数作为条目添加到此指向的对象。 代码

myobj.AdtoSyllables(...)
相当于

myobj["AdtoSyllables"](...) // now a retreiaval operation
甚至

var fn = myobj["AdtoSyllables"];
fn (...);
在AdtoSyllables函数中,使用了此选项。与大家的期望相反,它并不是指向myobj的指针

原因是AddtoSyllables被视为URLObject类的一个静态方法,正如OOP人员所理解的,甚至是一个松散的静态函数,如C中所述。要使JS将其视为URLObject对象的一个成员作为OOP人员的一个实例方法,必须告诉JS这样做。这是通过URLObject.prototype.AddtoSyllables=..实现的。。。。这相当于实例方法的声明

从另一个角度来看:

function foo() { /* some code using `this` */ }
var bar = {};
var baz = {};

bar.foo = foo; // same as bar["foo"] = foo;
baz.foo = foo; // same az baz["foo"] = foo;

在上面的代码中,foo中的这个用法既不指向bar,也不指向baz。同时,bar.foo将指向与baz.foo完全相同的实例,因为foo也是一个对象。

首先,发布的代码实际上在Chrome和Firefox上对我有效;因此,这必须取决于JavaScript引擎,否则会发生一些令人不安的事情

更新:我怀疑可能让您困惑的是,在代码中单独调用AddtoSyllables,但您并没有告诉我们在哪里突然不再定义this.syllables。这就是这种行为可能令人困惑的地方。我创建了一个JSFIDLE,希望能够解释它是如何更好地为您工作的

也就是说,编写这样的代码通常是非常可能的,而不必使用这个或原型。例如:

function createURLObject() {
   // Use closed-over locals instead of attaching properties.
   var syllables = new Array();

   function AddToSyllables(AWord) {
     // Since syllables is closed over, it is accessible here
     // (but WON'T be accessible outside this scope).
     syllables.push(AWord);
     return syllables.length;
   }

   // Expose whatever functionality you want to be "public"
   // in the returned object.
   return {
     AddToSyllables: AddToSyllables
   };
}

var myObj = createURLObject();
myObj.AddToSyllables("text");
当然,对于大多数来自其他语言的开发人员来说,理解JavaScript的古怪和令人惊讶是很有价值的
关于这个。也就是说,一旦你理解了它,我想你会发现它通常是可以完全避免的。

首先,发布的代码实际上在Chrome和Firefox上对我有效;因此,这必须取决于JavaScript引擎,否则会发生一些令人不安的事情

更新:我怀疑可能让您困惑的是,在代码中单独调用AddtoSyllables,但您并没有告诉我们在哪里突然不再定义this.syllables。这就是这种行为可能令人困惑的地方。我创建了一个JSFIDLE,希望能够解释它是如何更好地为您工作的

也就是说,编写这样的代码通常是非常可能的,而不必使用这个或原型。例如:

function createURLObject() {
   // Use closed-over locals instead of attaching properties.
   var syllables = new Array();

   function AddToSyllables(AWord) {
     // Since syllables is closed over, it is accessible here
     // (but WON'T be accessible outside this scope).
     syllables.push(AWord);
     return syllables.length;
   }

   // Expose whatever functionality you want to be "public"
   // in the returned object.
   return {
     AddToSyllables: AddToSyllables
   };
}

var myObj = createURLObject();
myObj.AddToSyllables("text");


当然,对于大多数来自其他语言的开发人员来说,了解JavaScript的古怪和令人惊讶的行为是很有价值的。也就是说,一旦你理解了它,我想你会发现它通常可以完全避免。

myobj.AdtoSyllablestext;应该是myobj.AddtoSyllablestext。。。哪个浏览器?在修正了输入错误后,代码对我来说运行得很好。是的,设置一个-它可以让人们非常容易地看到正在发生的事情并比较浏览器。myobj.AdtoSyllablestext;应该是myobj.AddtoSyllablestext。。。哪个浏览器?在修正了输入错误后,代码对我来说很好。是的,设置一个-它可以让人们很容易地看到正在发生的事情并比较浏览器。我建议使用我发布的原型解决方案。@ndrizza。不过,有多个答案总是好的——它允许用户更容易地比较它们,并判断每种技术何时合适。我建议使用我发布的原型解决方案。@ndrizza。不过,有多个答案总是好的——这让用户能够更容易地比较它们,并判断每种技术何时适用。如果你要将他的解决方案更改为使用原型,你还应该花时间解释它们:如果你要将他的解决方案更改为使用原型,你也应该花点时间来解释:事实上。。。因为它叫myobj。它应该指的是对象,因为这是函数的作用域。@Jeff,我更新了答案以反映您的观点,试图用OOP类比法澄清事实。。。因为它叫myobj。它应该指的是对象,因为这是函数的作用域。@Jeff,我已经更新了答案以反映您的观点,试图用OOP analogiesHa将其弄清楚。我喜欢你这样说,但无论如何,在这个例子中使用这个。。。我相信,在这个例子中完全避免这种情况的唯一方法是,假设您不想使用var x=new URLObject,那么实际使用原型;x、 AddToSyllables=…@杰夫:是的,是的。。。挑剔者;我经常使用局部闭包,而不是将其用于对象状态,但在声明函数时仍使用它,如原始示例中所示。然而,正如我所暗示的,完全可以避免这种情况。我已经更新了答案来说明如何使用。唯一的诀窍是,如果有人使用原型来做某事,这实际上会破坏它,除非我对返回语句的工作方式有很大的误解-它不会接收任何原型成员,对吧,除了对象成员?这不是问题,只是需要注意。不过,我确实喜欢使用完全私有的变量,这很好。@Jeff:你说得对,如果你决定基本上完全跳过基于原型的继承,这种反私有的方法主要是有效的。混合和匹配使用此功能的代码与不使用此功能的代码可能会有点混乱。有关这种完全不同的JavaScript编写方式的详细概述,请参阅我的一位老同事的博文:哈。我喜欢你这样说,但无论如何,在这个例子中使用这个。。。我相信,在这个例子中完全避免这种情况的唯一方法是,假设您不想使用var x=new URLObject,那么实际使用原型;x、 AddToSyllables=…@杰夫:是的,是的。。。挑剔者;我经常使用局部闭包,而不是将其用于对象状态,但在声明函数时仍使用它,如原始示例中所示。然而,正如我所暗示的,完全可以避免这种情况。我已经更新了答案来说明如何使用。唯一的诀窍是,如果有人使用原型来做某事,这实际上会破坏它,除非我对返回语句的工作方式有很大的误解-它不会接收任何原型成员,对吧,除了对象成员?这不是问题,只是需要注意。不过,我确实喜欢使用完全私有的变量,这很好。@Jeff:你说得对,如果你决定基本上完全跳过基于原型的继承,这种反私有的方法主要是有效的。将使用此代码的代码与 不可能有点乱。有关这种完全不同的JavaScript编写方式的概述,请参阅我的一位老同事的博文: