javascript: object inheritance is not able understand - javascript

I am working inheritance in JavaScript, here, have created two objects. on the below code, when try to alert as alert(newOnj.whatAreYou());, now, it is working fine. But, when i try to alert alert(newOnj.whatAreYounow());, now, am getting error as 'newOnj.whatAreYounow is not a function'. Actually, have inherited parent class to child class as subGadget.prototype = new Gadget();. what is the thing that i haven't understood here? please
function Gadget() {
this.name = "Alex";
this.color = "red";
this.whatAreYou = function(){
return 'I am a ' + this.color + ' ' + this.name;
}
}
function subGadget() {
this.whatAreYounow = function(){
return 'Now, I am a ' + this.color + ' ' + this.name;
}
}
subGadget.prototype = new Gadget();
var newOnj = new Gadget();
alert(newOnj.whatAreYounow());

You need to write -
var newOnj = new subGadget();

Related

Why is this script not working? Nothing is shown in live preview

I'm trying to create a Car item with some values, but the function ShowCar doesn't show anything when I run the program...
<script>
function Car(model,price,topspeed,acceleration,consumption) {
this.model=model;
this.price=price;
this.topspeed=topspeed;
this.acceleration=acceleration;
this.consumption=consumption;
}
function ShowCar() {
document.write("Model:"+this.model+"<br>");
document.write("Price:"+this.price+"<br>");
document.write("Topspeed:"+this.topspeed+"<br>");
document.write("Acceleration:"+this.acceleration+"<br>");
document.write("Average Consumption:"+this.consumption+"<hr>");
}
</script>
</head>
<body>
<h1> Car List </h1>
<script>
Car1=new Car("Seat Ibiza","6.500 euros","190 km/h","9.7 s","5.3 l/100km");
Car1.ShowCar();
</script>
</body>
I would highly suggest reading up on OOP in javascript: https://developer.mozilla.org/en-US/docs/Learn/JavaScript/Objects/Object-oriented_JS
But for your questions, here's a working solution:
function Car(model, price, topspeed, acceleration, consumption) {
this.model = model;
this.price = price;
this.topspeed = topspeed;
this.acceleration = acceleration;
this.consumption = consumption;
this.ShowCar = function() {
document.write("Model:" + this.model + "<br>");
document.write("Price:" + this.price + "<br>");
document.write("Topspeed:" + this.topspeed + "<br>");
document.write("Acceleration:" + this.acceleration + "<br>");
document.write("Average Consumption:" + this.consumption + "<hr>");
}
}
var Car1 = new Car("Seat Ibiza", "6.500 euros", "190 km/h", "9.7 s", "5.3 l/100km");
Car1.ShowCar();
<h1>Car List </h1>
Car.prototype.ShowCar = function() {
document.write("Model:"+this.model+"<br>");
document.write("Price:"+this.price+"<br>");
document.write("Topspeed:"+this.topspeed+"<br>");
document.write("Acceleration:"+this.acceleration+"<br>");
document.write("Average Consumption:"+this.consumption+"<hr>");
}
You can set ShowCar as part of the prototype of Car, so you'll be able to call it from an object initialized by Car. However, I suggest you learning some ES6 and use a class instead.
You should change ShowCar to:
function ShowCar(car) {
document.write("Model:"+car.model+"<br>");
document.write("Price:"+car.price+"<br>");
document.write("Topspeed:"+car.topspeed+"<br>");
document.write("Acceleration:"+car.acceleration+"<br>");
document.write("Average Consumption:"+car.consumption+"<hr>");
}
Then call ShowCar(Car1). ShowCar is currently a separate function rather than a method of Car.
What's the 'this' reference to in your function Car? If you want to define javascript class, please refer to https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Classes
Please use the debugger of the browser to see what happened :)
Write a proper class if you want Object Oriented Programming:
class Car {
constructor(model, price, topspeed, acceleration, consumption) {
this.model = model;
this.price = price;
this.topspeed = topspeed;
this.acceleration = acceleration;
this.consumption = consumption;
}
ShowCar() {
document.write("Model:" + this.model + "<br>");
document.write("Price:" + this.price + "<br>");
document.write("Topspeed:" + this.topspeed + "<br>");
document.write("Acceleration:" + this.acceleration + "<br>");
document.write("Average Consumption:" + this.consumption + "<hr>");
}
}
Then you can create an object and call a method:
Car1=new Car("Seat Ibiza","6.500 euros","190 km/h","9.7 s","5.3 l/100km");
Car1.ShowCar();

"Private" in Javascript [duplicate]

This question already has answers here:
How do JavaScript closures work?
(86 answers)
Closed 6 years ago.
I am having problem identifying what and how is some property of "local" scope in JS. How is the property _secretNum "private" when it is clearly available outside the scope of the constructor as per below line.
document.write("Value of secretNum in secret: " + secret._secretNum
+ "<br/>");
The full code is as below,
<body>
<script type="text/javascript">
function SecretCode() {
var _secretNum = 78;
this.guessNum = function(num) {
if (num > _secretNum) {
return "Lower";
} else if (num < _secretNum) {
return "Higher";
} else {
return "You guessed it";
}
}
this.setNum = function(newNum) {
this._secretNum = newNum;
}
this.getNum = function() {
return this._secretNum;
}
}
var secret = new SecretCode();
for ( var prop in secret) {
document.write(prop + " : " + secret[prop] + "<br/>");
}
document.write("Is 70 the number: " + secret.guessNum(70) + "<br/>");
secret.setNum(9);
document.write("Value of secretNum in secret: " + secret.getNum()
+ "<br/>");
document.write("Value of secretNum in secret: " + secret._secretNum
+ "<br/>");
var secretAliter = new SecretCode();
secretAliter.setNum(17);
document.write("Value of secretNum in secretAliter : "
+ secretAliter.getNum() + "<br/>");
document.write("Value of secretNum in secretAliter : "
+ secretAliter._secretNum + "<br/>");
</script>
</body>
How is the property _secretNum "private"
It's not, I don't know where you got that code from, but it's broken.
The local variable declared by var _secretNum = 78 is private, but it's also being ignored by the setNum and getNum accessor methods. They're using this._secretNum, which is a completely different not private variable, that has nothing to do with the var _secretNum = 78 line. You can change the value of this._secretNum all you want, both directly and by using setNum, and it won't affect the variable _secretNum which guessNum uses.
The point of declaring var _secretNum as a local variable within your constructor function is that it is only accessible within that function, and by the functions that "close over" it when they are returned. Drop the this._secretNum from your accessors and just use _secretNum.
By way of example:
function MyConstructor() {
var _name = "bob" // Completely private
this._age = 45 // Not private
this.getName = function () {
return _name // public accessor for private variable
}
this.getAge = function() {
return this._age // public accessor for public property
}
}
var x = new MyConstructor();
x._name = "blah" // unrelated, ignored by getName
alert(x.getName()) // bob, not "blah"
x._age = 25 // overwrite age
alert(x.getAge()) // 25

Javascript OOP - inheritance, prototyping, callback function

I'm trying to use OOP in Javascript with inheritance, prototyping and callback functions. Would you please have a look at my JSfiddel http://jsfiddle.net/Charissima/5g6GV/.
The first problem is solved already in Javascript OOP - inheritance and prototyping, but unfortunately the callback functions don't work any more.
function Car () {
this.totalDistance = 0;
};
Car.prototype.putTotalDistance = function(distance) {
this.totalDistance = distance;
};
Car.prototype.getTotalDistance = function() {
return this.totalDistance;
};
Car.prototype.drive = function(distance) {
this.totalDistance += distance;
return this.totalDistance;
};
function RaceCar () {};
RaceCar.prototype = new Car();
RaceCar.prototype.parent = Car.prototype;
RaceCar.prototype.drive = function(distance) {
return this.parent.drive.call(this, (distance * 2));
};
var myText;
car = new Car;
raceCar = new RaceCar;
car.putTotalDistance(200);
myText = 'car totalDistance = ' + car.drive(10) + ' - ok<br>';
raceCar.putTotalDistance(200);
myText += 'raceCar totalDistance before drive = ' + raceCar.getTotalDistance() + ' - ok<br>';
myText += 'raceCar totalDistance after drive = ' + raceCar.drive(10) + ' - ok<br><br>';
car.putTotalDistance(0);
raceCar.putTotalDistance(100);
var drivingFunctions = [car.drive, raceCar.drive];
myText += drivingFunctions[0](10) + '<br>';
try {
myText += drivingFunctions[1](100) + '<br>';
}
catch(err) {
myText += err + + '<br>'
}
document.body.innerHTML = myText;
You've put the two functions in an array, so when called, this get changed.
You could use function bind :
var drivingFunctions = [car.drive.bind(car), raceCar.drive.bind(raceCar)];
Here is an example to help you understand:
function Man(name){
this.name = name;
this.getName = function(){
return this.name;
};
}
var man = new Man('toto');
var a = [man.getName];
console.log(a[0]());//undefined
a.name = 'titi';
console.log(a[0]());//titi, because this refers to the array.

How to Use Inheritance in JavaScript with Constructor Methods Returning Object Literals with Private Properties?

var Animal = function(config) {
config = config || {};
var name = config.name,
numLegs = config.numLegs,
weight = config.weight,
speed = config.speed,
sound = config.sound
return {
getName: function () {
return name;
},
getNumLegs: function () {
return numLegs;
},
getWeight: function () {
return weight;
},
getSpeed: function () {
return speed;
},
getSound: function () {
return sound;
},
run: function(distance, unit) {
unit = unit || 'miles';
return 'The ' + name + ' ran ' + distance + ' ' + unit;
},
speak: function() {
return 'The ' + name + ' says "' + sound + '"';
}
}
};
function DragonFly(config) {
var me = {},
numWings = config.numWings;
me.prototype = new Animal(config);
me.getNumWings = function() {
return numWings;
};
me.fly = function(distance, unit) {
unit = unit || 'miles';
return 'The ' + me.name + ' flew ' + distance + ' ' + unit;
}
return me;
}
var dragonFly = new DragonFly({
numWings: 2,
name: 'DragonFly',
numLegs: 6
});
Okay, coming from a PHP background, I don't understand inheritance in JavaScript one bit and I'd like some help.
Basically, here's what I'd like to be able to do with an instance of the dragonFly object:
dragonFly.getName(); // 'DragonFly'
dragonFly.fly(1, 'mile'); // 'The dragonfly flew 1 mile';
dragonFly.run(1, 'yard'); // 'The dragonfly ran 1 yard';
I'd also like to know how to override methods and call the parent of those overridden methods. What is wrong with my approach? All the examples above return undefined or throw an error. The main reason I went with the object-literal style is so I could make properties private.
the "fastest" way :
var Animal = function(config) {
config = config || {};
var name = config.name,
numLegs = config.numLegs,
weight = config.weight,
speed = config.speed,
sound = config.sound
return {
getName: function () {
return name;
},
getNumLegs: function () {
return numLegs;
},
getWeight: function () {
return weight;
},
getSpeed: function () {
return speed;
},
getSound: function () {
return sound;
},
run: function(distance, unit) {
unit = unit || 'miles';
return 'The ' + name + ' ran ' + distance + ' ' + unit;
},
speak: function() {
return 'The ' + name + ' says "' + sound + '"';
}
}
};
function DragonFly(config) {
var me = new Animal(config);
var numWings = config.numWings;
me.getNumWings = function() {
return numWings;
};
me.fly = function(distance, unit) {
unit = unit || 'miles';
return 'The ' + me.name + ' flew ' + distance + ' ' + unit;
}
return me;
}
var dragonFly = new DragonFly({
numWings: 2,
name: 'DragonFly',
numLegs: 6
});
You are mixing 2 kind of "inheritance" in your script , the "classical" inheritance and the prototypal inheritance , you cant do that unless you want to be in serious trouble. both work , both have their pros and cons. Stick to the "classical" inheritance , or object augmentation since you began with it.
An object literal doesnt have a prototype , functions have prototypes. That's why in my opinion js isnt "really" object oriented , but it can mimic object oriented langages
A good exercice now would be to try using functions and prototypes , though i'm not sure you could create private fields with that.
Edit : the me.name should be me.getName() since name is "private". i think.

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