JQuery bind this and data-attribute - javascript

I would like to have a click listener which binds the object values itself and a data attribute of the element which has been clicked.
Example:
var Person = function (firstName) {
this.firstName = firstName;
$(window).on("click", ".myclass", sayHello).bind(this);
};
Person.prototype.sayHello = function() {
console.log("Hello, I'm " + this.firstName + data-url);
};
var person1 = new Person("Alice");
HTML:
<div class="wrapper">
Test
Test
Test
</div>
I don't know how to get the data attribute within the sayHello function. But I need the firstName and the data-url within the sayHello function.
Any suggestions?

I think this is what you're looking for (Not tested but it will help you):
$(a).click(function(){
data_val = $(this).data('url');//will give you data attribute value of clicked anchor element
var person1 = new Person("Alice", data_val);
});
var Person = function (firstName, val) {
this.firstName = firstName;
this.val = val;
};
Person.prototype.sayHello = function() {
console.log("Hello, I'm " + this.firstName + this.val);
};

Update the sayHello method to accept additional params and create a link to this of the Person object:
var Person = function (firstName) {
var self = this;
this.firstName = firstName;
$(window).on("click", ".myclass", function() {
self.sayHello(this);
});
};
Person.prototype.sayHello = function(element) {
console.log("Hello, I'm " + this.firstName + $(element).data('url'));
};
var person1 = new Person("Alice");

use getAttribute javascript function, try
console.log("Hello, I'm " + this.firstName + this.getAttribute('data-url'));

Related

is the prototype will work on factory function?

function person(firstName, lastName) {
return {
firstName: firstName,
lastName: lastName,
};
}
person.prototype.displayFullName = function() {
return this.firstName + " " + this.lastName;
};
let person1 = person("Virat", "Kohli");
let person2 = person("Sachin", "Tendulkar");
console.log(person1)
console.log(person1.displayFullName())
console.log(person2.displayFullName())
Can we add a new function to the factory function using prototype
To make a constructor call use the new keyword. Properties added to the object bound to this will be accessible by the object returned by the constructor call new Person(..).
function Person(firstName, lastName) {
this.firstName = firstName;
this.lastName = lastName;
}
Person.prototype.fullName = function () {
return this.firstName + ' ' + this.lastName;
};
let person1 = new Person('Virat', 'Kohli');
let person2 = new Person('Sachin', 'Tendulkar');
console.log(person1.fullName());
console.log(person2.fullName());

setting property as function in a constructor javascript

i'm working with a piece of code that sets a name property as a function
name = n;
this.name = function(n){
if( n ) name=n;
return name;
}
full constructor is:
function Warrior(n){
name = n;
this.name = function(n){
if( n ) name=n;
return name;
}
}
I don't understand how this is different than this.name = n; and why I can't use that in a toString function like
Person.prototype.toString = function(){
return "Hi! my name's "+this.name;
}
What you created is a getter/setter for name:
A getter is a function which returns a value associated with an object property.
A setter is a function which updates the value associated with an object property.
Getters and setters are useful for creating “derived properties” (i.e. properties which are derived from other properties). For example:
function Person(firstname, lastname) {
this.firstname = firstname;
this.lastname = lastname;
}
Person.prototype.fullname = function (fullname) {
if (arguments.length < 1) return this.firstname + " " + this.lastname;
var newname = fullname.split(" ");
this.firstname = newname[0];
this.lastname = newname[1];
return fullname;
};
var person = new Person("Aadit", "Shah");
alert(person.firstname);
alert(person.lastname);
alert(person.fullname());
person.fullname("Chuck Norris");
alert(person.firstname);
alert(person.lastname);
alert(person.fullname());
In the above code fullname is a derived property. It is derived from firstname and lastname. As you can see, when I update fullname, I am also updating firstname and lastname. Hence getters and setters are useful in this case.
However a lot of people misuse getters and setters. For example:
function Warrior(name) {
this.name = function (newName) {
if (arguments.length >= 1)
name = newName;
return name;
}
}
In this case there's no good reason to create a getter/setter for name because it is not a derived property. It's a misuse of getters/setters and all it does is make the code slower. Instead it should be implemented as:
function Warrior(name) {
this.name = name;
}
Plain and simple.
Now consider:
Person.prototype.toString = function () {
return "Hi! my name's " + this.name;
};
The reason this doesn't work is because this.name is a getter function. Hence you need to call it to get the actual value. Thus, it should be:
Person.prototype.toString = function () {
return "Hi! my name's " + this.name();
};
Finally, newer versions of JavaScript have built in support for getters and setters:
function Person(firstname, lastname) {
this.firstname = firstname;
this.lastname = lastname;
}
Object.defineProperty(Person.prototype, "fullname", {
get: function () {
return this.firstname + " " + this.lastname;
},
set: function (fullname) {
var newname = fullname.split(" ");
this.firstname = newname[0];
this.lastname = newname[1];
}
});
var person = new Person("Aadit", "Shah");
alert(person.firstname);
alert(person.lastname);
alert(person.fullname);
person.fullname = "Chuck Norris";
alert(person.firstname);
alert(person.lastname);
alert(person.fullname);
This makes getters and setters look like normal properties. Such properties are called accessor properties.
Here your constructor function is Warrior and you can add new method toString to an existing prototype Warrior. Like this you can add.
Warrior.prototype.toString = function(){ // code goes here }
this.name is a function .so
Warrior.prototype.toString = function(){
return "Hi! my name's "+this.name();
}
Using new keyword to create new objects from the same prototype
Warrior.prototype.toString = function(){
return "Hi! my name's "+this.name();
}
myname = new Warrior("ur name");
console(myname.toString());

JavaScript: Using Object.defineProperties()

I'm trying to learn how to use Object.defineProperties(). I'm using the following code:
var Person = function(firstName, lastName)
{
this.firstName = firstName;
this.lastName = lastName;
};
Object.defineProperties(Person, {
sayHi : {
get : function() {return "Hello";},
enumerable : true
},
sayBye : {
get : function() {return "Bye";},
enumerable : true
}
});
var john = new Person('John', 'Doe');
console.log(john.sayHi());
But I keep getting:
TypeError: john.sayHi is not a function
console.log(john.sayHi());
Can someone tell me what is wrong with this code?
Thanks
Well, you are not defining sayHi as a function. This is how to define it as a function:
var Person = function(firstName, lastName)
{
this.firstName = firstName;
this.lastName = lastName;
};
// Define the properties on the prototype, not the Person object itself
Object.defineProperties(Person.prototype, {
sayHi : {
get : function() {
return function() {
return "Hello, I am " + this.firstName + " " + this.lastName;
};
},
enumerable : true
},
sayBye : {
get : function() {
return function() {
return "Bye";
};
},
enumerable : true
}
});
var john = new Person('John', 'Doe');
console.log(john.sayHi());
console.log(john.sayBye());
To be precise: in your code, john.sayHi returns the "Hello" string, which is a string primitive, and therefore definitely not a function ;-)
The get function for the property must return a function in order to achieve what you want.
To give you a longer answer, see this following other implementation, taking fully advantage of two things: first the new features from ES5 (Object.create()) and ES6 (Object.defineProperties()) and the prototypal nature of JS (no use of new operator, prototypal inheritance):
var Person = {
init: function(firstName, lastName) {
this.firstName = firstName;
this.lastName = lastName;
}
};
Object.defineProperties(Person, {
sayHi : {
get : function() {return function() {return "Hello, I am " + this.firstName + " " + this.lastName;}},
enumerable : true
},
sayBye : {
get : function() {return function() {return "Bye";};},
enumerable : true
}
});
var Employee = Object.create(Person); // Employee inherits from Person
Employee.init = function(firstName, lastName, position) {
this.firstName = firstName;
this.lastName = lastName;
this.position = position;
};
Object.defineProperties(Employee, {
introduce : {
get : function() {return function() {
return this.sayHi() + ", " + this.position;
}},
enumerable : true
},
farewell : {
get: function() {return function() {
return this.sayBye() + ", it was a pleasure to meet you";
}},
enumerable: true
}
});
var john = Object.create(Employee); // john inherits from Employee
john.init('John', 'Doe', 'Manager');
console.log(john.sayHi()); // Inherited from Person
console.log(john.introduce()); // Inherited from Employee
console.log(john.sayBye()); // Inherited from Person
console.log(john.farewell()); // Inherited from Employee
JSFIddle demo
Replace
get : function() {return "Hello";} with
get : function() {return function() {return "Hello";};}

javascript passing a function as an argument

I am wondering why when I make adjustments to the following code:
var product = {
firstname: "john",
lastname: "kcarl",
fullname : function() { return this.firstname + " " + this.lastname }
};
function write()
{
document.write(product.fullname());
};
write();
**** the following fullname becomes undefined
function write(method)
{
document.write(product.method());
};
write(fullname);
**** even when I try this it comes undefined
function write(method)
{
document.write(method());
};
write(product.fullname);
It's because of scope issue with javascript. Here is a better way to write this code:
var Product = function() {
var self = this;
this.firstname = "john";
this.lastname = "kcarl";
this.fullname = function() {
return self.firstname + " " + self.lastname;
}
};
var product = new Product();
var fullnameMethod = product.fullname;
document.write(fullnameMethod());
In the above example, I save the scope into a variable called self and I can feel free to call the fullname() method anytime

How can I create a new Person object correctly in Javascript?

I'm still struggling with this concept. I have two different Person objects, very simply:
;Person1 = (function() {
function P (fname, lname) {
P.FirstName = fname;
P.LastName = lname;
return P;
}
P.FirstName = '';
P.LastName = '';
var prName = 'private';
P.showPrivate = function() { alert(prName); };
return P;
})();
;Person2 = (function() {
var prName = 'private';
this.FirstName = '';
this.LastName = '';
this.showPrivate = function() { alert(prName); };
return function(fname, lname) {
this.FirstName = fname;
this.LastName = lname;
}
})();
And let's say I invoke them like this:
var s = new Array();
//Person1
s.push(new Person1("sal", "smith"));
s.push(new Person1("bill", "wonk"));
alert(s[0].FirstName);
alert(s[1].FirstName);
s[1].showPrivate();
//Person2
s.push(new Person2("sal", "smith"));
s.push(new Person2("bill", "wonk"));
alert(s[2].FirstName);
alert(s[3].FirstName);
s[3].showPrivate();
The Person1 set alerts "bill" twice, then alerts "private" once -- so it recognizes the showPrivate function, but the local FirstName variable gets overwritten.
The second Person2 set alerts "sal", then "bill", but it fails when the showPrivate function is called. The new keyword here works as I'd expect, but showPrivate (which I thought was a publicly exposed function within the closure) is apparently not public.
How can I ensure that my closure is a reusable object with publicly exposed methods? I am using the (function() { //object code })(); syntax to ensure my variables are scoped only to the object being created. Thanks!
this is using the technique from "JavaScript: The Good Parts" by Douglas Crockford
http://oreilly.com/catalog/9780596517748
Chapter 5: Inheritance - section 'Functional'
var personConstructor = function (spec) {
var that = {};
that.fullName = function () {
return spec.first_name + " " + spec.last_name;
};
that.setFirstName = function (firstName) {
spec.first_name = firstName;
};
return that;
};
var john = personConstructor({first_name: "John", last_name: "Doe"});
var jane = personConstructor({first_name: "Jane", last_name: "Doe"});
alert(john.fullName()); // John Doe
alert(jane.fullName()); // Jane Doe
john.first_name = "OVERWRITE";
alert(john.fullName()); // John Doe
john.setFirstName("OVERWRITE-VIA-SETTER");
alert(john.fullName()); // OVERWRITE-VIA-SETTER Doe
put this together on jsfiddle, link below if you want to test drive it,
watch out for the 4 alerts when the page loads
http://jsfiddle.net/SecKg/
I modified Person2 to declare the showPrivate function within the constructor -- ensuring the function was public:
;Person2 = (function() {
var prName = 'private';
return function(fname, lname) {
this.FirstName = fname;
this.LastName = lname;
this.showPrivate = function() { alert(prName); };
}
})();
You want to be using the prototype method of creating Person objects.
;(function(){
function Person(firstName, lastName) {
this.firstName = firstName;
this.lastName = lastName;
function showPrivate() {
alert(this.firstName);
}
}
Person.prototype.getName = function() {
return this.firstName + ' ' + this.lastName;
}
})();
showPrivate will be private as it's creating inside the constructor. The getName function is public, and can be invoked from outside the Person object.
I'm not entirely sure what you're trying to accomplish here. Your question is a little confusing. Perhaps try to reword?
//this would allow for instance:
// john.setName('first', 'Johnny');
// jane.setName('last', 'Smith');
var personConstructor = function (spec) {
return {
fullName: function () {
return spec.first_name + " " + spec.last_name;
},
setName: function (nameType, name) {
spec[nameType+'_name'] = name;
}
};
};

Categories