Where is this parameter getting its value from? - javascript

I have this code:
https://jsfiddle.net/toddmotto/qaqeapn6/
I'm wondering, where is the 'target' parameter getting its value from?
function (target)

It is a decorated class
A Decorator is a special kind of declaration that can be attached to a class declaration, method, accessor, property, or parameter. Decorators use the form #expression, where expression must evaluate to a function that will be called at runtime with information about the decorated declaration.
Please refer https://www.typescriptlang.org/docs/handbook/decorators.html

That is internal feature of Class Decorators.
ES2016 Decorators work on property descriptors and classes. They automatically get passed property names and the target object, as we’ll soon cover. Having access to the descriptor allows a decorator to do things like changing a property to use a getter, enabling behaviour that would otherwise be cumbersome such as automatically binding methods to the current instance on first access of a property.
You can read further information: https://medium.com/google-developers/exploring-es7-decorators-76ecb65fb841#.qj8979jae

Related

Defining a setter for individual style property

According to the current CSS specification CSSStyleDeclaration.setProperty() has a shorthand of writing directly to the style property. Like in the code below, both lines have the same functionality:
element.style.color = "#fff";
element.style.setProperty("color", "#fff");
Though there is an interesting and unclear situation to me here:
I couldn't find the way to hook a custom setter for individual style properties, since these don't have an explicit setter. Changing the setProperty method only works for the direct call of the method element.style.setProperty() and not the shorthand (i.e. element.style.color).
Both seem to refer to CSSStyleDeclaration interface, but I can't find a way to define a setter for a specific style property (i.e. element.style.color).
MDN says the following:
While this property is considered read-only, it is possible to set an inline style by assigning a string directly to the style property. In this case the string is forwarded to CSSStyleDeclaration.cssText. Using style in this manner will completely overwrite all inline styles on the element.
According to this, changing a setter for cssText could possibly intercept the setter for specific style properties, but it only does for inline style definition itself (i.e. element.style = 'color:#fff;')
Is there a way to define a custom setter for individual style properties, such as element.style.color, or at least have a generic setter for any of them?
As you have explained, there are two ways to set a style property:
e.style.property=
e.style.setProperty(property,..)
Depending on implementation, these two ways can be handled either independently, or using each other. It is very unprobably, that setProperty calls the way 1. The way 1. can have a setter, which may or may not call the setProperty.
The property may exist (have a property descriptor), or the way 1. may be handled another way (e.g. by catch the exception non-existent property.)
This does mean, that you can define/redefine the property as an accessor, which's getter calls getPropertyValue, and which's setter calls setProperty. Then, you can inject any call of (even instance-defined) function.
Object.defineProperty(CSSStyleDeclaration.prototype, "color", {configurable:true, enumerable:true, get:function() {return this.getPropertyValue("color");}, set:function(c) {let tweakedC=tweakColor(c); this.setProperty("color", tweakedC); handleNewPropertyValue(c, tweakedC);}});
function handleNewPropertyValue(c, tweakedC) {...};
I have used this way in some version of Chrome, but I believe, that it will do in most implementations, except of those, where setProperty depends on existing the property per se (unprobably).
Tweaking the prototype to create a new instance property on first access is very easy, but it is another question.

Using setters in Javascript to "override" properties

The MDN page about set seems to state that an
[ECMAScript 2015] setter must not appear in an object literal ... with a
data entry for the same property.
However when using the super keyword this no longer seems to apply.
class Foo {
constructor(bar){
this.bar = bar
}
set bar(newBar){
if (!newBar.match(/\w+/))
throw Error("Invalid bar value")
// I can use super despite not being a derived class.
return super.bar = newBar
}
}
const baz = new Foo("Baz")
baz.bar = "new value" // No recursion
This seems like a useful feature as the property doesn't have to be "hidden" by prefixing it with an underscore. Plus I don't have to mess with the property enumerability to avoid the "hidden" version from showing in a loop or serialization.
But the set syntax is a bit of a black-box and I can't tell what it's actually doing.
Am I breaking something here or is it okay to use?
Also what is super referencing here?
This seems like a useful feature as the property doesn't have to be "hidden" by prefixing it with an underscore or something. Plus I don't have to mess with the property enumerability to avoid the "hidden" version from showing in a loop or serialization.
No, it's not useful. It's a hack at best, and doesn't do what you expect.
There is nothing hidden here at all. You are creating a new property with the name bar on the instance itself, shadowing any getters/setters you had defined on the prototype. The second assignment does not get your setter caller. Also the instance property is a normal enumerable property, so it will show up in for in loops and serialisation.
Also what is "super" referencing here?
The super keyword refers to the prototype of the object that the method (or setter) is defined on, i.e. Object.getPrototypeOf(Foo.prototype). This is the Object.prototype in your case, since your class Foo doesn't extend anything.
The .foo access will be looked up on that prototype, and would normally find a method that you inherited from your parent class or something. When using that, the property reference super.foo will however make the receiver of the operation (i.e. what would the this keyword in a method invocation) be the current this instance, not the prototype.
In your case, it's not a method call but an assignment. This could run a setter inherited from the parent class, but in your case there is no Object.prototype.foo property so it will fall back to standard assignment on the target - and that target is the baz instance itself, where a new own property will be created.
So no, it is not okay to use.

Javascript object attributes?

I know that all object properties have a name and have attributes like value, configurable, enumerable and writable. But in this post I read that objects too have attributes like prototype, class and extensible.
I understand that prototype attribute is for pointing for the parent object. But what I don't understand is what's class attribute? Is there such attribute? And isn't extensible is a method of object as isExtensible() ?
In this post I read that objects too have attributes like prototype, class and extensible.
They're not called "attributes" normally but internal slots. Usually they are denoted by double brackets to differentiate them from normal properties, i.e. [[prototype]], [[class]] and [[extensible]].
What is the [[class]] attribute? Is there such attribute?
Not in ES6 any more. The [[class]] internal slot contained information on which kind of builtin type (e.g. Array, RegExp, builtin wrapper) the object was. It was shown when you used the Object.prototype.toString method on the object. (Have a look at Why can Object.prototype.toString.call(foo) detect foo's type? or Why does `Object.prototype.toString` always return `[object *]`? for more details - it was also the best way to detect whether an object is an array before Array.isArray was available).
Since ES6, there is no such internal slot any more and Object.prototype.toString relies on the Symbol.toStringTag mechanism now.
And isn't extensible a method of object as isExtensible()?
No, the [[extensible]] internal slot is the thing that isExtensible() accesses, and that Object.preventExtensions() can set.

Is it possible to access class properties without initialising the class?

I want to access all of the properties of a class that will be defined when the constructor is called, so that I can implement a sort of interface for the class.
Say I had a class that defines the property hello, I would like to access it to check it has been implemented and the type assigned to it is correct. Problem is, since all non-static class properties are tied to an instance, I can't get at them without instantiating the class, which I can't do.
In this situation, is it possible to access hello?
class MyClass {
constructor () {
this.hello = 'greetings';
}
}
In this situation, is it possible to access hello?
Not without using a JavaScript parser (like IDEs do to try to infer instance mbmers). hello, as you say, doesn't exist as a property until/unless an instance is created. With a parser, you can (usually) determine what the property names will be, perhaps sometimes their initial values, but that's all.

Example of Properties vs. Methods in JS

I found a great description of the semantic difference between Properties and Methods (paraphrased, via http://www.webdeveloper.com/forum/showthread.php?133712-Properties-Vs.-Methods):
Properties are like nouns. They have a value or state.
Methods are like verbs. They perform actions.
A property can't perform an action and the only value that a method has is the one that is returned after it finishes performing the action.
e.g.
Property: door; Possible Values: open, closed
Method: openDoor; Action: to change the value of the door property to "open"
Creating an example: I understand this in theory but I can't come up with an example. Would it be possible to show me how the door/openDoor would look in actual Javascript code?
Really, you need to back up and read some of the links posted above. But as a quick example:
var house = {} ;
house.isDoorOpen = false ;
house.openDoor = function(){
house.isDoorOpen = true ;
}
Here house is the object. It has a property: house.isDoorOpen. Here, it is more like an adjective. Either the door is open (true) or closed (false). As it sounds, it describes a property of the house.
Also, it has a method openDoor (which is used like this: house.openDoor() ). That's something that it can do. In this case, the action openDoor affects the isDoorOpen property, making it true.
Let's look at how the javascript spec ECMA-262 describes the term property
http://www.ecma-international.org/ecma-262/5.1/#sec-4.3.26
4.3.26 property
association between a name and a value that is a part of an object
NOTE Depending upon the form of the property the value may be
represented either directly as a data value (a primitive value, an
object, or a function object) or indirectly by a pair of accessor
functions.
4.3.27 method
function that is the value of a property
NOTE When a function is called as a method of an object, the object is
passed to the function as its this value.
Also
Javascript's definition of attribute is different from Java's
4.3.29 attribute
internal value that defines some characteristic of a property
for in, loops through an object's enumerable properties, and that includes its functions
http://eloquentjavascript.net/1st_edition/chapter8.html
"A function is called as a method when it is looked up as a property,
and immediately called, as in object.method()."
There does seem to be a more standard definition of property..
https://en.wikipedia.org/wiki/Property_(programming)#JavaScript
"A property, in some object-oriented programming languages, is a
special sort of class member, intermediate between a field (or data
member) and a method. .... Some object-oriented languages, such as
Java, don't support properties, and require the programmer to define a
pair of accessor and mutator methods instead."
In that more standard, non-javascript definition of property
C# has properties, and Java doesn't have properties
Object in JavaScript is just key-value pairs stored in a Hash. The difference between b/w property and method is that - property is a value stored in the hash key, whereas method is a function stored in the hash key.

Categories

Resources