JavaScript prototyping not working - javascript

I am following an online tutorial and I am at a prototype section. My alert comes back with
function() { return this.brand + ' ' + this.model; }
Anyone know the reason?
function Car(model, brand) {
this.model = model;
this.brand = brand;
}
Car.prototype.fullName = function() {
return this.brand + ' ' + this.model;
}
var s = new Car("G5", "Pontiac");
var full = s.fullName;
alert(full);

s.fullName is the function itself. If you wanted to call this function you would have to write s.fullName().

Related

second argument Object.create

My expectation was that I'd overwrite Vehicle's toString method with a new toString method. However this doesn't seem to work and I don't know why. Based on this article it looks like it should https://strongloop.com/strongblog/an-introduction-to-javascript-es6-classes/ (scroll down to Class Extending)
function Vehicle(make, year) {
this.make = make;
this.year = year;
}
Vehicle.prototype.toString = function() {
return this.make + ' ' + this.year;
};
var vehicle = new Vehicle('Toyota Corolla', 2009);
function Motorcycle(make, year) {
Vehicle.apply(this, [make, year]);
}
Motorcycle.prototype = Object.create(Vehicle.prototype, {
toString: function() {
return 'Motorcycle ' + this.make + ' ' + this.year;
}
});
Motorcycle.prototype.constructor = Motorcycle;
var motorcycle = new Motorcycle('harley', 2010);
console.log(motorcycle.toString()); //TypeError
The properties object given as the second argument of Object.create is supposed to contain property descriptors, not just values. This corrects the issue:
Motorcycle.prototype = Object.create(Vehicle.prototype, {
toString: {
configurable: true, enumerable: true, writable: true,
value: function() {
return 'Motorcycle ' + this.make + ' ' + this.year;
}
}
});
See also the MDN reference for Object.create.
to override the method, first point the Motorcycle's prototype constructor to itself. please read the comments in the below code .
Vehicle.prototype.toString = function() {
return this.make + ' ' + this.year;
};
var vehicle = new Vehicle('Toyota Corolla', 2009);
function Motorcycle(make, year) {
Vehicle.apply(this, [make, year]);
}
Motorcycle.prototype = Object.create(Vehicle.prototype); //Motorcycle.prototype is an object that inherits from Vehicle.prototype
// and is still pointing to the Vehicle constructor
Motorcycle.prototype.constructor = Motorcycle; // changing the constructor back to Motorcycle;
// method overridden after Motorcycle is pointing its own constructor
// now override the toString method
Motorcycle.prototype.toString=function(){
console.log("inside the motorcycle toString ")
}
var motorcycle = new Motorcycle('harley', 2010);
console.log(motorcycle.toString());

I want to call a method by calling outer function

I am currently learning about 'creating objects using the factory pattern' in Javascript. I have written this bit of code. I want to call the vehicle.getInfo(); function by calling the getVehicle(); function.
function getVehicle (theYear, theMake, theModel) {
var vehicle = new Object();
vehicle.year = theYear
vehicle.make = theMake
vehicle.model = theModel
vehicle.getInfo = function () {
return 'Vehicle: ' + this.year + ' ' + this.make + ' ' + this.model;
console.log('Vehicle: ' + this.year + ' ' + this.make + ' ' + this.model);
};
console.log(vehicle); // at this level, is there a way to call getInfo function without the actual "console.log(vehicle.getInfo());"
};
getVehicle("2014", "Tata", "Zest");
In the getVehicle() function, I'd like to console.log what the vehicle.getInfo() method returns. But I'd like to do this, without using console.log(vehicle.getInfo());.
Is that possible?
Can you please help me?

How do I create a new instance in a factory

I cannot figure out how to create a new instance in my factory. I created a constructor in the initial factory
app.factory('Tea',function(){
var Tea = function(name,description,price,caffeine, size ) {
this.name = name;
this.description = description;
this.price = price;
this.caffeine = caffeine;
this.size = size;
}
Tea.prototype.toString = function(){
var returnString='' ;
returnString += "name" + this.name + "\n" +
"description: " + this.description + "\n" +
"price: " + this.price + "\n" + "caffeine: " + this.caffeine + "\n" + "size: " + this.size;
return returnString
}
return Tea;
})
In my next factory I made sure to inject Tea so I would be able to create new instances. I created an object to store my array and created a method to push new instances
app.factory("DrinkList",function(Tea){
var beverageList = {
drinkLibrary: []
};
beverageList.newItem = function(){
beverageList.drinkLibrary.push(new Tea);
}
console.log(beverageList);
return beverageList;
})
In my controller I made sure to reference both factories that I created. However, drinkList.newItem is undefined.
app.controller('myController', function($scope,Tea,DrinkList ) {
$scope.drinkList = DrinkList.newItem();
console.log(DrinkList.newItem());
});
I have been working hard to get a better grasp of factories and controllers.
In my Factory I have created an instance
app.factory('Drink',function($http) {
var Drink = function(name,description,caffeineLevel) {
this.name = name;
this.description = description;
this.caffeineLevel = caffeineLevel;
}
return Drink;
})
This needs some cleaning up, but I realized that I need to use ng-model in my form. I have declared a form that can be reused and stored it inside of a function. I am creating new instances each time I click submit. There is more that I need to learn but this is a start.
app.controller('myController', function($scope,Drink,$http ) {
var init = function() {
$scope.defaultForm = {
beverageName: "",
description: "",
caffeine: ""
};
}
init();
// $scope.defaultForm = defaultForm;
$scope.allDrinkList = [];
$scope.drinkList= function(obj) {
var newdrink = new
Drink(obj.beverageName,obj.description,obj.caffeine);
$scope.allDrinkList.push(newdrink);
console.log($scope.allDrinkList);
init();
});

Can you add functions to Javascript classes with the prototype keyword?

I need to be able to add many functions to a Javascript class and I thought that you could do that with the className.prototype = function(){} but maybe I was not correct on this.
Car.prototype.toAnotherString = function () {
return this.model + " has done " + this.miles + " miles";
};
Question: Ist he prototype declared correctly in this class and can the class Car be declared some how with out the function name>
function Car( model, year, miles ) {
this.model = model;
this.year = year;
this.miles = miles;
this.toString = function () {
return this.model + " has done " + this.miles + " miles";
};
Car.prototype.toAnotherString = function () {
return this.model + " has done " + this.miles + " miles";
};
}
var civic = new Car( "Honda Civic", 2009, 20000 );
var mondeo = new Car( "Ford Mondeo", 2010, 5000 );
console.log( civic.toString() );
console.log( mondeo.toString() );
console.log( civic.toAnotherString() );
console.log( mondeo.toAnotherString() );
New Code:
So is this how the prototype should be added.
function Car( model, year, miles ) {
this.model = model;
this.year = year;
this.miles = miles;
this.toString = function () {
return this.model + " has done " + this.miles + " miles";
};
}
Car.prototype.toAnotherString = function () {
return this.model + " has done " + this.miles + " miles";
};
No, it's not: the line defining a method on Car.prototype should be placed separately:
function Car (model, year, miles) {
this.model = model;
this.year = year;
this.miles = miles;
this.toString = function () {
return this.model + " has done " + this.miles + " miles";
};
}
Car.prototype.toAnotherString = function () {
return this.model + " has done " + this.miles + " miles";
};
See, the major advantage of prototypes is ability to create a method function just once. But in your code, this line will be executed each time the Car constructor is called, creating a new instance of the function again and again. And that defeats the purpose of prototype.
But how this function will know about the object it's called for, you may ask? That's done with so-called function context trickery. See, when you call civic.toAnotherString(), inside toAnotherString this object will be referring to the same object as civic. And when you call mondeo.toAnotherString(), this will refer to the same object as mondeo.
But wait, there's more! You can call this method off one object, yet pass another one as its context (i.e., this):
civic.toAnotherString.call(mondeo); // or .apply(mondeo)
And, lo and behold, even though the method seems to belong to civic object, it'll actually act as though it was attached to mondeo one.
This - ability to switch this inside a method - is one of the most powerful JS features. I'd suggest studying this (really, no pun intended) tutorial on MDN up-to-bottom, as well as corresponding articles on Function.call, Function.apply and Function.bind.
Prototyping should be done outside of the initializing function, like this:
function Car( model, year, miles ) {
this.model = model;
this.year = year;
this.miles = miles;
this.toString = function () {
return this.model + " has done " + this.miles + " miles";
};
}
Car.prototype.toAnotherString = function () {
return this.model + " has done " + this.miles + " miles";
};

Is possible to bind a function result with angularJS?

I have this object:
function Boy(n,s,a)
{
this.name = n;
this.surname = s;
this.age = a;
this.getInfo = function(){
return this.name + ' ' + this.surname + ' (' + this.age + ')';
}
}
I want to do something like this:
{{ boy.getInfo() }}
and not like this:
{{ boy.name }} {{ boy.surname }} ({{boy.age}})
is it possible?
there are some tricks for doing something similar?
Absolutely! You can create an object and shove it into $scope just like anything else.
var NameController = function ($scope) {
$scope.boy = new Boy("Foo", "Bar", 32);
};
NameController.$inject = ['$scope'];
app.controller("NameController", NameController);
And then bind it in the UI just like so:
<h3>{{boy.getInfo()}}</h3>
Here is an example of binding to all three properties and seeing the result of the function: http://jsfiddle.net/jwcarroll/Pb3Cu/
You can bind $scope functions normally
function MyController($scope){
$scope.myfunc = function(){
return "test";
}
}
and then, in the view
{{ myfunc() }}
You can do something like:
function Boy(n,s,a)
{
this.name = n;
this.surname = s;
this.age = a;
this.getInfo = function(){
return this.name + ' ' + this.surname + ' (' + this.age + ')';
}
}
var boy = new Boy(n, s, a);
$scope.boy = function(){
return boy.getInfo();
}
And in you template just bind {{boy()}}.

Categories

Resources