Unable to get property of undefined or null reference - javascript

I am getting following error
Unable to get property 'showMsg' of undefined or null reference
on the last line of below code:
Function.prototype.showMsg = function () {
alert("This is a sample message.");
};
function Person() {
this.name = "Mahesh";
};
var personObj = new Person();
personObj.prototype.showMsg();
Actually I should be able to access showMsg() from Person instance since I have added it to the Function.prototype. Then why I am getting this error?

Well You Understand it all Wrong
Function.prototype.showMsg = function () {
alert("This is a sample message.");
};
function Person() {
this.name = "Mahesh";
};
var personObj = new Person();
personObj.prototype.showMsg();
First you prototyped the function class, then create a custom class called Person, then you create an instance of Person. And then you are calling the very blue print which is showMsg which is 2 Mistakes 1 showMsg is not Bounded into the Person and then to call it if its bounded you call it directly like this
personObj.showMsg()
Will To Make This Script Work from my point of View if i got you write
write it like this ->
function Person() {
this.name = "Mahesh";
};
Person.prototype.showMsg = function () {
alert("This is a sample message.");
};
var personObj = new Person();
personObj.showMsg();
my script bound the showMsg Directly to the Person Class if you need it through the Person Object and Through The Function Class To Then you have to inherit from Function Class Like This
Function.prototype.showMsg=function () {
alert("This is a sample message.");
};
function Person() {
this.name = "Mahesh";
};
Person.prototype = Function;
Person.prototype.constructor = Person;
var personObj = new Person();
personObj.showMsg();
Regards

Related

Javascript prototype method "Cannot set property"

I'm always getting Cannot set property 'saySomething' of undefined but why?
Am I making a mistake somewhere?
var Person = new Object();
Person.prototype.saySomething = function ()
{
console.log("hello");
};
Person.saySomething();
Debugging tip: You get this ..of undefined errors when you try to access some property of undefined.
When you do new Object(), it creates a new empty object which doesn't have a prototype property.
I am not sure what exactly are we trying to achieve here but you can access prototype of function and use it.
var Person = function() {};
Person.prototype.saySomething = function() {
console.log("hello");
};
var aperson = new Person();
aperson.saySomething();
The prototype property exists on functions, not on instantiated objects.
var Person = new Object();
console.log(Person.prototype); // undefined
var Person2 = function () {}
console.log(Person2.prototype); // {}
This is useful because things put on the prototype of a function will be shared by all object instances created with that function (by using new).
var Person = function() {};
Person.prototype.saySomething = function() {
console.log("hello");
};
console.log(
new Person().saySomething === Person.prototype.saySomething // true. they are the same function
);
If all you want is to add a method to the person object, there's no need for a prototype:
var Person = {};
Person.saySomething = function() {
console.log("hello");
};
Person.saySomething();
You can even use object literal syntax:
var Person = {
saySomething: function() {
console.log("hello");
}
};
Person.saySomething();
i was trying out some code thought of posting it, might help others.
<script>
var MODULE = {};
MODULE = (function (my) {
my.anotherMethod = function () {
console.log("hello ");
};
my.newMethod = function(){
console.log("hi new method ");
}
return my;
}(MODULE));
MODULE.anotherMethod();
MODULE.newMethod();
</script>
And please not var MODULE ={}, if this is not initialized with {} then it give cannot set property.
I know i am late to the party but as you see there is no satisfying answer available to the question so i am providing my own.
In your case when you write
var Person = new Object();
you are creating an instance of Object type.
You can add a property using prototype property to the Object, not to the instance of Object.which you can use by the instance laterly.
so you can define like
Object.prototype.saySomething = function ()
{
console.log("hello");
};
now you can call it like this.
Person.saySomething();
You can check here.
var Person = function(name) {
this.canTalk = true;
this.name = name;
};
Person.prototype.greet = function() {
if (this.canTalk) {
console.log('Hi, I am ' + this.name);
}
};
bob = new Person('bob');
bob.greet();

Can i create an object trough parent in js

I am new to OOJS and I'm a little confused trying to understand inheritance, I created two simple classes, person and student that inherit from person, is there an option to create student by passing data in the parent's constructor? if it's possible, how to do it ? can a child get all the properties and methods from the parent or only the methods?
**the fname and lName in the alert are undefined
function Person(fNme, lName) {
this.fname = fNme;
this.lName = lName;
}
Object.prototype.go = function() {
alert("I am going now last time you see "+ this.lName);
}
function Student() {
this.study = function () {
alert("I am studing !");
}
}
Student.prototype = new Person();
var s1 = new Student("sam", "bubu");
alert(s1.fname +"+"+ s1.lName)
you can use constructor stealing.
function Student(fName,lName) {
Person.call(this,fName,lName);
this.study = function () {
alert("I am studing !");
}
}
when you call Student constructor you can pass along arguments to Person() with call() to initialize variables in Person
This is done by just calling the parent constructor
function Student(fName, lName, whateverelse) {
Person.call( this, fName, lName ); // call base class constructor function
this.study = function () {
alert("I am studing !");
}
}

How to invoke function inside another function in JavaScript as I've mentioned below

I've a code
function person() {
name = "David";
hello = function() {
console.log("I'm in hello");
};
}
And I want to invoke hello function from outside. How can I achieve it?
Assign hello (and name) to this in person:
function Person() {
this.name = "David";
this.hello = function() {
console.log("I'm in hello");
};
};
Then, you can access the function like this:
var p = new Person();
p.hello();
this assigns the variables to the Person. This prevents the variables from polluting the global scope.
You could also pass parameters to Person:
function Person(name) {
this.name = name;
this.hello = function() {
alert("Hello! I'm " + this.name + '!');
};
};
var p = new Person("Fred");
p.hello();
function person() {
this.name = "David";
this.hello = function() {
console.log("I'm in hello");
};
}
var personObj = new person();
personObj.hello ();
What you can do is that:
function person() {
name = "David";
this.hello = function() {
console.log("I'm in hello");
};
}
var johnny = new person();
johnny.hello();
See this nice article: http://www.phpied.com/3-ways-to-define-a-javascript-class/
function person() {
name = "David";
this.hello = function() {
console.log("I'm in hello");
};
}
var p = new person();
p.hello();
or
function person() {
var obj={};
obj.name = "David";
obj.hello = function() {
console.log("I'm in hello");
};
return obj;
}
var p = person();
p.hello();
This is for your curiosity and clarity :)
You have declared global variables inside a function. Untill you execute the function the global variables will not come into existence and would not be accessible. Once you call the function the globals would be defined and initialized properly and thereafter you can call them from any scope in the javascript.
function person() {
name = "David";
hello = function() {
console.log("I'm in hello");
};
}
Now, in order to call hello from outside without using this or class pattern, you will have to first make a call (method execution) to person method. see this:
either person(); or console.log(person()); but not console.log(person);
and then you can easily call hello();
NOTE: This is for David's understanding purpose. Please do not use
arbitrarily global variables in your javascript.

call parent ctor from ctor of inheriting class

Is it valid to instead of doing this
function Animal(name, numLegs) {
this.name = name;
this.numLegs = numLegs;
}
Animal.prototype.sayName = function() {
console.log("Hi my name is " + this.name);
};
function Penguin(name) {
this.name = name;
this.numLegs = 2;
}
Penguin.prototype = new Animal();
var penguin = new Penguin("Tux");
penguin.sayName();
do that?
function Animal(name, numLegs) {
this.name = name;
this.numLegs = numLegs;
}
Animal.prototype.sayName = function() {
console.log("Hi my name is " + this.name);
};
function Penguin(name) {
return new Animal(name, 2);
}
Penguin.prototype = new Animal();
var penguin = new Penguin("Tux");
penguin.sayName();
I find the second version more elegant and hoped both version were equivalent in their results, but for the second one codeacademy tells me
Oops, try again. Make sure to create a new Penguin instance called penguin!
while the first one is accepted.
This is not the correct way to call the parent constructor:
function Penguin(name) {
return new Animal(name, 2);
}
The correct way is as follows:
function Penguin(name) {
Animal.call(this, name, 2);
}
The reason is because of the way new works:
Let's say you have a function called ABC.
When you execute new ABC JavaScript creates an instance of ABC.prototype and binds it to this inside of the function ABC which is why you can add properties to this inside ABC.
The constructor function returns this by default unless you return another object explicitly.
The reason Codecademy complains about your code is because you're returning a new Animal(name, 2) which is not an instanceof Penguin.
As I said before the correct way to call the parent constructor is to use ParentConstructor.call(this, arg1, arg2, ...). In this case we are setting the this inside the parent constructor to the same value as this inside the current constructor (which is the instance created by new).
If you want to write elegant code then try this on for size:
function defclass(prototype) {
var constructor = prototype.constructor;
var instance = prototype.instance = function () {};
constructor.prototype = instance.prototype = prototype;
return constructor;
}
function extend(parent, keys) {
var supertype = keys.super = parent.prototype;
var prototype = new supertype.instance;
for (var key in keys) prototype[key] = keys[key];
return defclass(prototype);
}
Using defclass and extend you could rewrite your code as follows:
var Animal = defclass({
constructor: function (name, numLegs) {
this.name = name;
this.numLegs = numLegs;
},
sayName: function () {
console.log("Hi my name is " + this.name);
}
});
var Penguin = extend(Animal, {
constructor: function (name) {
this.super.constructor.call(this, name, 2);
}
});
var penguin = new Penguin("Tux");
penguin.sayName();
How cool is that?
I think the difference is that constructor functions don't return a value. So if you call
new Penguin('bla')
it is not the function Penguin that returns the new Object, it is the new that returns the new Object. So if you let Penguin() return a new Object this will conflict with the new-keyword.
If you want to call the parent-constructor, you can do that as follows:
function Penguin(name) {
Animal.call(this, name, 2);
}
Just additionally: When you assign the prototype of Animal to its sub-prototype Penguin, you call the Function in your example without its paramers. There is a cleaner way to do that:
Penguin.prototype = Object.create(Animal.prototype);
After that you have lost the constructor function of Penguin so you need to reassign it like this:
Penguin.prototype.constructor = Animal;
This is explained in detail here:
https://developer.mozilla.org/en-US/docs/Web/JavaScript/A_re-introduction_to_JavaScript
and
https://developer.mozilla.org/en-US/docs/Web/JavaScript/Introduction_to_Object-Oriented_JavaScript
In the second example you are NOT returning an instance of Penguin but an instance of Animal. if you want to add more functionality to penguin you need to decorate the Animal class with extra functionality.
function Penguin(name) {
var self = new Animal(name, 2);
self.penguinFunction = function (){
//do something here
}
return self;
}

How to access a superclass instance variable from the subclass?

everybody!
Suppose that I have this class in JavaScript:
function Animal()
{
this.name = "name";
}
Animal.prototype.someMethod =
function ()
{
}
and this subclass:
function Cat()
{
Animal.call(this);
}
Cat.prototype = new Animal();
Cat.prototype.constructor = Cat;
Cat.prototype.someMethod =
function ()
{
// I want to access the superclass "name" instance variable here
}
What's the syntax to access the superclass "name" instance variable from the overriden method in the Cat class?
Thank you.
Marcos
UPDATED: Well, if you want to see the real code, here it is. The problem is with the abc variable (just a test variable that I was using).
var pesquisaAcervo;
$(
function ()
{
carregadoBase();
if ($("#form\\:tipoPesquisa").val() == "SIMPLES")
{
pesquisaAcervo = new PesquisaAcervoSimples();
}
else
{
pesquisaAcervo = new PesquisaAcervoAvancada();
}
pesquisaAcervo.paginaCarregada();
}
);
// --- PesquisaAcervo ----------------------------------------------------------
function PesquisaAcervo()
{
$("*:visible[id^='form:materiaisPesquisa']").
change(this.materialMudado).keyup(this.materialMudado);
this.abc = 10;
}
PesquisaAcervo.prototype.paginaCarregada =
function ()
{
$("#cabecalhoPesquisa a").click(this.exibirDicasPesquisa);
$("#cabecalhoPesquisa select").
change(function () {$("#form").submit();}).
keyup(function () {$(this).change();});
$("*:visible[class*='foco']").focus().select();
};
PesquisaAcervo.prototype.materialMudado =
function ()
{
};
PesquisaAcervo.prototype.exibirDicasPesquisa =
function ()
{
};
// --- PesquisaAcervoSimples ---------------------------------------------------
function PesquisaAcervoSimples()
{
PesquisaAcervo.call(this);
$("#form\\:campos").change(
function ()
{
$("#textoCampo").text($("#form\\:campos :selected").text() + ":");
}
).keyup(function () {$(this).change();}).change();
$("#pesquisaSimples a").click(
function ()
{
pesquisaAcervo = new PesquisaAcervoAvancada();
$("#pesquisaSimples").parent().hide();
$("#pesquisaAvancada").parent().show();
$("#form\\:tipoPesquisa").val("AVANCADO");
}
);
}
PesquisaAcervoSimples.prototype = new PesquisaAcervo();
PesquisaAcervoSimples.prototype.constructor = PesquisaAcervoSimples;
PesquisaAcervoSimples.prototype.materialMudado =
function ()
{
alert(this.abc); // "undefined" here
};
// --- PesquisaAcervoAvancada --------------------------------------------------
function PesquisaAcervoAvancada()
{
PesquisaAcervo.call(this);
}
PesquisaAcervoAvancada.prototype = new PesquisaAcervo();
PesquisaAcervoAvancada.prototype.constructor = PesquisaAcervoAvancada;
Your actual code reveals the problem. The issue is with how you're calling materialMudado. It's being invoked as the callback for an event. The keyword this inside the callback will refer to the target of the event (which has no abc property), not to the object that the function "belongs" to.
Here's a simple demonstration:
function Test() {};
Test.prototype.callback = function() {
alert(this);
}
var t = new Test();
$(document).click(t.callback);
Output (after clicking page):
[object HTMLDocument]
Compare to this:
function Test() {};
Test.prototype.callback = function() {
alert(this);
}
var t = new Test();
$(document).click(function() {
t.callback();
});
Output:
[object Object]
In this second example we close over the variable t, retaining a reference to it.
Applying this to your example produces something like this:
function PesquisaAcervo() {
var that = this;
var callback = function() {
that.materialMudado();
};
$("*:visible[id^='form:materiaisPesquisa']").
change(callback).keyup(callback);
this.abc = 10;
}
this.name should work. I don't see you overriding the name property in your Cat function so you should be able to just do this.name and the protopical chain will do the work to find the first instance of this property which should be Animal.name.
There is no such thing as an override for an instance variable. An instance variable is just a property on the this object. You can read it with:
var x = this.name;
or assign to it with:
this.name = "foo";
this.name will access the name whether you have an instance of an Animal object or an instance of a Cat object.
If you want to assign to the name property in the Cat constructor, you can just do so with
this.name = "Cat";
Once you have a working instance of an object, properties are just properties and there is no distinction for whether a property was created by a superclass or a subclass. They're just properties of the object at that point and you access all of them the same way with the this.propertyName syntax.
Just use the this keyword:
function Animal()
{
this.name = "name";
}
Animal.prototype.someMethod2 =
function ()
{
}
function Cat()
{
Animal.call(this);
}
Cat.prototype = new Animal();
Cat.prototype.constructor = Cat;
Cat.prototype.someMethod =
function ()
{
alert(this.name);// I want to access the superclass "name" instance variable here
}
var c = new Cat();
c.someMethod();
Add this code to the bottom, I've just added an alert to your someMethod method...
In your example, Cat derives everything from Animal, so it has access to the name variable

Categories

Resources