This question already has answers here:
Self-references in object literals / initializers
(30 answers)
Closed 8 years ago.
How can I reference a property of an object when creating the object itself? Example below which doesn't work:
var object = {
prop1 : $(this).find('.foo');
prop2 : this.prop1.find('.bar');
}
You can use the new keyword with an anonymous function:
var $self = $(this);
var object = new function () {
this.prop1 = $self.find('.foo');
this.prop2 = this.prop1.find('.bar');
};
Technically that object will have a different constructor property than the object literal would, but that is unlikely to cause an issue for most use cases.
As a simple demonstration:
var obj = new function () {
this.x = 7;
this.y = this.x * 2;
};
console.log(obj); // Object {x: 7, y: 14}
You can't refer a property of the object which is not yet created. You can have a function which will be called after the creation of object. So then you can refer a property using this.
Like bellow:-
obj = {
a1:3,
a2:function(){return this.a1}
};
so calling obj.a2() will return 3 here.
Or if you don't want to call is like a function use Get
obj = {
a1:3,
get a2(){return this.a1}
};
obj.a2; //returns 3
Basically what get does It binds an object property to a function that will be called when that property is looked up.
This might be helpful
var obj = {
prop1 : $(this).find('.foo');
prop2 : function() { return this.prop2.find('.bar'); }
};
I assume you're interested in avoiding recalculating $(this).find('.foo'), in which case you could do something like:
var object = (function() {
var prop1 = $(this).find('.foo'),
prop2 = prop1.find('bar');
return {
prop1: prop1,
prop2: prop2
};
}.bind(this);
Related
This question already has answers here:
Do let statements create properties on the global object?
(5 answers)
Closed 2 years ago.
The result is 10 when I use var keyword:
var x = 10;
let foo = {
x: 90,
getX: () => {
return this.x
}
}
console.log(foo.getX())
But undefined is the result when I use let keyword:
let x = 10;
let foo = {
x: 90,
getX: () => {
return this.x
}
}
console.log(foo.getX())
I cannot understand why there are two different results, when both of them have the same global scope.
As your object method, you used an arrow function, whose context (this value) is bound to the function in which you've declared them.
That is, your getX function's this value will be the global object (window).
Then you try to access the x property of that object, which is 10 (as global-scope var creates properties on the global object) in case of var.
However, let never creates a property on the global object, therefore in your second example, you get undefined.
Try it:
const object = {
method: () => this
}
console.log(object.method() === window) //true
var foo = 1
let bar = 2
console.log(foo, window.foo) // 1 1
console.log(bar, window.bar) // 2 undefined
This question already has answers here:
Is there an equivalent of the __noSuchMethod__ feature for properties, or a way to implement it in JS?
(6 answers)
Closed 7 years ago.
I would like to override accessor of a javascript object so that instead of override it should return a fixed value.
eg.
var obj = {};
console.log(obj.someProperty) //will print undefined expected value false
If a property is undefined there is no way to have it return false by default but it will be "falsey".
For example:
var obj = {};
if (!obj.someProperty) {
console.log("expression is falsey");
}
A more explicit way to test truthiness is to use the double bang operator:
var obj = {};
console.log(!!obj.someProperty) // print's undefined, but evaluates to false
But in short, what you are going after will not work because in JavaScript you cannot redefine undefined.
I would do this with the following:
var obj = {};
if (!obj.hasOwnProperty('itdoesnthavethis')) console.log('property is not there')
This will always return a boolean and will not check through the object's prototype chain for the property, just the object itself.
Read more here : https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Object/hasOwnProperty
With ES6 and its Proxy feature you can do something like this:
var obj = {};
obj = new Proxy(obj, {
get: function(target, prop) {
var pv = target[prop];
return pv === undefined ? false : pv;
}
});
that will essentially create proxy wrapper around your object handling property get operations.
With ES5 something like that is impossible to achieve for an arbitrary property.
But if set of properties is known you can design your own object class:
function MyObject() {}
MyObject.prototype.foo = false;
MyObject.prototype.bar = false;
MyObject.prototype.baz = false;
and use it as:
var obj = new MyObject();
console.log(obj.foo); // false
console.log(obj.bar); // false
console.log(obj.foobar); // undefined
case 1: The following code explains how Ii can create methods and assign values to a object
var obj = function(){return 0}; // obj is asigned with a function object
obj.val = obj(); // val property is created and assigned with a value
now I was able to do this by writing 2 statements but JS doesn't allow me to write this definition of object in single statement like case2.
case 2:
var obj = {function(){return 0}, val : obj()};
case 3: people might suggest that i can write it this way
var obj = {
func : function(){return 0},
val : obj.func()
};
but i dont want to write it this way becoz both are properties and none are values. i want the object behavior to be that of case 1 and code written like case 2.
can anybody throw some light on how this can be achieved in JS
I'm not sure what it is you want to achieve, but you could do either of the following:
Create and instantiate the object directly
var obj = {
val: 0
};
Use an invoked function to return the desired object
var object = (function() {
var self = {};
self.val = 0;
return self;
})();
Both suggestion essentially do the same thing.
You can create a function in the format of case 1:
function defaultValueObject(obj) {
obj.val = obj();
return obj;
}
var x = defaultValueObject(function () { return 0; });
... but I really don't understand why you are trying to do this..
Underscore or jQuery may help. For example
var composed = _.extend(function(){return 42}, {val: 10})
composed() // 42
composed.val // 13
Whats the difference between (via prototypes)
var Todo = {};
Todo.prototype.name = "...";
Todo.prototype.hello = function() { ... }
Vs (variables & functions "outside" object)
var Todo = {}
Todo.name = "..."
Todo.hello = function() { ... }
Or even the below : variables & functions in object
var Todo = {
name: "...",
hello = function() { ... }
}
Think it like
A property or a function declared with prototype is an instance member of Todo.
A property or a function declared without prototype is a static member of Todo.
The first one doesn't make sense as you are dealing with an object instance (({}) instanceof Object === true), it won't have a prototype property (Object does).
You may be inquiring about the difference between these two patterns...
var ObjA = function() {
this.method = function() {};
};
var ObjB = function() {};
ObjB.prototype.method = function() {};
jsFiddle.
The former will use more memory when instantiated - each object has their own method. The latter won't each have their own method, the method lives on the prototype object, which is the next in command on the prototype chain when its attempted to be accessed on the parent.
Todo.prototype is also an object, so the difference is if you declare property with prototype, then every object who created from this prototype will have the property, otherwise, the property is only for Todo the object self.
A significant difference between method #1 and #2 (which is almost identical to example #3) is on new keyword that you need to use if you extend your function via prototype, e.g.
var Todo1 = function() {};
Todo1.prototype.name = "Foobar";
var Todo2 = {name: "Foobar" }
var a = Todo1;
console.log(a.name); // no property retrieved
var b = Todo2;
console.log(b.name); // Foobar
var c = new Todo1;
console.log(c.name); // Foobar
Is there a way to call a function (or a property) on an object via reflection, in JavaScript?
Lets say that during run-time, my code has already determined that objectFoo indeed has a property called 'bar'. Now that my code knows that, the next thing I want to do is invoke that. Normally i would do this: var x = objectFoo.bar. But 'bar' was determined at run time, so I need to invoke it using reflection.
In JavaScript, object methods are really just properties containing functions. Like all properties, you can refer to them using associative array syntax:
var x = { 'a': 1 };
x.a += 1;
x['a'] += 1;
console.log(x.a);
Output is: 3.
So if you have the name of a method you want to invoke on myObject:
var methodName = 'myMethod';
// Invoke the value of the 'myMethod' property of myObject as a function.
myObject[methodName]();
EVAL:
http://www.w3schools.com/jsref/jsref_eval.asp
Eval will allow you to run any javascript code by passing in a string and having the javascript engine evaluate it as javascript code.
If you mean that you want to first search a list properties of an object, then look at this:
var o = {}
for(att in o){
alert(o[att]);
}
If you do this, you can even set the property's value by accessing it as if it were an array (all objects are actually associative arrays).
obj["propertyName"] = "new value";
obj["MethodName"]();
Create object (invoke constructor) via reflection:
SomeClass = function(arg1, arg2) {
console.log('Your reflection');
}
ReflectUtil.newInstance('SomeClass', 5, 7);
and implementation:
var ReflectUtil = {};
/**
* #param strClass:
* class name
* #param optionals:
* constructor arguments
*/
ReflectUtil.newInstance = function(strClass) {
var args = Array.prototype.slice.call(arguments, 1);
var clsClass = eval(strClass);
function F() {
return clsClass.apply(this, args);
}
F.prototype = clsClass.prototype;
return new F();
};
Create a register object:
var funcRegister = {};
Create a function to call the other:
var callReflectionFunc = function(type, obj) {
var func = false;
if(funcRegister[type])
func = funcRegister[type](obj);
return func;
}
Populate your register with functions:
funcRegister['yourtype1'] = function(obj) {
console.log('your type 2');
return obj;
}
funcRegister['yourtype2'] = function(obj) {
console.log('your type 2');
return obj;
}
Then call it with your type and an object where you can put your args
callReflectionFunc(type, obj);