Confusion about object oriented javascript - javascript

I'm practicing object oriented syntax in javascript and am having some problems. This is my code:
<html>
<head>
<script type="text/javascript">
function Name(first,mid,last) {
this.first = first;
this.middle = mid;
this.last = last;
}
Name.prototype.fullname = function () {
return this.first + " " + this.middle + " " + this.last;
}
Name.prototype.fullnamereversed = function() {
return this.last + " " + this.middle + " " + this.first;
}
var s = new Name("James","Harlow","Smith")
</script>
</head>
<body>
<script type="text/javascript">
document.body.innerHTML = s.fullname;
document.body.innerHTML = s.fullnamereversed;
</script>
</body>
</html>
When I load the page, the innerHTML of the body is the exact text of Name.protoype ("function ()... this.first + this.middle + this.last..."). What have I done wrong here?

You need to call the functions with the () operator:
document.body.innerHtml = s.fullname();

You are assigning a function to the prototype, therefore you need to call it as such:
<script type="text/javascript">
document.body.innerHTML = s.fullname() + ' ' + s.fullnamereversed();
</script>

You need to invoke your function: document.body.innerHTML = s.fullname();
Example here.

document.body.innerHTML = s.fullname; sets the innerHTML to the function s.fullname.
If you want to set the innerHTML to what the function returns, then you need to actually call the function:
document.body.innerHTML = s.fullname();

Related

What am I doing wrong?

This is my Javascript code I have so far. I am trying to create a personInfo() object with 2 functions. I am not sure what I am doing wrong.
var personInfo =
{
personInfo.personRelation: " ",
personInfo.personName: " ",
personInfo.personAge: 0,
personInfo.personGender: " "
var relationValue = personRelation;
var nameValue = personName;
var ageValue = personAge;
var genderValue = personGender;
getPersonInfo: function()
{
document.write( "<p>" + personInfo.personRelation + "<br />" );
document.write( "Name: " + personInfo.personName + "<br />");
document.write( "Age: " + personInfo.personAge + "<br />" );
document.write( "Gender: " + personInfo.personGender + "</p>" );
}
setPersonInfo(relationValue, nameValue, ageValue, genderValue): function()
{
this.relationValue = relationValue;
this.nameValue = nameValue;
this.ageValue = ageValue;
this.genderValue = genderValue;
}
}; // end object personInfo
This my html code...I am trying to print each object with the while loop. I am very new to Javascript, so I am not sure if I mistakes in the external javascript file or if it is simply my implementation. Any help would be great. Thank you.
<html>
<head>
<link rel="stylesheet" href="object.css" type ="text/css" />
<title>Object Test</title>
<script type="text/javascript" src="MyObject.js">
var people = new Array(5);
</script>
</head>
<body>
<script type="text/javascript" src="MyObject.js">
var dad_info = setPersonInfo("Dad", "Kenneth Vavrock", 66, "Male");
dad_info = people[0];
var mom_info = setPersonInfo("Mom", "Connie Vavrock", 63, "Female");
mom_info = people[1];
var brother_info = setPersonInfo("Brother", "Craig Vavrock", 33, "Male");
brother_info = people[2];
var nephew_info = setPersonInfo("Nephew", "Sawyer Vavrock", 1, "Male");
nephew_info = people[3];
var dad_info = setPersonInfo("Step Mother", "Bonnie Vavrock", 70, "Female");
stepmother_info = people[4];
var count = 1;
while ( count >= 0 )
{
dad_info.getPersonInfo();
mom_info.getPersonInfo();
brother_info.getPersonInfo();
nephew_info.getPersonInfo();
stepmother_info.getPersonInfo();
count--;
}
</script>
</body>
</html>
Your "personInfo" object is malformed, it looks like a mix between a object literal and a class-like function. Have a look at this tutorial
Also, do not use an empty string " " as default value for anything (unless you really need to), there is really no point to it.
To solve the problem at hand.
var personInfo = function () {
this.personRelation = "";
this.personName = "";
this.personAge = 0;
this.personGender = "";
this.getPersonInfo = function () {
document.write( "<p>" + personInfo.personRelation + "<br />" );
document.write( "Name: " + personInfo.personName + "<br />");
document.write( "Age: " + personInfo.personAge + "<br />" );
document.write( "Gender: " + personInfo.personGender + "</p>" );
}
};
This way it can be used as such:
var people = []; // Create an empty array
// Create new person info for "dad"
var dad_info = new personInfo();
dad_info.personRelation = "...";
// [...]
people.push(dad_info); // Add dad_info to the array.
You should be all set.

How can i get rid of putting "new" before a function

I was wondering how can I make it posible to get rid of putting "new" before a function, for example:
new functionToDo("thingsToDo").iGotYouBruh("Halo Humans");
is there a posible way of doing this without the "new"?
here is the code I'm trying to use without the "new":
function local (title) {
var storeTitle = title;
this.addL = function(lString) {
var storeText = lString;
localStorage.setItem(storeTitle, storeText);
console.info("Locally stored " + storeTitle.toUpperCase() + " with " + storeText.substring(0, 10) + "... As text.");
};
this.removeL = function() {
localStorage.removeItem(storeTitle);
console.info("Locally removed " + storeTitle + ".");
};
this.getL = function () {
localStorage.getItem(storeTitle);
console.info("Locally got string of " + storeTitle + ": " + localStorage.getItem(storeTitle));
};
};
and here's what I would have to do to invoke the function:
new local("storedElement").getL();
This is possible by checking whether this is an instance of the function itself and returning a new instance otherwise:
function local (title) {
if (!(this instanceof local)) {
return new local(title);
}
var storeTitle = title;
this.addL = function(lString) {
var storeText = lString;
localStorage.setItem(storeTitle, storeText);
console.info("Locally stored " + storeTitle.toUpperCase() + " with " + storeText.substring(0, 10) + "... As text.");
};
this.removeL = function() {
localStorage.removeItem(storeTitle);
console.info("Locally removed " + storeTitle + ".");
};
this.getL = function () {
localStorage.getItem(storeTitle);
console.info("Locally got string of " + storeTitle + ": " + localStorage.getItem(storeTitle));
};
};
You could use JavaScript closures. In particular look at the "Using Closures for the Module Pattern" section of this webpage for a full description. The idea is to have the function return an literal with all the required methods. Any functions or variables that you want to be kept private are just local variables for the function.

Why Uncaught TypeError: Cannot read property 'length' of undefined?

<html>
<head>
<meta charset="utf-8">
<script src="dist/localforage.js"></script>
<script type="text/javascript">
"use strict"
var value1;
var $id = function(id) { return document.getElementById(id); }
var certArr;
window.onload = function()
{
$id("read-button").addEventListener("change", onChangeFile, false);
};
function onChangeFile(e) {
alert("aaaaddffd");
var file = e.target.files[0];
var reader = new FileReader();
reader.onload = function(e) {
var Oribuf = e.target.result;
var certArr = new Uint8Array(Oribuf);
alert(certArr);
};
reader.readAsArrayBuffer(file);
alert("aaaa: " + certArr);
readFile(certArr);
};
function readFile(arrData) {
// Here. Why this alert Undefined?
alert("bbbbb: " +arrData);
var key = 'STORE_KEY';
var r = document.getElementById('results');
localforage.setItem('cert1', 1234688, function(err, value) {
r.innerHTML += 'Saved: ' + value + '<br />';
});
localforage.getItem('cert1', function(err, value) {
// console.log(value);
r.innerHTML += 'Read: ' + value + '<br />';
} );
localforage.keys(function(err, keys) {
r.innerHTML += 'keys: ' + keys + '<br /><br />';
});
// Here. Why Uncaught TypeError: Cannot read property 'length' of undefined?
// How can I solved this problem. Help me.
alert(arrData.length);
alert("aad: " + arrData);
var text = "";
for(var i=0;i<arrData.length;i++)
text += " " + arrData[i];
localforage.setItem(key, text, function(e) {
var tmp_func = function(err, readValue) { r.innerHTML += 'Read: ' + readValue + '< br />'; };
r.innerHTML += 'Saved: ' + text + '<br />';
});
alert("ccccc");
};
function selectCert(sel){
if(parent.middle.document.getElementById("test").innerHTML == "1")
parent.middle.document.getElementById("test").innerHTML = "2";
else
parent.middle.document.getElementById("test").innerHTML = "1";
parent.middle.reload();
}
</script>
</head>
<body>
<ul>
<div id="results"></div>
<input id="read-button" type="file" />
<li id="qwer" onclick="selectCert(1)">1</li>
<li id="asdf" onclick="selectCert(2)">2</li>
</ul>
</body>
</html>
This is my HTML 5 and JavaScript code. It uses local storage, file API, etc.
Why does this code show me the following error?
Uncaught Type Error: Cannot read property 'length' of undefined
Two words: variable scope.
You've defined certArr in the beginning of your file using
var certArr;
... but you effectively re-declare it within your function by using the var keyword again:
var certArr = new Uint8Array(Oribuf);
To access the globally-declared version of certArr, remove the var keyword:
certArr = new Uint8Array(Oribuf);
remove this variable
var certArr;
Add This type variable
var certArr = new Uint8Array();
beginning of the code

JavaScript Rendering

Why doesn't this HTML/script (from "Secrets of the JavaScript Ninja") render?
http://jsfiddle.net/BCL54/
<html>
<head>
<script>
function outer(){
var a = 1;
function inner(){ /* does nothing */ }
var b = 2;
if (a == 1) {
var c = 3;
}
}
outer();
assert(true,"some descriptive text");
assert(typeof outer==='function',
"outer() is in scope");
assert(typeof inner==='function',
"inner() is in scope");
assert(typeof a==='number',
"a is in scope");
assert(typeof b==='number',
"b is in scope");
assert(typeof c==='number',
"c is in scope");
</script>
</head>
<body>
</body>
</html>
Because you didn't import Resig's necessary script containing the assert function :
<script>
function assert(pass, msg){
var type = pass ? "PASS" : "FAIL";
jQuery("#results").append("<li class='" + type + "'><b>" + type + "</b> " + msg + "</li>");
}
function error(msg){
jQuery("#results").append("<li class='ERROR'><b>ERROR</b> " + msg + "</li>");
}
function log(){
var msg = "";
for ( var i = 0; i < arguments.length; i++ ) {
msg += " " + arguments[i];
}
jQuery("#results").append("<li class='LOG'><b>LOG</b> " + msg + "</li>");
}
</script>
You can find those functions in the source of his site. Note that those function also ask for jQuery and some DOM elements into which to write. You'd better adapt to your page.
Until you're proficient enough in javascript to rewrite those functions, you'd better do the excellent exercises directly on the site.

JavaScript inheritance using prototype

I've been programming for over 20 years, but have recently turned to JavaScript. Despite spending hours trawling the web, the penny hasn't yet dropped with the prototype inheritance method.
In the simplified code below, I am trying to inherit the 'name' property from the Synthesizer 'class' to the Roland 'class', but the only way I seem to be able to access it is by using 'Synth2.prototype.name' rather than by 'Synth2.name' (which returns undefined). I would like to get the approach working so that I can use 'Synth2.name', as portability is a design requirement.
I would be very grateful for any assistance.
function Synthesizer(name) {
this.name = name;
}
function Roland(name) {
this.prototype = new Synthesizer(name);
}
Synth1 = new Synthesizer("Analogue");
Synth2 = new Roland("Fantom G6");
document.write(Synth1.name + '<br>');
document.write(Synth2.name + '<br>');
Thanks guys! (Now updated with call to super class)...
function Synthesizer(name) {
this.name = name;
this.rendersound = function () {
document.write("applying envelope to " + this.name + "<br>");
}
}
function Roland(name) {
Synthesizer.call(this, name);
this.prototype = Synthesizer;
this.Synthesizer_rendersound = this.rendersound;
this.rendersound = function () {
document.write("applying differential interpolation to " + this.name + "<br>");
this.Synthesizer_rendersound(this);
}
}
Synth1 = new Synthesizer("Analogue");
Synth2 = new Roland("Fantom G6");
document.write(Synth1.name + '<br>');
document.write(Synth2.name + '<br>');
document.write('<br>');
Synth1.rendersound();
document.write('<br>');
Synth2.rendersound();
document.write('<br>');
document.write('Synth1.prototype ' + Synth1.prototype + '<br>');
document.write('Synth2.prototype ' + Synth2.prototype + '<br>');
document.write('<br>');
document.write('Synth1.constructor ' + Synth1.constructor + '<br>');
document.write('Synth2.constructor ' + Synth2.constructor + '<br>');
You can do this by several way.
For example :
var Synthesizer = function(name){
this.name = name;
}
function Roland(name) {
Synthesizer.call(this, name); // you call the constructor of Synthesizer
// and force Synthesizer's this to be Roland's this
}
function clone(obj){
var ret = {};
for(var i in obj){ ret[i] = obj[i]; }
return ret;
}
Roland.prototype = clone(Synthesizer.prototype); // inheritance of public functions
For Function.prototype.call : https://developer.mozilla.org/en/JavaScript/Reference/Global_Objects/Function/Call
I believe you have to set the constructor's prototype, like this:
function Synthesizer(name) {
this.name = name;
}
function Roland(name) {
this.name = name;
}
Roland.prototype = new Synthesizer();
Synth1 = new Synthesizer("Analogue");
Synth2 = new Roland("Fantom G6");
document.write(Synth1.name + '<br>');
document.write(Synth2.name + '<br>');

Categories