PDA

View Full Version : JavaScript Prototype set a Boolean value to true



sniperman
05-11-2015, 05:55 PM
<label>Choose Thing</label>
<select size="1" name="thing_type" id="thing_type" onchange="Select(this.value, this.options[this.selectedIndex].title);">
<option value="OneType">Type 1</option>
<option value="OtherType">Type 2</option>
</select>


function Thing() {

Thing.Type = {
'OneType' : false,
'OtherType' : false
};
return Thing;
}

var Thing1 = new Thing();

var f = document.getElementById("thing_type");
var newType = f.options[f.selectedIndex].value;
for(i=0;i<2;i++) {
if (Thing.Type.newType == "OneType") { Thing.Type.newType = true; }// set the user chosen value to true in the Prototype


The aim of this code is to be able to change the Boolean type values from false to true. When I run code similar to this, the expectation is that the line of code which references Thing.Type.newType to either read Thing.Type.OneType or Thing.Type.OtherType. Instead it returns a new object in the prototype.

jscheuer1
05-11-2015, 06:39 PM
That's invalid code. No closing brace at the end. Also the Select() function is not defined. I will try to trouble shoot this anyway - by removing the undefined onchange event and adding a closing brace assuming it follows the end of the code and was just omitted as a typo when pasting the code into the post.

If I have any luck with that, I'll let you know. But if there is more code, I should probably see it.

By the way. I'm not used to seeing things like Thing.Type = {}, if Thing is the prototype and the function is being run to generate an instance new Thing() than I would expect to see:


function Thing() {

this.Type = {
'OneType' : false,
'OtherType' : false
};
return this;
}

If Thing is used to reference itself internally when run as an instance, doesn't that defeat the purpose of having a prototype? Maybe not, but if not, I must have been absent that day.

jscheuer1
05-11-2015, 07:01 PM
OK, still not sure what you're going for. But this might be it:


<!DOCTYPE html>
<html>
<head>
<title></title>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8">

</head>
<body>
<label>Choose Thing</label>
<select size="1" name="thing_type" id="thing_type">
<option value="OneType">Type 1</option>
<option value="OtherType">Type 2</option>
</select>

<script type="text/javascript">
function Thing() {

this.Type = {
'OneType' : false,
'OtherType' : false
};
return this;
}

var Thing1 = new Thing();

var f = document.getElementById("thing_type");
var newType = f.options[f.selectedIndex].value;
for(var p in Thing1.Type){
Thing1[p] = p === newType;
}
if(window.console){console.log(Thing1);} /* diagnostic - should show (if there is a console) something like:
Thing {Type: Object, OneType: true, OtherType: false}
*/
</script>
</body>
</html>

Any questions, let me know.

Note: You generally do not iterate over an object (Thing1.Type in this case) using numerical indexes, though that can sometimes be done. If it is it's usually more cumbersome than using the index names as is done in my code for(var p in Thing1.Type) not for(i=0;i<2;i++)

sniperman
05-11-2015, 08:45 PM
By the way. I'm not used to seeing things like Thing.Type = {}, if Thing is the prototype and the function is being run to generate an instance new Thing() than I would expect to see:

You are right. I am still getting my head around the difference between a reference within the prototype constructor using Thing.Type rather than this.Type. I found both are valid when calling an instance.


If Thing is used to reference itself internally when run as an instance, doesn't that defeat the purpose of having a prototype? Maybe not, but if not, I must have been absent that day.

Not necessarily. The aim of this code is to create a prototype of a Constant but Extensible game environment, so there is no need to use more than one instance, the prototype itself is sufficient to represent the Constant and Extensible Object. This prototype should be added to and manipulated, and external functions like the ones expressed, can extend the prototype (i.e. say we want the thing to have ten types of OneType rather than 1), so a new array object would be created to represent this. There is no need for extra instances of a Constant.

I saw your code, and added a function to represent more what I wanted to achieve, where the value is changed depending on the choice, and update the prototype, say, before the prototype values are sent to a database and made Constant.


<label>Choose Thing</label>
<select size="1" name="thing_type" id="thing_type" onchange="userChange();">
<option value="OneType">Type 1</option>
<option value="OtherType">Type 2</option>
</select>

<script type="text/javascript">
function Thing() {

this.Type = {
'OneType' : false,
'OtherType' : false
};
return this;
}

var Thing1 = new Thing();

function userChange() {
var f = document.getElementById("thing_type");
var newType = f.options[f.selectedIndex].value;
for(var p in Thing1.Type){
Thing1[p] = p === newType;
}
console.log(Thing1); /* diagnostic - should show (if there is a console) something like:
Thing {Type: Object, OneType: true, OtherType: false}
*/
}
</script>

I did find one issue with the code. Thing prototype when we create an instance, now has Thing.OneType and Thing.OtherType as well as Thing.Type.OneType and Thing.Type.OtherType. To me that seems like an unnecessary duplication of OneType and OtherType, but I do understand one is an instance.

jscheuer1
05-11-2015, 11:52 PM
I see what I did wrong. I iterated over Thing1.Type, but assigned the results to Thing1:


for(var p in Thing1.Type){
Thing1[p] = p === newType;
}

should have been:


for(var p in Thing1.Type){
Thing1.Type[p] = p === newType;
}

That should fix it.

Also, though I don't think this is an issue, just something to know as it saves time, the prototype constructor returns the instance implicitly, so doesn't have to explicitly. In other words, this:


function Thing() {

this.Type = {
'OneType' : false,
'OtherType' : false
};
return this;
}

Can be just:


function Thing() {

this.Type = {
'OneType' : false,
'OtherType' : false
};
}

Just thought I'd add a possible way to deal with all this:


<!DOCTYPE html>
<html>
<head>
<title></title>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8">

</head>
<body>
<label>Choose Thing</label>
<select size="1" name="thing_type" id="thing_type">
<option value="OneType">Type 1</option>
<option value="OtherType">Type 2</option>
</select>

<script type="text/javascript">
function Thing() {
this.Type = {
'OneType' : false,
'OtherType' : false
};
}

var Thing1 = new Thing();

var f = document.getElementById("thing_type");
function setBoleanVals(){
var newType = this.value;
for(var p in Thing1.Type){
Thing1.Type[p] = p === newType;
}
if(window.console){console.log(Thing1);} /* diagnostic */
}
f.addEventListener('change', setBoleanVals, false);
setBoleanVals.apply(f);
</script>
</body>
</html>

Or even:


<!DOCTYPE html>
<html>
<head>
<title></title>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8">

</head>
<body>
<label>Choose Thing</label>
<select size="1" name="thing_type" id="thing_type">
<option value="OneType">Type 1</option>
<option value="OtherType">Type 2</option>
</select>

<script type="text/javascript">
function Thing() {
}
Thing.prototype = {
Type: {'OneType' : false, 'OtherType' : false}
};

var Thing1 = new Thing();

var f = document.getElementById("thing_type");
function setBoleanVals(){
var newType = this.value;
for(var p in Thing1.Type){
Thing1.Type[p] = p === newType;
}
if(window.console){console.log(Thing1);} /* diagnostic */
}
f.addEventListener('change', setBoleanVals, false);
setBoleanVals.apply(f);
</script>
</body>
</html>

Here's another way you might find interesting:


<!DOCTYPE html>
<html>
<head>
<title></title>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8">

</head>
<body>
<label>Choose Thing</label>
<select size="1" name="thing_type" id="thing_type">
<option value="OneType">Type 1</option>
<option value="OtherType">Type 2</option>
</select>

<script type="text/javascript">
function Thing(select) {
this.select = select;
this.Type = {};
this.setBooleans = function(){
for(var p in this.Type){
this.Type[p] = p === this.select.value;
}
if(window.console){console.log(this);} /* diagnostic */
}
var o = select.options, c = -1;
while(o[++c]){this.Type[o[c].value] = o[c].value === select.value;}
}

var Thing1 = new Thing(document.getElementById("thing_type"));
if(window.console){console.log(Thing1);} /* diagnostic */

Thing1.select.addEventListener('change', function(){Thing1.setBooleans();}, false);
</script>
</body>
</html>