2014-10-18 3 views
-1

Довольно долгий вопрос. Но в основном это описывается в значительной степени для описания того, что я хочу. Этот код здесь для создания любого объекта according to user input для ввода текстового поля. Если я хочу создать Number, String или Object, i просто нужно написать Number/String/Object в text field.Динамические динамические объекты JavaScript на языке

кнопка была введена, чтобы позвонить createObj.getObjName и получить ввод из текста field.It пытается соответствовать входу для любых три типа объекта, которые являются Number/String/Object.Then она вызывает функцию Его [problem lies here i think], который перебирает **list_keys array** с использованием Array.prototype.some, который создается с использованием объекта json, который содержит другое имя объекта. Они представляют собой assigned with objects, созданные с использованием new keyword.

проблема заключается в вызове функции проверки я попытался вынудило THIS keyword указать createObj объекта внутри него вместо окна object.I пытался console.log(this) это дает мне этот выход, который является input html button element.

<input type='button' id='btn' value="create"> 

Но я хочу, чтобы ЭТО относилось к самому createObj. Почему это относится к элементу HTML? Как я могу это решить?

Полный код:

(function() { 
    var list = { 
     "Number": new Number(), 
     "String": new String(), 
     "Object": new Object(), 
     "Array": new Array() 
    } 
    var list_keys = Object.keys(list); 
    var createObj = { 
     re: null, 
     text: null, 
     match: null, 
     newObj: null, 
     getObjName: function() { 
      this.re = /Number|Object|String/; 
      this.text = document.getElementById('text').value; 
      this.match = this.text.match(this.re); 
      var bool = check.call(this); 
      if (bool) { 
       this.makeObj(list.this.match[0]); 
      } 
     }, 
     makeObj: function(obj) { 
      this.newObj = obj; 
     } 
    }; 

    function check() { 
     console.log(this); 
     return list_keys.some(function(el, indx, arr) { 
      return this.match[0] === el; 
     }); 
    } 
    document.getElementById('btn').addEventListener('click', createObj.getObjName); 
})(); 
+0

почему вниз голосовать этот question.Is вопрос не ясный :( –

ответ

2

Вы можете просто связать объект, как этот

createObj.getObjName.bind(createObj) 

это возвращает новую функцию, с this ссылкой createObj внутри getObjName.

Кроме того, что, если нет никакого совпадения?

return this.match[0] === el; 

это произойдет сбой во время выполнения, так как this.match будет нулевым. Таким образом, вы можете захотеть сделать что-то вроде этого

return this.match && list_keys.some(...); 

Если бы я был написать один и тот же код, в лучшую сторону, я хотел бы сделать что-то вроде этого

(function() { 
    var MyObject = { 
     newObject: null, 
     createObject: function() { 
      var text = document.getElementById('text').value; 
      if (window.hasOwnProperty(text)) { 
       this.newObject = new window[text]; 
      } 
     } 
    } 

    document.getElementById('btn').addEventListener('click', 
     MyObject.createObject.bind(MyObject)); 

})(); 
+0

я сильно утверждаю, что в такой ситуации, как это тогда? дополнительный псевдоним, закрытый над 'this' (например,' var self = this'), проще понять и более эффективно, чем использовать '.bind'. Последний IMHO должен быть зарезервирован для случаев, когда вы не контролируете лексическую область функции вы пытаетесь использовать 'this' in. – Alnitak

+0

@Alnitak На самом деле, я даже не уверен, почему OP делает этот путь. Поэтому я просто дал ему простейшую альтернативу, не изменяя другую часть кода. – thefourtheye

+0

Правда, это не самый простой код для чтения. Я бы использовал 'new' для создания фактического экземпляра вместо статического объекта, содержащего свойства метода. – Alnitak

1

когда вы связываете функции к event, this относится к узлу html, к которому привязано событие. Вы можете обойти это различными способами. Первое, что приходит на ум ссылаются createObj непосредственно:

getObjName: function() { 
    createObj.re = /Number|Object|String/; 
    createObj.text = document.getElementById('text').value; 
    createObj.match = this.text.match(createObj.re); 
    var bool = check.call(createObj); 
    if (bool) { 
     this.makeObj(list.createObj.match[0]); 
    } 
}, 

это меньше, чем идеал, поскольку он ссылается на объект по имени, что означает, если изменить имя объекта, вы должны изменить все ссылки на Это. Это также представляет проблему, если вы (или другой разработчик, работающий с вашим кодом) определяет новый createObj по строке. Поскольку он ссылается на объект по имени, он будет использовать новый объявленный объект вместо вашего.Улучшение было бы создать псевдоним для объекта (обычно называется что):

getObjName: function() { 
    that.re = /Number|Object|String/; 
    that.text = document.getElementById('text').value; 
    that.match = this.text.match(that.re); 
    var bool = check.call(that); 
    if (bool) { 
     this.makeObj(list.that.match[0]); 
    } 
}, 
... 
var that = createObj 

проблема с этим состоит в том, что that обычно подразумевается ссылаться this в сферу, где контекст теряется, а не произвольный объект (в данном случае createObj).

Кроме того, я не уверен, что функция принадлежит методу createObj или, по крайней мере, к структуре, содержащей ваши данные. Разделение проблем является важным, и в то время как

var createObj = { 
    re: null, 
    text: null, 
    match: null, 
    newObj: null, 

касаются данных, которые вы манипулируете, getObjName и makeObj обеспокоены с обработкой событий и изготовления объекта с помощью собранных данных. Я бы извлечь из-структуры для хранения данных, которые я затем использовать в других моих объектах:

var descriptors = { 
    re: null, 
    text: null, 
    match: null, 
    newObj: null 
} 

var getObjName = function() { 
    descriptors.re = /Number|Object|String/; 
    descriptors.text = document.getElementById('text').value; 
    descriptors.match = descriptors.text.match(descriptors.re); 
    var bool = check.call(descriptors); 
    if (bool) { 
     makeObj(list.descriptors.match[0]); 
    } 
} 
var makeObj = function(obj) { 
    this.newObj = obj; 
} 
function check() { 
    console.log(this); 
    return list_keys.some(function(el, indx, arr) { 
     return this.match[0] === el; 
    }); 
} 
document.getElementById('btn').addEventListener('click', getObjName); 

это отделяет от функциональности-структуру, и лучше передает намерение частей (descriptors содержит все данные, getObjName обрабатывает событие, а makeObj создает экземпляр нового объекта).

есть еще одна проблема с этим, но с точки зрения дизайна getObjName нарушает принцип единой ответственности. Ему поручено обработать событие и получить имя объекта. Я бы реорганизовать обработку часть событий, чтобы остаться верным намерением getObjName «s:

var getObjName = function(descriptors) { 
    descriptors.re = /Number|Object|String/; 
    descriptors.text = document.getElementById('text').value; 
    descriptors.match = this.text.match(descriptors.re); 
    return check.call(descriptors); 
} 

document.getElementById('btn').addEventListener('click', function() { 
    if (getObjName(descriptors)) { 
     makeObj(list.descriptors.match[0]); 
    } 
}); 
+0

У меня есть вопрос относительно вашего ответа. Вы писали, что привязывать объект, используя его имя, могут в будущем вызвать проблему, если я изменю имя. Но в вашем четвертом фрагменте вы использовали имя объекта, которое является (дескриптором) все время. И внутри getObjName вы использовали дескрипторы.match = this.text.match (дескриптор.re); Здесь не следует, чтобы этот ключ снова вызывал одну и ту же проблему с индикацией? Я имею в виду ЭТО внутри функции относится к окну –

+0

извините, опечатка ... должно быть, оставила его без внимания. крепление ... –

+0

сделано. Я также установил дескрипторы в качестве параметра (в последнем блоке), чтобы отделить его от внешней структуры –

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