2013-05-07 3 views
1

Я пытающегося построить свой первый пользовательский объект, и это выглядит примерно так:Ввод массивов в пользовательских объектов

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: NAN

-или-

Это SylCount не определено.

Я рассмотрел информацию в главном Javascript, в Библии Javascript и на различных сайтах JS. Все они исчерпывающе описывают использование массивов объектов, но ни один из них не обсуждает массивы внутри объектов.

И все же я делаю что-то неправильно здесь, и я не знаю, что. Может ли кто-нибудь помочь?

+0

myobj.AdtoSyllables («текст»); должен быть myobj.AddtoSyllables («текст»); ... – RafH

+1

Какой браузер? Код работает отлично для меня (после исправления опечатки). –

+0

Да, может быть полезно создать [скрипку] (http://jsfiddle.net/) - это очень просто, чтобы люди могли точно видеть, что происходит и сравнивать браузеры. – Jeff

ответ

0

вам нужно сделать, это:

function URLObject() 
{ 
var that = this; 
that.AddtoSyllables = AddtoSyllables; 
function AddtoSyllables(AWord) 

и т.д ... Как это вы можете добавить метод и атрибуты к одному объекту.

+0

Я рекомендую использовать прототип решения, как я опубликовал. – ndrizza

+1

@ndrizza Ясно. Всегда хорошо иметь несколько ответов, хотя это позволяет пользователям более легко сравнивать их и судить, когда каждый метод подходит. – Jeff

2

Здесь вы идете:

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 добавляет функцию объявленную после этого к каждому объекту, построенного с помощью функции конструктора. (В вашем случае каждый объект, который был экземпляр с помощью new URLObject())

+0

Посмотрите здесь, это потрясающий ресурс: http://ejohn.org/apps/learn/#1 – ndrizza

+2

Если вы собираетесь изменить свое решение на использование прототипов, вы также должны потратить время на их объяснение :) – Paul

0

Проблемы у Вас есть, что функция AddtoSyllables не является функция члена или метода из URLObject. Это всего лишь вложенная функция без объектных вложений, поэтому все способы использования this приведут к возврату объекта окна dom. Правильный способ объявления функции AddtoSyllables заключается в следующем:

function URLObject() 
{ 
    //... 
} 

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

Чтобы объяснить причины поведения в этом вопросе, я хотел бы уточнить, что объекты в JavaScript рассматриваются как карты, словарь или пара ключевых значений (используйте термин, который подходит вам лучше всего). Использование синтаксиса x.y = value; эквивалентно присвоению значения value на карте x с ключом y. Имея код:

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

добавляет функцию AddtoSyllables как запись на объект this указывает. Код

myobj.AdtoSyllables(...) 

эквивалентно

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

или даже

var fn = myobj["AdtoSyllables"]; 
fn (...); 

Внутри функции AdtoSyllables, this используется.Против общих ожиданий, это не указатель на myobj.

Причиной этого является то, что AddtoSyllables рассматривается как статический метод из URLObject класса (как ООП ребята поняли бы это), или даже свободная статическая функция (например, в C). Чтобы заставить JS рассматривать его как член объекта URLObject (метод экземпляра для парней ООП), 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; 

В приведенном выше коде, this порядки внутри foo не будет ни точка, ни barbaz. В то же время bar.foo укажет на тот же экземпляр, что и baz.foo, для foo также является объектом.

+1

Фактически ... поскольку он вызывается с помощью 'myobj.', он должен ссылаться на объект, так как теперь это область действия функции. – Jeff

+0

@Jeff, я обновил ответ, чтобы отразить вашу точку зрения, пытаясь сделать это понятным с помощью аналогов ООП –

2

Во-первых, код как отправленный фактически работает для меня в Chrome и Firefox; так что это должно зависеть от механизма JavaScript, или есть что-то напуганное.

Update: Я подозреваю, что может быть путаю некоторые отдельный вызов AddtoSyllables (в коде вы не показали нам), где внезапно this.syllables больше не определяется. Здесь поведение this может ввести в заблуждение. Я создал jsFiddle, чтобы, надеюсь, объяснить, как это работает немного лучше для вас.

http://jsfiddle.net/J3tUb/

Тем не менее, это часто очень возможно писать код, как это без необходимости использовать this (или прототип) на всех. Например:

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 причудливая (и удивительно, для большинства разработчиков из других языков) поведения по отношению к this. Тем не менее, как только вы поймете это, я подозреваю, вы обнаружите, что его часто можно избежать вообще.

+0

Ha. Мне нравится, что вы это говорите, но затем используйте «это» в примере в любом случае ... Я верю, что единственный способ полностью избежать «этого» для этого примера - фактически использовать прототип (предполагая, что вы не хотите go 'var x = new URLObject(); x.AddToSyllables = ...') – Jeff

+0

@Jeff: Да, да ... nitpicker;) Я часто хожу с закрытыми локалями вместо использования' this' для состояния объекта, но все равно использую 'this' при объявлении функций (как в исходном примере) , Однако, безусловно, можно избежать «этого» * ​​полностью, как я подразумевал. Я обновил ответ, чтобы показать, как это сделать. –

+0

Единственный трюк с этим заключается в том, что если кто-то * использует прототип для чего-то, это фактически нарушит его, если я не ошибаюсь в том, как работает оператор 'return', он не получит никаких элементов прототипа, правильно (кроме объектов)? Не то, чтобы это проблема, просто что-то, о чем нужно знать. Мне действительно нравится использование полностью закрытых переменных, но это аккуратно. – Jeff

Смежные вопросы