Property Getter as Function

How can I pass property getter as a function type to another function

You can reference the getter by writing ::test (or this::test).

When you write test::get, you are actually referencing the get method on String. That method takes an index and returns the character at that index.

If the property was a var and you want a reference to its setter, you can write ::test::set.

For more info on property references, see here: https://kotlinlang.org/docs/reference/reflection.html#bound-function-and-property-references-since-11

javascript getter and setter within object property within class

I'm trying to do is get that same functionality, but where the property is not loose on the top level of the class, but within an object property inside the class.

Then you need to create that object somewhere first. As you will want to have a separate object (with different property values) for each instance, create that instance-specific object in the constructor:

class B {
#innerObjProp;
constructor() {
this.#innerObjProp = {};
}
}

and then define your getters/setters in that object, not on the class level, with the usual ES5 syntax for getters/setters in object literals:

class B {
#innerObjProp;
constructor() {
let b = "b"; // a local variable as a place to store the value
this.#innerObjProp = {
get b() {
// do some stuff that b depends on...
// ...
// ... and then ultimately return it:
return b;
},
set b(arg) {
// do some stuff that depends on b or vice versa...
// ...
// ... and then ultimately set b to something:
b = something();
}
};
}
}

Notice that this is a code smell. If your class has grown so large that you don't want to put some things at its "top level", something is wrong with your design, and you should consider splitting the class into multiple smaller classes.

Property getter as function

Starting with Swift 5.2, this is now possible, thanks to this Swift Evolution proposal.

Basically, key paths can now be used in places where functions are needed, like map/filter, etc.

For the example from the question, the usage would be along the lines of:

users.filter(\.isUnderaged)
users.map(\.firstName.count) // yes, chaining is also permitted

Why do we need propertie's getter if property already does it's job in python?

The property class provides two ways to configure the getter, setter, and deleter methods.

  1. Passing functions as arguments when you create the property.
  2. Using the property's getter, setter, and deleter methods, each of which returns a new property with the corresponding fget, fset, or fdel overriden.

For example, given three functions

def get_value(self):
...

def set_value(self, value):
...

def delete_value(self):
...

you write either

p1 = property(get_value, set_value, delete_value)

or

# All arguments are optional
p2 = property()
p2 = p2.getter(get_value)
p2 = p2.setter(set_value)
p2 = p2.deleter(set_value)

property, property.getter, property.setter, and property.deleter are all designed to allow them to be used as decorators.

p2 = property()

@p2.getter
def p2(self): # get_value
...

@p2.setter
def p2(self, value): # set_value
...

@p2.deleter
def p2(self): # del_value
...

In ordinary usage, a hybrid approach is taken: the property is created and initialized with a getter in one step (the first argument is the getter to support this most common use-case of a read-only property), an optional setter and deleter provided when necessary.

@property
def p2(self): # get_value
...

So, the explicit use of property.getter is rare, but available. While all three methods could be called at any time to alter the behavior of an existing property, I don't think I've even seen them used other than for the intial configuration of a property.

How to distinguish between a getter and a setter and a plain property in JavaScript?

When you are stringifying, you will lose all the undefined and the Function objects. Instead, you can check if the returned property descriptor object has a non-undefined get or set properties and decide like this

  1. If the property descriptor has a value property, it is a normal data property.

  2. If the property descriptor has get and set properties, and both have functions as values, then it is an accessor property.

  3. If the property descriptor has get's value as a function, then it is a getter property.

  4. Otherwise, a setter property.


Since value is there, it is a normal data property:

descriptor.hasOwnProperty('value');
// true

Here, value is not there, but get property is a function. So a getter property:

descriptorGetter.hasOwnProperty('value');
// false
typeof descriptorGetter.get === 'function';
// true
typeof descriptorGetter.set === 'function';
// false

Here also, value is not there, but set property is a function. So a setter property:

descriptorSetter.hasOwnProperty('value');
// false
typeof descriptorSetter.get === 'function';
// false
typeof descriptorSetter.set === 'function';
// true

Apart from that, if you had an accessor property, like this

var o = {
get cabbage() {
return 'cabbage';
},
set cabbage(value) {
this._cabbage = value;
},
};

descriptorCabbage = Object.getOwnPropertyDescriptor(o, 'cabbage');

console.log(descriptorCabbage.hasOwnProperty('value'));
// false
console.log(typeof descriptorCabbage.get === 'function');
// true
console.log(typeof descriptorCabbage.set === 'function');
// true

You can write this as a function, like this

function getTypeOfProperty(object, property) {
var desc = Object.getOwnPropertyDescriptor(object, property);

if (desc.hasOwnProperty('value')) {
return 'data';
}

if (typeof desc.get === 'function' && typeof desc.set === 'function') {
return 'accessor';
}

return typeof desc.get === 'function' ? 'getter' : 'setter';
}

console.log(getTypeOfProperty(o, 'foo'));
// data
console.log(getTypeOfProperty(o, 'bar'));
// getter
console.log(getTypeOfProperty(o, 'bam'));
// setter
console.log(getTypeOfProperty(o, 'cabbage'));
// accessor

Calling a method from the getter of a property

No, not unless you code it into every Getter, or you abandon "Plain Old C# Classes" altogether and construct a data model paradigm based around a read-audited set of data. If you go down that route that you simply have each "data class" being an Dictionary of Get/Set delegates and access its data values through those delegates. Its not an uncommon design, but it no longer follows the OO paradigms.

Example (psuedo code)

public class MonitoredCustomerObject
{
// Assumption that the Get/Set delegates are stored in a simple Tuple.
private Dictionary<string, Tuple<delegate,delegate>> getterSetterDict = new ...

public GetValue(string key)
{
executeMyOnReadCode();
return getterSetterDict[key].Item1();
}

public SetValue(string key)
{
executeMyOnWriteCode();
getterSetterDict[key].Item2();
}
}

How to check if a property of an object is a getter or a setter?

Yes. The Object.getOwnPropertyDescriptor method does the opposite of defineProperty:

const obj = {
property: 'value',
get accessor(){ return 'value' },
set accessor(value){}
}

console.log(Object.getOwnPropertyDescriptor(object, 'property'))
/*
{
enumerable: true,
writable: true,
configurable: true,
value: "value"
}
*/

console.log(Object.getOwnPropertyDescriptor(object, 'accessor'))
/*
{
enumerable: true,
writable: true,
configurable: true,
get: function(...){...},
set: function(...){...}
}
*/

Using this, you can implement a function, that determines that for you:

const isAccessor = (object, property) => !('value' in Object.getOwnPropertyDescriptor(object, property))


Related Topics



Leave a reply



Submit