What is an instance in JavaScript? Can anyone provide an example please?
Also, please explain your code.
An instance is simply an object that was created by a class (ES6) or constructor function. Here's an example:
function Person(name) {
this.name = name;
}
var john = new Person("John Doe");
console.log(john);
//john is an instance of Person - we can see this by using the instanceof operator
console.log(john instanceof Person);
JavaScript makes instances when defining variables, but these are only accessible by using typeof unless you explicitly use the new constructor to make your variable:
var str = "Foo Bar";
var num = 123;
var bool = true;
var obj = { abc: "def" }
var arr = [true, 1, "s"];
console.log(typeof str);
console.log(typeof num);
console.log(typeof bool);
console.log(typeof obj);
console.log(typeof arr);
console.log(typeof undefined);
console.log(typeof null);
There are a couple of tricks with typeof though - typeof [] == "object" because an array is an object with a few different methods. The other most common issue is typeof null == "object", because of a discrepancy when JavaScript was created between null and undefined.
If you want to find the constructor of any value, use constructor.name:
var str = "Foo Bar";
var num = 123;
var bool = true;
var obj = { abc: "def" }
var arr = [true, 1, "s"];
console.log(str.constructor.name);
console.log(num.constructor.name);
console.log(bool.constructor.name);
console.log(obj.constructor.name);
console.log(arr.constructor.name);
This trick also works with your own constructors and classes:
function Person(name) {
this.name = name;
}
var john = new Person("John Doe");
console.log(john.constructor.name);
When you create an object !
Example:
//instancing a image
var myImage = new Image(100, 100);
//Append in to body
document.querySelector("body").appendChild(myImage);
Simply put, in object-oriented programming, there are classes and objects. When you instantiate, or create an instance of a class, you get an object.
For example, take the following Car class:
function Car(myVin) {
this.vin = myVin;
}
let myHonda = new Car(“24A6733HJ42983C55”);
let myFord = new Car(“JJ67100473KL93228”);
let momsMinivan = new Car(“JF293HJL679904611”);
You just instantiated the Car class three times. Each is an instance.
ES2015 (aka ES6) introduces the class keyword, and constructors:
class Car {
constructor(myVin) {
this.vin = myVin;
}
}
This gets much more involved.
IMO, If you really want to learn OO programming, it’s really best to learn the C++ way first. There you’ll see classical inheritance at work, with concepts of constructors, private, protected, and public data members, design patterns, and other key concepts. This will build a solid foundation before you dive into the kluge that is Ecmascript classical inheritance.
Under the hood, Javascript has prototypical inheritance; Ecmascript plasters classical inheritance on top. It’s is a little weird and hacky, and have to do strange things with closures to achieve privacy.
See link below for a good lesson on OOP in C++.
https://m.youtube.com/watch?v=vz1O9nRyZaY
Let there be an object with properties id, name, and age. Now you want to create 100
objects that represent 100 people. Each person will have an id, name, and age.
You can create objects like:
var person1 = {
id: 1,
name: “p1”,
age: 20
};
var person2 = {
id: 2,
name: “p2”,
age: 21
};
….. And so on.
But instead of creating 100 objects by individually defining id, name, and age for all of
them, you create a standard template with properties id, name, and age. Then use
this template to create objects and set the required values.
This standard template can be seen as an object. Each time you create a new
object by using the new keyword, you create a new instance of an already-defined object with already-specified
properties.
For that, you can do this:
function people(id, name, age){
this.id = id;
this.name = name;
this.age = age;
}
let people1 = new people(1,'rani',20);
let people2 = new people(2,'rahul',21);
let people3 = new people(3,'adi',20);
.
.
.
and so on.
Here people1, people2, and people3 are the instances.
Related
Good afternoon. In C#, I create a class, then from this class I create a class variable (or object). And if I work with collections, then I add my new classes to the collection.
class person{
int id;
string name;
int age;
}
person myPerson = new person();
List<person> people = new List<person>();
people.add(myPerson);
As I understand it, in Javascript it happens in a different way. Here they do not like to create classes first, but directly add an object with data directly to the collection.
Tell me how Javascript is used to work with its own data types. What is the approach used?
C# is a strongly typed language, that is, you can declare a variable to be an instance of an object (or a primitive type) and then the language will throw an error if you violate this. So, a collection like this
List<person> people = new List<person>();
makes sense in C#. However, Javascript is a weakly typed language, that is, you can define a variable to be an instance of a class, but you cannot declare it. So, if you do something like this:
var myVariable = new MyClass();
then you have instantiated MyClass in your definition, but you only declared myVariable to be a variable.
In Javascript you can use arrays or objects as collections. Example using array:
class Rectangle {
constructor(height, width) {
this.height = height;
this.width = width;
}
}
var myCollection = []; //creating the collection
myCollection.push(new Rectangle(2, 3)); //adding an element to a collection
myCollection.push(new Rectangle(3, 2)); //adding an element to a collection
myCollection.push(new Rectangle(4, 4)); //adding an element to a collection
myCollection.push(new Rectangle(10, 15)); //adding an element to a collection
for (let rectangle of myCollection) {
console.log(`${rectangle.width} x ${rectangle.height}`);
}
Example using object
let myCollection = {
'first': 'a',
'second': 'b',
'third': 'c'
}
myCollection.fourth = 'd';
for (let key in myCollection) console.log(`${key} is ${myCollection[key]}`);
In Javascript, class is a syntactic sugar for functions. Example:
function MyClass(foo, bar) {
this.myFoo = foo;
this.myBar = bar;
}
let obj = new MyClass('abc', 'def');
console.log(obj);
You can work in JS (since ES6) exactly as in C# :
C# code :
class person{
int id;
string name;
int age;
}
person myPerson = new person();
List<person> people = new List<person>();
people.add(myPerson);
JS code :
class Person
{
constructor(id, name, age)
{
this.id = id;
this.name = name;
this.age = age;
}
}
myPerson = new Person("p1", "Tom", 54);
people = [];
people.push(myPerson);
Hope it helps ! :)
In Javascript (no jquery or other frameworks please) I want to test if 2 (or more) objects are the same type of object.
Here are some sample objects:
function Person (firstName, lastName, age) {
this.firstName = firstName;
this.lastName = lastName;
this.age = age;
}
function Animal (name, type, age) {
this.name = name;
this.type = type;
this.age = age;
}
var family = {};
family.father = new Person ('John', 'Doyle', 33);
family.mother = new Person ('Susan', 'Doyle', 32);
family.pet = new Animal ('Jodie', 'Cat', 2);
Given the above objects, I want a generic way to test if family.father, family.mother, and family.pet are from the same "type" of object. Can I test for the difference between Person and Animal in a generic way. Something like:
if ( sourceObject(family.father) === sourceOjbect(family.mother) ) {
alert('father and mother are the same type');
} else {
alert('father and mother are not from the same object... we could have problems.');
}
if (sourceObject(family.pet) !== sourceObject(family.father)) {
alert('the pet is a different type than the father');
} else {
alert('Perhaps it should be a child instead of a pet?');
}
or perhaps something like this:
if (isSameObject(family.pet, family.father)) {
alert('Perhaps it should be a child instead of a pet?');
} else {
alert('Father and pet are different.');
}
There is no "sourceObject" function, but I'm trying to find out if there IS something that does this or someone has found a quick way to do that comparison.
Note I am not looking to compare the data in the objects, I am looking to compare the type of Objects involved in the comparison. I need to do this without knowing the exact make up of the components involved. For example, in the above code I could test for a "type" property, but that requires foreknowledge of the objects. I am trying to write a generic function that will not necessarily know anything about the objects passed to it other than the objects them selves.
You can compare their constructors, as such
family.father.constructor == family.mother.constructor
MDC about constructors
https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Object/constructor
JSFiddle
http://jsfiddle.net/8LvN5/
Use constructors: http://jsfiddle.net/uME8m/
alert(family.father.constructor === family.mother.constructor); //true
alert(family.father.constructor === family.pet.constructor); //false
You can compare using .constructor or .constructor.name.
family.father.constructor == family.mother.constructor
family.father.constructor == family.pet.constructor
More on objects you can see here.
If you want to construct a function, you can do:
function sourceObject(obj) {
return obj.constructor; // you can return obj.constructor.name as well
}
You could compare the prototype, based on prototypical inheritance.
EDIT: might be better to compare constructors, for browser compatibility...
family.father.__proto__ == family.mother.__proto__ //EDIT: doesn't work in IE
//so
family.father.constructor == family.mother.constructor
so, in general:
function isSameObject(obj1, obj2){ //is same prototype - actaully;
return obj1.constructor == obj2.constructor
}
http://javascriptweblog.wordpress.com/2010/06/07/understanding-javascript-prototypes/
You can use Object.getPrototypeOf() (MDN Resource) to get the internal [[prototype]] property and then simply compare those two properties:
function isSameObject(obj1, obj2) {
return Object.getPrototypeOf(obj1) === Object.getPrototypeOf(obj2);
}
This should work in every modern browser, starting with IE9.
The advantage compared to the constructor property, is that the constructor property can be easily accidentally overridden, for instance when implementing inheritance:
function A() {
}
function B() {
}
B.prototype = Object.create(A.prototype);
var b = new B();
console.log(b.constructor); //A
FIDDLE
I known this has been asked hundreds of times, however, I can't seem to grasp the concept of prototype
Here's my sample script
var config = {
writable: true,
enumerable: true,
configurable: true
};
var defineProperty = function(obj, name, value) {
config.value = value;
Object.defineProperty(obj, name, config);
}
var man= Object.create(null);
defineProperty(man, 'sex', "male");
var person = Object.create(man);
person.greet = function (person) {
return this.name + ': Why, hello there, ' + person + '.'
}
var p=Object.getPrototypeOf(person);
alert(p.sex);//shows male
person.prototype.age=13;//why there is a error said the prototype is undefined? I thought it supposed be man object...
var child=function(){}
child.prototype.color="red";//why this line doesn't show error? both child and person are an object .
alert(child.prototype.color);//shows red
var ch=Object.getPrototypeOf(child);
alert(ch.color);//why it is undefined? it is supposed red.
Hope you can give me some helps... thanks.
Updated:
Thanks your guys kindly help, Based on Elclanrs's answer, Below is what I learned.
Function is the one of the build-in objects in javascript. the 3 format creation function object are equal.
var function_name = new Function(arg1, arg2, ..., argN, function_body)
function function_name(arg1, arg2, ..., argN)
{
...
}
var function_name=function(arg1, arg2, ..., argN)
{
...
}
So, that is why create a prototype chain we have to create a function and then call it with the new keyword .
Function.prototype is the reference to All the Function object prototype.
Cheers
The prototype property only exists on functions, and person is not a function. It's an object.
Here's what's happening:
var man = Object.create(null); // man (object) -> null
man.sex = "male";
var person = Object.create(man); // person (object) -> man (object) -> null
person.greet = function () { ... };
var p = Object.getPrototypeOf(person); // man (object) -> null
alert(p.sex); // p is the same object as man
person.prototype.age = 13; // person doesn't have a prototype
var child = function () {}; // child (function) -> Function.prototype
// -> Object.prototype -> null
child.prototype.color = "red"; // child has a prototype
var ch = Object.getPrototypeOf(child); // Function.prototype
alert(ch.color); // ch is not the same as color.prototype
// ch is Function.prototype
For more information I suggest you read this answer: https://stackoverflow.com/a/8096017/783743
Edit: To explain what's happening in as few words as possible:
Everything in JavaScript is an object except primitive values (booleans, numbers and strings), and null and undefined.
All objects have a property called [[proto]] which is not accessible to the programmer. However most engines make this property accessible as __proto__.
When you create an object like var o = { a: false, b: "something", ... } then o.__proto__ is Object.prototype.
When you create an object like var o = Object.create(something) then o.__proto__ is something.
When you create an object like var o = new f(a, b, ...) then o.__proto__ is f.prototype.
When JavaScript can't find a property on o it searches for the property on o.__proto__ and then o.__proto__.__proto__ etc until it either finds the property or the proto chain ends in null (in which case the property is undefined).
Finally, Object.getPrototypeOf(o) returns o.__proto__ and not o.prototype - __proto__ exists on all objects including functions but prototype only exists on functions.
I think you might be mixing concepts. Try grasping the concept of prototypes with classic prototype inheritance first, then you can get into all the new Object stuff.
In JavaScript, every object (numbers, strings, objects, functions, arrays, regex, dates...) has a prototype which you can think of as a collection of methods (functions) that are common to all current and future instances of that object.
To create a prototype chain you have to create a function and then call it with the new keyword to specify that it is a constructor. You can think of constructors as the main function that takes the parameters necessary to build new instances of your object.
Having this in mind, you can extend native objects or create your own new prototype chains. This is similar to the concept of classes but much more powerful in practice.
Similar to your example, you could write a prototype chain like this:
// Very basic helper to extend prototypes of objects
// I'm attaching this method to the Function prototype
// so it'll be available for every function
Function.prototype.inherits = function(parent) {
this.prototype = Object.create(parent.prototype);
}
// Person constructor
function Person(name, age, sex) {
// Common to all Persons
this.name = name;
this.age = age;
this.sex = sex;
}
Person.prototype = {
// common to all Persons
say: function(words) {
return this.name +'says: '+ words;
}
};
// Student constructor
function Student(name, age, sex, school) {
// Set the variables on the parent object Person
// using Student as a context.
// This is similar to what other laguanges call 'super'
Person.call(this, name, age, sex);
this.school = school; // unique to Student
}
Student.inherits(Person); // inherit the prototype of Person
var mike = new Student('Mike', 25, 'male', 'Downtown'); // create new student
console.log(mike.say('hello world')); //=> "Mike says: hello world"
In newer version of JavaScript (read EcmaScript) they added new ways to deal with objects and extend them. But the concept it's a bit different from classical prototype inheritance, it seems more complicated, and some more knowledge of how JS works underneath would help to really understand how it works, plus it doesn't work in older browsers. That's why I suggest you start with the classical pattern for which you'll find accurate and abundant information on the internet.
I think the difference has clicked in my head, but I'd just like to be sure.
On the Douglas Crockford page Prototypal Inheritance in JavaScript, he says
In a prototypal system, objects inherit from objects. JavaScript,
however, lacks an operator that performs that operation. Instead it
has a new operator, such that new f() produces a new object that
inherits from f.prototype.
I didn't really understand what he was trying to say in that sentence so I performed some tests. It seems to me that the key difference is that if I create an object based on another object in a pure prototypal system, then all the parent parent members should be on the prototype of the new object, not on the new object itself.
Here's the test:
var Person = function(name, age) {
this.name = name;
this.age = age;
}
Person.prototype.toString = function(){return this.name + ', ' + this.age};
// The old way...
var jim = new Person("Jim",13);
for (n in jim) {
if (jim.hasOwnProperty(n)) {
console.log(n);
}
}
// This will output 'name' and 'age'.
// The pure way...
var tim = Object.create(new Person("Tim",14));
for (n in tim) {
if (tim.hasOwnProperty(n)) {
console.log(n);
}
}
// This will output nothing because all the members belong to the prototype.
// If I remove the hasOwnProperty check then 'name' and 'age' will be output.
Is my understanding correct that the difference only becomes apparent when testing for members on the object itself?
Your assumptions are correct, but there is another pattern that Douglas doesn't talk much about - the prototype can be used for properties as well. Your person class could have been written as:
var Person = function(name, age) {
this.name = name;
this.age = age;
}
Person.prototype.name = null; //default value if you don't init in ctor
Person.prototype.age = null;
Person.prototype.gender = "male";
Person.prototype.toString = function(){return this.name + ', ' + this.age;};
In this case, iterating over properties of an instance of this class, as you do in your example, would generate no output for the 'gender' property.
EDIT 1:
The assignment of name and age in the constructor do make the properties visible by hasOwnProperty (thanks #matt for reminding me of this). The unassigned gender property would not be visible until someone sets it on the instance.
EDIT 2:
To further add to this, I present an alternative inheritance pattern - one that I have personally used for very large projects:
var inherits = function(childCtor, parentCtor) {
function tempCtor() {};
tempCtor.prototype = parentCtor.prototype;
childCtor.superclass = parentCtor.prototype;
childCtor.prototype = new tempCtor();
childCtor.prototype.constructor = childCtor;
};
var Person = function(name){
this.name = name;
}
Person.prototype.name = "";
Person.prototype.toString = function(){
return "My name is " + this.name;
}
var OldPerson = function(name, age){
OldPerson.superclass.constructor.call(this);
this.age = age
};
inherits(OldPerson, Person);
OldPerson.prototype.age = 0;
OldPerson.prototype.toString = function(){
var oldString = OldPerson.superclass.toString.call(this);
return oldString + " and my age is " + this.age;
}
This is a fairly common pattern with a small twist - the parent class is attached to the child via the "superclass" property permitting you to access methods/properties overridden by the child. Technically, you could replace OldPerson.superclass with Person, however that is not ideal. If you ever changed OldPerson to inherit from a class other than Person, you would have to update all references to Person as well.
EDIT 3:
Just to bring this full circle, here is a version of the "inherits" function which takes advantage of Object.create and functions exactly the same as I previously described:
var inherits = function(childCtor, parentCtor) {
childCtor.prototype = Object.create(parentCtor.prototype);
childCtor.superclass = parentCtor.prototype;
};
EDIT: This answer was originally a response to #jordancpaul's answer, which he has since corrected. I will leave the portion of my answer that helps explain the important difference between prototype properties and instance properties:
In some cases, properties are shared between all instances and you need to be very careful whenever you're declaring properties on the prototype. Consider this example:
Person.prototype.favoriteColors = []; //Do not do this!
Now, if you create a new Person instance using either Object.create or new, it doesn't work as you might expect...
var jim = new Person("Jim",13);
jim.favoriteColors.push('red');
var tim = new Person("Tim",14);
tim.favoriteColors.push('blue');
console.log(tim.favoriteColors); //outputs an array containing red AND blue!
This doesn't mean you can't ever declare properties on the prototype, but if you do, you and every developer who works on your code needs to be aware of this pitfall. In a case like this, if you prefer declaring properties on the prototype for whatever reason, you could do:
Person.prototype.favoriteColors = null
And initialize it to an empty array in the constructor:
var Person = function(name, age) {
...
this.favoriteColors = [];
}
The general rule when using this method is that default values for simple literal properties (strings, numbers, booleans) can be set on the prototype directly, but any property that inherits from Object (including arrays and dates) should be set to null and then initialized in the constructor.
The safer way is to only declare methods on the prototype, and always declare properties in the constructor.
Anyway, the question was about Object.create...
The first argument passed to Object.create is set as the prototype of the new instance. A better usage would be:
var person = {
initialize: function(name, age) {
this.name = name;
this.age = age;
return this;
},
toString: function() {
return this.name + ', ' + this.age;
}
};
var tim = Object.create(person).initialize("Tim",14);
Now the output will be the same as in your first example.
As you can see, it's a different philosophical approach from the more classical style of OOP in Javascript. With Object.create, the emphasis is on creating new objects from existing objects, rather than on the constructor. Initialization then becomes a separate step.
Personally I have mixed feelings about the Object.create approach; it's very nice for inheritance because of the second parameter that you can use to add additional properties to an existing prototype, but it also is more verbose and makes it so instanceof checks no longer work (the alternative in this example would be to check person.isPrototypeOf(tim)).
The main reason I say Object.create is verbose is because of the second parameter, but there are some useful libraries out there that address that:
https://github.com/Gozala/selfish
https://github.com/Raynos/pd
(and others)
I hope that was more enlightening than confusing!
What's the proper way to create an object (with its "namespaces" and such)?
1
//Company object
var Microsoft = {};
//Create an employee
Microsoft.employee = function(name) {
this.name = name;
}
or
2
//Company object
Apple = {
employee: function(name) {
this.name = name;
}
}
OR another way? Shoot.
Read something about prototypes and such. What's the proper way to do it; benefits and downsides?
First off, you forgot the var for Apple. But otherwise these are basically the same thing.
Secondly, in my examples I'm not going to use the attribute name since, when dealing with functions, the name is an empty string by default. At least in Node.js and Chrome. So I'll use empName instead.
In the Microsoft example you are making an empty object and then adding an attribute to it after the fact.
In the Apple example you are making an object with the attribute right away.
It's really just what makes the most sense to you, and which you prefer. Since they are, more or less, equivalent.
Now, this has nothing to do with prototypes. Here's an example of what you did:
var Apple = {
employee: function(empName) {
this.empName = empName;
}
};
Apple.employee('Hank');
Apple.empName; // 'Hank'
And here's how you would do this with an instance (using the new operator, and the prototype)
var Apple = function() {}; // base 'parent'
Apple.prototype.employee = function(empName) {
this.empName = empName
};
var a = new Apple();
a.employee('Hank');
a.empName; // 'Hank'
Apple.empName; // undefined
So prototype is used to add attributes to new instances of an object (using 'object' loosely). Note that to access employee in Apple, on this second example, you would have to do something like
Apple.prototype.employee('Hank'); // doesn't really do much
Apple.empName; // undefined
// but you can call the employee prototype with a bound variable
// you'd do this if you don't want to make an instance of Apple
// but still want to use one of it's prototypes
var obj = {};
Apple.prototype.employee.call(obj, 'Hank');
obj.empName; // 'Hank'
// a practical use of accessing a prototype method is
// when wanting to convert a function's arguments
// to an array. function arguments are like an array,
// but until turned into one they are not completely the same
var func = function() {
var args = Array.prototype.slice.call(arguments);
var sum = 0;
for(var i = 0, l = args.length; i < l; i++) {
sum += args[i];
}
return sum;
};
func(1); // 1
func(1, 2, 3, 4, 5); // 15
Hope that helps.
EDIT: Also, don't prototype objects (e.g. {} or Object). It's not safe to do this. Since, essentially, every variable in JavaScript is an object, then any prototypes you add to them will be available on all variables. So if you did Object.prototype.xyz = 12 then had var obj = { a: 1, b: 2, c: 3} and then tried for(var key in obj) { console.log(key); } you would result in the following logs: a, b, c and xyz ... which you wouldn't want.