Working with javascript prototype inheritance - javascript

Why does this work....
function Person(name) {
this.name = name;
}
Person.prototype.speak = function() {
alert(this.name);
}
var person = new Person("fred");
person.speak();
But not this..
function Person(name) {
this.name = name;
speak = function() {
alert(this.name);
}
var person = new Person("fred");
person.speak();
I am not understanding how inheritance works, or the javascript "prototype-chain".
Thanks.

function Person(name) {
this.name = name;
speak = function() {
alert(this.name);
}
should be
function Person(name) {
this.name = name;
this.speak = function () {
alert(this.name);
};
}

Actually it's variable scope that you're not understanding.
function Person(name) {
this.name = name;
speak = function() {
alert(this.name);
}
}
By omitting var before speak = ... here you've created a global variable named speak, not a variable within Person's scope. In a browser global variables are attached to the global object, window, so your code is equivalent to:
function Person( name ) {
this.name = name;
window.speak = function() { alert( this.name ); }
}
Douglas Crockford has written some related material about variable scope in prototypal inheritance that you should find enlightening.

Related

How to invoke the method myFunction to return (name) i've tried many ways but it doesn't work

Below is what am talking about
class User {
constructor(name) {
this.name = name;
}
myFunction() {
return function() {
return this.name;
}
}
}
let kk = new User("kk");
let speak = kk.myFunction();
speak();
I'm getting this error:
Uncaught TypeError: Cannot read property 'name' of undefined
You should use this.name instead, and the function should not return a function
class User {
constructor(name) {
this.name = name;
}
myFunction() {
alert(this.name);
return this.name;
}
}
let user = new User("jj").myFunction();
console.log(user)
EDIT:
The question you edited now is different from the original question you posted. This one needs a currying solution:
class User {
constructor(name) {
this.name = name;
}
myFunction() {
let name = this.name;
return function() {
return name;
}
}
}
let kk = new User("kk");
let speak = kk.myFunction();
console.log(speak());
You can use an arrow function (() => {}) which won't have it's own binding of this, instead the this value of the enclosing lexical scope is used (your class in this case).
class User {
constructor(name) {
this.name = name;
}
myFunction() {
return () => this.name;
}
}
const speak = new User("kk").myFunction();
console.log(speak());

how to access this in onclick function inside a function?

The following code is not working.Some one please help me in this problem
The name of unit is not alerted.
function unit(name,svgCircle)
{
this.name = name;
this.cir = svgCircle;
this.cir.onclick = clicking;
}
function clicking(){
alert(this.name);
}
Actually your onclick function is binding on the this.cir object. So "this" object inside the clicking() function will refer to this.cir object. If you want to access name property inside clicking() function then you can add one more line as following code.
function unit(name,svgCircle)
{
this.name = name;
this.cir = svgCircle;
this.cir.name = name;
this.cir.onclick = clicking;
}
function clicking(){
alert(this.name);
}
This should work, are you using angular or any other javascript
function unit(name,svgCircle)
{
this.name = name;
this.cir = svgCircle;
this.cir.onclick = clicking.bind(this);
}
function clicking(){
alert(this.name);
}
unit("ml", "testSvg");
clicking();

TypeError: ... is not a function

My JavaScript code in NodeJS results in:
TypeError: ninja.changeName is not a function
Following is my code:
function Ninja(name){
this.name = name;
var changeName = function(name2) {
this.name = name2;
}
}
var ninja = new Ninja("John");
ninja.changeName("Bob");
console.log(ninja.name);
What's wrong with the code?
var changeName will just create a reference to a function which will be lost once the function is done executing.
You must assign the function as a property of the Ninja function instead:
function Ninja(name) {
this.name = name;
this.changeName = function(name2) {
this.name = name2;
}
}
var ninja = new Ninja("John");
ninja.changeName("Bob");
console.log(ninja.name);
var changeName = function(name2) {
this.name = name2;
}
You are declaring a function but not attaching that to the object.
It should be
this.changeName = function(name2) {
this.name = name2;
}
So that the property changeName as a function attached to the object.
You are assigning a function to a variable. This isn't the same as setting a function in the objects prototypal inheritance structure and the variable changeName is only in scope within the context of Ninja.
You can assign the function to this.changeName (important that you're binding to this) like the following:
function Ninja(name){
this.name = name;
this.changeName = function(name2) {
this.name = name2;
}
}
Or you could use prototypes:
function Ninja(name){
this.name = name;
}
Ninja.prototype.changeName = function(name2) {
this.name = name2;
}
Although these approaches look fairly similar, the difference is very important. The first approach creates a new function for every Ninja created. The second approach will use the same function for each object. To look into the reason to use prototypal inheritance, there are various blog posts scattered around the internet.
You are declaring the changeName as a variable but not binding it with the 'Ninja', So I believe instead of using var, it should this. So the code becomes like this.
function Ninja(name){
this.name = name;
this.changeName = function(name2) {
this.name = name2;
}
}
Hope it helps.
function Ninja(name){
this.name = name;
return {
changeName : function(name2) {
this.name = name2;
}
}
}
In your code changeName is not exposed if you want to access the private data you can try with the above snippet
Another approach to make your function public available would be to first declare it private (Some prefer to use an underscore, like usual in .Net):
function Ninja(name) {
this._name = name;
var _changeName = function(name) {
this._name = name;
}
}
And then export it using return. Some might know this from the classical Java boilerplate Getters and Setters, where fields are declared private by default and Methods make them available:
function Ninja(name) {
this._name = name;
var _changeName = function (name) {
this._name = name;
}
return {
changeName: _changeName,
getName: function () {return _name;}
}
}
...And now, use the object:
var ninja = new Ninja("John");
ninja.changeName("Bob");
console.log(ninja.getName());

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.

JavaScript Callback/this confusion with require.js / objects

I try to use the following structure in my app: https://gist.github.com/jonnyreeves/2474026
I try to register some callback inside my constructor. I made an example using jquery, actually it's leaflet maps, but the difference shouldn't matter.
function Person() {
this.name = "abc";
$("#something").onSomeEvent(function() {
this.name = "cde";
});
}
How do I properly reference my object-property name, inside the callback?
You can use something like this:
function Person() {
this.name = "abc";
$("#something").onSomeEvent(function() {
this.name = "cde";
}.bind(this));
}
function Person() {
var self = this;
self.name = "abc";
$("#something").onSomeEvent(function() {
//this is right if you need
self.name = "cde";
});
}
you can use $('#someting') with right this.
if you use bind to solve the problem,in the callback this is wrong.
Use bind, which is not supported in older IEs, or jquerys proxy
function Person() {
this.name = "abc";
$("#something").onSomeEvent(function() {
this.name = "cde";
}.bind(this));
}
function Person() {
this.name = "abc";
$("#something").onSomeEvent($.proxy(function() {
this.name = "cde";
},this));
}

Categories

Resources