I am a bit confused, I would like to have a function that clears all the properties of an object which is available to all the instances of an object. So, I have added a prototype clear() function. This is the following code:
(function () {
Supplier.$inject = [];
angular.module('webclient').factory('Supplier', Supplier);
function Supplier() {
Supplier.prototype = {
clear: function () {
for (var key in this) {
//skip loop if the property is from prototype
if (this.hasOwnProperty(key))
continue;
console.log("key:" + key);
this[key] = undefined;
}
},
}
return Supplier;
};
})();
So, I would like to be able to clear all the properties of the current supplier object. So, if the supplier object had the following properties:
SupplierID:21,
Email:None
I would like to set the properties to undefined. I would use the class as following:
var supplier = new Supplier();
supplier.SupplierID = 21;
supplier.Email = "None";
And to set each property to undefined I would
supplier.clear();
Any ideas?
Thanks
try this: (plnkr)
function Supplier() {
var supplier = function() {};
supplier.prototype.clear = function() {
for (var key in this) {
if (!this.hasOwnProperty(key))
continue;
delete this[key];
}
};
return supplier;
}
hasOwnProperty return true if key is not in the prototype also prototype should be set outside of constructor, so your code should look like this:
function Supplier() { }
Supplier.prototype = {
clear: function () {
for (var key in this) {
if (this.hasOwnProperty(key)) {
console.log("key:" + key);
this[key] = undefined;
}
}
},
}
Don't set properties to undefined, just delete() them:
delete this[key];
And #jcubic is right, hasOwnProperty returns true if key is not in the prototype...
Related
Say I have an object like below:
var obj = {};
obj.test = function() { console.log(?); }
Is there anyway to print out "test", the key that this function is value of, but not know the obj name in advance?
Not really. Relationships in JS are one-way.
You could search for a match…
var obj = {};
obj.not = 1;
obj.test = function() {
var me = arguments.callee;
Object.keys(obj).forEach(function(prop) {
if (obj[prop] === me) {
console.log(prop);
}
});
};
obj.test();
But look at this:
var obj = {};
obj.not = 1;
obj.test = function() {
var me = arguments.callee;
Object.keys(obj).forEach(function(prop) {
if (obj[prop] === me) {
console.log(prop);
}
});
};
obj.test2 = obj.test;
obj.test3 = obj.test;
window.foo = obj.test;
obj.test();
The same function now exists on three different properties of the same object … and as a global.
Might be a bit of a convoluted solution, but this might be useful -
You can have a method that will add functions to your object at a specific key. Using the bind method, we can predefine the first argument to the function to be the key that was used to add it.
The function that I am adding to the key is _template, it's first argument will always be the key that it was added to.
var obj = {};
function addKey(key) {
obj[key] = _template.bind(null, key)
}
function _template(key, _params) {
console.log('Key is', key);
console.log('Params are',_params);
}
addKey('foo')
obj.foo({ some: 'data' }) // this will print "foo { some: 'data' }"
Reference - Function.prototype.bind()
try this Object.keys(this) and arguments.callee
var obj = {};
obj.test = function() {
var o = arguments.callee;
Object.values(this).map((a,b)=>{
if(a==o){
console.log(Object.keys(this)[b])
}
})
}
obj.one = "hi"
obj.test()
You can get the name of the method called with
arguments.callee.name
var a ={ runner_function : function(){ console.log(arguments.callee.name ); } };
a.runner_function() //It will return "runner_function"
I'm trying to backwards engineer the array methods push, pull, shift, unshift, but I can't seem to figure out how to a) construct it b) call it. How could I do this? Here are the conditions:
returns an empty array object. this object should have the
following methods: push(val) adds val to the end of the array
pop() removes a value from the end and returns it unshift(val) adds
val to the beginning of the array shift() removes a value from the
beginning and returns it the goal of this problem is to reverse
engineer what array methods are actually doing and return an object
that has those methods
Here is what I initially thought it should look like.
function createArray() {
//CODE HERE
this.push = function Push(value){
if(index >= 0){
Mainarray[index++]=value;}
};
this.pop = function (){
if(index >= 0){
index--;
return Mainarray[index];
}
else{
// display message of Empty Array
console.log('Error: Item is not array');
}
};
this.unshift = function(){return ;};
}
You could use prototypes — like this:
function YourArray() {
this.arr = [];
this.index = 0;
}
YourArray.prototype.push = function( value ) {
this.arr[ this.index++ ] = value;
return this;
}
var arr = new YourArray();
arr.push('foo');
function NewArray() {
this.array = [];
}; /* Class */
NewArray.prototype.push = function(data) {
this.array.push(data);
} /* Method */
/* You should use prototypes, because all methods will became common, and if you are created methods like this.pop = function (){} then any instance will copy this functions */
var n = new NewArray();
n.push(2);
console.log(n);
Advantages of using prototype, vs defining methods straight in the constructor?
You can recreate the push method by assigning you array at position the length of the same array a value.
This is the prototype for the push:
Array.prototype.push = function(element) {
this[this.length] = element;
};
and this is for the pop method:
Array.prototype.pop = function() {
var key = this.stack.pop();
var prop = this.object[key];
delete this.object[key];
return prop;
};
You can make your own methods by changing the prototype names.
push to mypush or sthing
Example for your push function createArray:
this.push = function pushValue(value) {
this.arr[this.arr.length] = value;
};
I used native arrays methods as values assigned to keys in the returned object. The trick is to declare an array inside the object and use it as a reference. It should pass the checks you`re looking for.
function createArray() {
//CODE HERE
return {
arr: [],
push: function (val) {this.arr.push(val)},
pop: function() {return this.arr.pop()},
unshift: function (val) {return this.arr.unshift(val)},
shift: function() {return this.arr.shift()}
}
}
I am building a javascript library where I have to create a log of classes and most of them have a lot of properties which have to make public for the user.
For example:
function Person(name,age){
}
Now I want to create the getter and setter for properties (name and age).
Nornall, I have to add these methods to Person.prototype:
Person.prototype.getName=function(){}
Person.prototype.setName=function(x){
//check if x is typeof String
}
Person.prototype.getAge=function(){}
Person.prototype.setAge=function(x){
//check if x is typeof Number
}
This will result in two many lines of repeated codes.
So I wonder if I can call a method like this:
makeThesePropertiesPublic(Person,{
name:"string",
age:"number"
});
Then I can call this:
var p=new Person("xx",1);
p.getName();
p.getAge();
.......
Is there a out-of-box method to implement this?
First of all you can't define the getter and setter functions on the prototype because they need to be able to access name and age which are only accessible inside the constructor. Hence you would need to define the getter and setter functions inside the constructor.
I would do this:
function Person(name, age) {
var private = {
name: name,
age: age
};
Object.defineProperties(this, {
name: getAccessor(private, "name", "String"),
age: getAccessor(private, "age", "Number")
});
}
function getAccessor(obj, key, type) {
return {
enumerable: true,
configurable: true,
get: function () {
return obj[key];
},
set: function (value) {
if (typeOf(value) === type)
obj[key] = value;
}
};
}
function typeOf(value) {
return Object.prototype.toString.call(value).slice(8, -1);
}
Now you can access create a Person and access their name and age properties as follows:
var person = new Person("Aadit M Shah", 20);
person.name = 0; // it won't set the name
person.age = "twenty"; // it won't set the age
alert(person.name);
alert(person.age);
See the demo: http://jsfiddle.net/aVM2J/
What about something like this?
function Person(n, a) {
var name = n;
var age = a;
var person = {};
person.getName = function () {
return name
}
person.getAge = function () {
return age;
}
return person;
}
var p = Person("jon",22);
console.log(p.getName());//jon
I need to loop over the properties of a javascript object. How can I tell if a property is a function or just a value?
var model =
{
propertyA: 123,
propertyB: function () { return 456; }
};
for (var property in model)
{
var value;
if(model[property] is function) //how can I tell if it is a function???
value = model[property]();
else
value = model[property];
}
Use the typeof operator:
if (typeof model[property] == 'function') ...
Also, note that you should be sure that the properties you are iterating are part of this object, and not inherited as a public property on the prototype of some other object up the inheritance chain:
for (var property in model){
if (!model.hasOwnProperty(property)) continue;
...
}
Following might be useful to you, I think.
How can I check if a javascript variable is function type?
BTW, I am using following to check for the function.
// Test data
var f1 = function () { alert("test"); }
var o1 = { Name: "Object_1" };
F_est = function () { };
var o2 = new F_est();
// Results
alert(f1 instanceof Function); // true
alert(o1 instanceof Function); // false
alert(o2 instanceof Function); // false
You can use the following solution to check if a JavaScript variable is a function:
var model =
{
propertyA: 123,
propertyB: function () { return 456; }
};
for (var property in model)
{
var value;
if(typeof model[property] == 'function') // Like so!
else
value = model[property];
}
How can I call each function in this object?
var obj = {
hey1: function() {
alert('hey');
},
hey2: function() {
alert('hey2');
},
hey3: function() {
alert('hey3');
}
}
I'd like each function to run one after the other. I'm looking for something like:
for (var hey in obj) {
hey();
}
But obviously that doesn't run (otherwise I wouldn't be asking this question).
Thanks guys!!!
for (var hey in obj) {
obj[hey]();
}
In a situation where it is not guaranteed that each property will be a function, you can weed out other properties:
for (var hey in obj) {
if (typeof obj[hey] == "function") {
obj[hey]();
}
}
To further restrict it to only immediate properties of the object (and not the ones inherited from its prototype):
for (var hey in obj) {
if (typeof obj[hey] == "function" && obj.hasOwnProperty(hey)) {
obj[hey]();
}
}
Lopping will give you they keys, not the values. Use the key to get the value:
for (var hey in obj) {
obj[hey]();
}
jsfiddle.net/s8tbr/
Note: Depending on from where you get the object, you might want to check that the properties are members of the object itself, not inherited from a prototype:
for (var hey in obj) {
if (obj.hasOwnProperty(hey)) {
obj[hey]();
}
}