This question already has answers here:
How do you create a method for a custom object in JavaScript?
(7 answers)
Closed 8 years ago.
How do you define JavaScript functions?
For example:
string.doSomething(); // OR
element.getSomeInfo();
I couldn't find anything on this, but maybe that's because it has a name I don't know.
EDIT
About four years later, let me rephrase this question to explain what I meant. I didn't know about objects, but essentially my question was "How do I define a function as a property of an object?". I wasn't necessarily differentiating between extending native Javascript classes (which is a bad idea) and just defining my own object with functions as properties.
So, to answer my own question, these are some different ways to do that:
const foo = {
bar: x => 1 / x;
}
so that, for example, foo.bar(4) returns .25. Another one:
function Rocket(speed){
this.speed = speed;
this.launch = () => {
this.speed = 'super fast and upwards';
}
}
So now one could define const Apollo = new Rocket('standing still'); and call Apollo.launch();
We can additionally extend such classes (including native ones) by
Rocket.prototype.stop = function(){
this.speed = 'Standing still';
}
and then call it using Apollo.stop();.
function Person(name) {
this.name = name;
}
Person.prototype.sayHi = function() {
return "Hi, I'm " + this.name;
}
var p = new Person("Jack");
p.sayHi() === "Hi, I'm Jack" // evaluates to true
Is this what you're looking for?
You can add a function as a member of an object.
For example:
var foo = {};
foo.sayHello = function () {
alert('hello');
}
foo.sayHello();
Add to prototype of the built-in String object (https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/String/prototype)
String.prototype.doSomething = function(){
console.log('bingo!');
}
var aaa = "testing123";
aaa.doSomething();
I am not sure what element you mean here though.
Related
This question already has an answer here:
Prototype chain: call "super" method over multiple levels
(1 answer)
Closed 4 years ago.
I'm trying to simulate the "class" syntax in JavaScript. How do I call the function from an object's prototype when redefining it? In the example, I'm trying to extend the Bear object's sound function.
function Animal(name) {
this.name = name;
}
Animal.prototype.sound = function() { console.log("I'm " + this.name); }
function Bear(name) {
Animal.call(this, name)
}
Bear.prototype = new Animal();
Bear.prototype.sound = function() { this.prototype.sound(); console.log("growl!"); }
const cal = new Bear("Callisto")
cal.sound() // Should be: I'm Callisto growl!
console.log(cal)
You could directly access the method on the Animals prototype:
Bear.prototype.sound = function() {
Animal.prototype.sound.call(this);
console.log("growl!");
};
This question already has answers here:
Organize prototype javascript while perserving object reference and inheritance
(3 answers)
Closed 5 years ago.
I'm having a hard time figuring out how to access the parent's class scope. My code is as follows
var Class = function(){
this.smth = 3;
}
Class.prototype.setters = {};
Class.prototype.setters.smth = function(smth){
this.smth = smth;
}
However this of course does not work, it affects smth to Class.setters. I tried using .bind(Class.prototype); to no avail.
Does anyone have a solution? I've got plenty of sub-methods.
When you call someInstance.setters.smth(...) the this of the function call is the settings object, and there's no way for that smth function to know how the settings object is being accessed, only that it is being provided as a this.
You could keep your desired syntax but at significant memory cost by creating a unique setters object for each instance, inside your constructor:
var Class = function(){
var thisClassInstance = this;
this.smth = 3;
this.setters = {};
this.setters.smth = function(smth){
thisClassInstance.smth = smth;
}
}
This is suboptimal because you lose the benefits of prototype inheritance; each instance has a suite of unique functions in the setters object and nothing is shared.
A leaner way would be to have each instance has its own setters object that knows the identity of its parent instance, but that setters object inherits all its methods from a prototype setter object:
// all `setters` object inherit their methods from this object
var settersPrototype = {};
// methods on the `setters` set values on `this.parent`
settersPrototype.smth = function(smth){
this.parent.smth = smth;
}
var Class = function(){
this.smth = 3;
// this instance has a `setters` object that inherits all its methods
this.setters = Object.create(settersPrototype);
this.setters.parent = this;
}
This way, you have a mild memory cost of a unique { parent: ... } object per instance, but there is a single prototype version each setter function, present on the one-and-only settersPrototype object.
You can do this a few ways. There are others with your prototype approach, but this might make it a bit more clear:
ES5
var TestClassEs5 = function(){
// With ES5, store the outer this to variable to preserve
var self = this;
this.smth = 3;
this.setters = {
smth: function (smth) {
self.smth = smth;
}
}
return this;
}
ES6
const TestClassEs6 = function(){
this.smth = 3;
// Using a fat arrow syntax binds the function to the lexical scope
this.setters = {
smth: (smth) => this.smth = smth
}
return this;
}
JS Bin:
http://jsbin.com/qugatacive/edit?js,console
Closed. This question is opinion-based. It is not currently accepting answers.
Want to improve this question? Update the question so it can be answered with facts and citations by editing this post.
Closed 6 years ago.
Improve this question
I've been traveling deeper into the JS world and came across 3 different ways I could develop the frontend cart of a website:
Constructor with Prototype Functions
var cart = function(){
this.items = {}
}
cart.prototype.increaseItemQty = function(partNumber){
if(this.items[partNumber]){
this.items[partNumber].qty += 1;
} else {
this.items[partNumber] = {
qty : 1
};
}
}
cart = new cart();
Methods Within the Constructor
var cart2 = function(){
this.items = {};
this.increaseItemQty = function (partNumber) {
if(this.items[partNumber]){
this.items[partNumber].qty += 1;
} else {
this.items[partNumber] = {
qty : 1
};
}
}
}
cart2 = new cart2();
Object Methods
var cart3 = {
items : {},
increaseItemQty : function(partNumber){
if(this.items[partNumber]){
this.items[partNumber].qty += 1;
} else {
this.items[partNumber] = {
qty : 1
};
}
}
};
If I know that there will only be one instance of the cart, then should I just use the Object Method method? Is there any reason why I should still use a constructor?
Yes, there is a (minor) reason you shouldn't use a constructor: the instance will hold a reference to the constructor function via instance.[[Prototype]].constructor, and thus it won't be garbage collected. It will waste memory uselessly because you won't instantiate it again.
var cart = new function(){ /* ... */ };
console.log(cart.constructor); // Won't be garbage-collected
If you prefer a function approach you can still do something like the following. This way you can also have private variables.
var cart = function() {
// You can add private variables here
this.items = {};
this.increaseItemQty = function(partNumber) {
if(this.items[partNumber]) {
this.items[partNumber].qty += 1;
} else {
this.items[partNumber] = {
qty : 1
};
}
};
return this;
}.call({});
cart.increaseItemQty(0);
console.log(cart.items);
You should use constructor functions if you think that you'll need to initialize your carts with some defaults or do some initialization stuff that should be mandatorily performed prior to use the whole object.
In the other hand, maybe you're missing Object.create. You don't need constructor functions to implement a prototype chain:
var A = {
doStuff() {
console.log("I did some stuff");
}
};
var B = Object.create(A);
B.moreStuff = function() {
console.log("I did even more stuff");
};
// A new object where its prototype is B
var someB = Object.create(B);
b.doStuff(); // ...from A
b.moreStuff(); // ...from B
To create an object, basically it can be created using the constructor 'function' or simply with the object notation '{ }' which both are exactly doing the same in your case above.
The main advantage with the constructor pattern is, it will be more useful if you need to deal with the arguments when you create an instance as below.
function Car(model) {
this.model = model;
}
Or if you need to use private variables and methods as below.
function Car() {
// private variable
var modelYear = 1990;
// private method
var isEligibleToInsurance = function() {
return this.modelYear > modelYear;
};
this.isLatestModel = function() {
return isEligibleToInsurance();
};
}
This way you can have a private method and use the same inside the public methods. When you use object notation, you can't have a common private method used across all the public methods and when you use 'prototype', you can't use the private methods declared inside the constructor.
Note: When you name the class, you can follow pascal case to name it as "Car" instead of "car" and create instances with camel case as "var car = new Car();"
Difference between cases 1 and 2: in case 1, you assign methods to all instances of cart class or its child classes, in case 2 only to instances of cart.
Difference between cases 2 and 3: in case 3, furthermore, you create just one instance just by using object initializer expression and assign some methods as its properties.
Now, if to answer your question, if you have only one instance, theoretically it will be enough for you to add method as its property like in case 3. Or even write procedural-style functions.
But in terms of extensibility and reusability of code, the best practise is utilize methods by creating classes. Classes in javascript are sets of objects with the same prototype. So the best is to add methods as properties of the prototype object like in case 1. If you will have only one instance - there will be no difference to you. But since cart should be pretty heavy and complex class, whenever requirements to your cart change, case 1 will be the most convenient.
Closed. This question is opinion-based. It is not currently accepting answers.
Want to improve this question? Update the question so it can be answered with facts and citations by editing this post.
Closed 7 years ago.
Improve this question
I'm writing a small example to call function getAge() to display age via an object.
I've 3 ways to do that:
"use strict";
var personClass = class {
static getAge() {
return 18
}
};
var personJSON = {
getAge: function () {
return 18
}
};
function personFunc() {
var getAge = function () {
return 18
};
// set a flag to point to getAge function
this.getAge = getAge()
}
$('#btn1').click(function () {
alert(personClass.getAge())
});
$('#btn2').click(function () {
alert(personJSON.getAge())
});
$('#btn3').click(function () {
var p = new personFunc();
alert(p.getAge)
});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<button id="btn1">Get age via class</button>
<button id="btn2">Get age via json</button>
<button id="btn3">Get age via function</button>
My question: What's the best way? And why?
It depends on the actual problem you have to solve and the style of programming you're using. If you tend to use an object oriented approach and want to benfit from it's features like inheritance you might want to model a person as
function Person(){
var age = 18;
this.getAge = function() {
return age;
}
}
var person = new Person();
alert(p.getAge());
Or as a class
class Person {
constructor() {
this.age = 18;
}
getAge() {
return this.age()
}
}
If you prefer a more functional style, you'll write pure and independent functions that perform some action on some data:
// does not make much sense in this age of a person context
function age(obj, dateFn) {
return dateFn() - obj.born;
}
var person = { born : new Date(/* */) }
var animal = { born : new Date(/* */) }
alert(age(person, Date.now));
alert(age(animal, Date.UTC));
For the example of getAge, any kind of static function does not make any sense (your first example), since age is the property of some object. So you'll need an instance of an object which you can use to call a method, or to pass to a function.
I would recommend the most simple form:
var personJSON = {
getAge: function () {
return 18;
}
};
It already creates a well-defined object with the desired properties, it scales well and it is not encumbered by red-tape boilerplate code.
Good code already did so for years and it is a very well proven style. It is readable and compact.
What you will NOT get from this are the new advanced features of ES6 class definitions which might be required in more advanced cases.
Warning! This is just my personal, biased opinion:
I, for one, will not use class definitions at all, instead I will leverage this style and lambdas, as I've always done in 10+ years. I'm also contrary to the introduction of syntactical sugar in Javascript just to let it look like other languages. I prefer the prototypical paradigm.
I'm just saying how I would use the three. This is not meant to be an absolute answer, this is the way I see things. And I'm interested to see other people points of view on this.
class
I'd only use this key word in case I want to instantiate multiple times this object. (Only available in ECMAScript 6)
"use strict"
class Animal {
constructor(name) {
this.name = name;
}
speak() {
console.log(this.name + ' makes a noise.');
}
}
class Dog extends Animal {
speak() {
console.log(this.name + ' barks.');
}
}
var bobby = new Dog("Bobby");
bobby.speak();
JSON
I'd only declare a JSON when I'm only going to instantiate it once.
var Game = {
run: function() {
//...
},
stop: function() {
//...
},
pause: function() {
//...
},
maxPlayer: 4,
rooms: [{
roomName: "Room1",
playerNames: ["Player1", "Player2"]
}, {
roomName: "Room2",
playerNames: ["Player1", "Player2", "Player3"]
}]
};
function
You're using it more like a class substitute here. By using new keyword you can instantiate this function as a class as many times as you want. (Which a lot a people do and that's ok ! Mostly because the keyword class is only available in ECMAScript 6)
var Person = function (firstName) {
this.firstName = firstName;
};
Person.prototype.sayHello = function() {
console.log("Hello, I'm " + this.firstName);
};
var person1 = new Person("Alice");
person1.sayHello();
I would suggest something like this. I'd be curious to hear other people's feedback.
//Convention says use capital case if declaring a function as a class.
function Person(age){
//Optional: allow the developer to pass in an age when creating the object
//Otherwise default to 18
this.age = age? age: 18; //ternary operator
//function declaration.
this.getAge = function() {
return this.age;
}
}
$('#btn3').click(function () {
var p = new Person();
alert(p.getAge()) //Alert 18
var p2 = new Person(15);
alert(p2.getAge()) //Alert 15
});
My reasoning for this is that this is an objected oriented way of doing it.
The capital case lets you know that this function is intended to be used with a with the new keyword.
Is reusable - you can have multiple, different Person objects, with different ages, without having to declare the methods each time for each one.
Syntax and usage is similar to object oriented languages like Java which one might already be familiar with.
The last way that you wrote is the best
function personFunc() {
var getAge = function () {
return 18
};
// set a flag to point to getAge function
this.getAge = getAge()
}
Buth there is a better one by perfomance, but little complex by writing. It is like TypeScript or Babel compiles it's classes to JavaScript.
function PersonClass() {
this.age = 18;
}
PersonClass.prototype.getAge = function () {
return this.age;
};
usage is the same:
var person = new PersonClass();
person.getAge();
But to write like this by yourself is little time-consuming. So I think that the best thing for now is to use ES6 classes and compile them with TypeScript or Babel.
So, my opinion is the best way to write like this:
class PersonClass {
private age = 18;
getAge() {
return this.age;
}
}
This question already has answers here:
What techniques can be used to define a class in JavaScript, and what are their trade-offs?
(19 answers)
Closed 8 years ago.
I come from C, C++, Java background. I want to create a struct/ class with some attributes and methods like:
MyClass{
string text;
array characters;
printText(){
print text;
}
printLen(){
print characters.length();
}
}
So next time I can create an object like above by just calling its constructor. How do I implement this in JavaScript? I am new to the programming principles followed in javascript, I want to create a custom data type here for reusability.
function MyClass () {
this.text = "";
this.characters = [];
}
MyClass.prototype.printText = function () {
console.log(this.text);
};
MyClass.prototype.printLen = function () {
console.log(this.characters.length);
};
var instance = new MyClass();
instance.text = "test";
instance.characters.push('a');
instance.characters.push('b');
instance.printText();
instance.printLen();