Currently, I'm working on a project for my school whose purpose is to create an object pertaining to math; my object is similar to that of the Native Math object, and, as a result, I want to emulate certain aspects of it.
When using the console in Firefox, I have found that certain properties (e.g. E, PI, and SQRT2) cannot be edited (represented by a little lock on them). I know that there is a const declaration method, but I've tried both...
const obj = {
prop: function(x){
return x^3^4;
},
foo: "bar",
bar: "foo"
}
obj.prop = -3.14;
print(obj.prop); // prints "-3.14"
...and...
const unEditable = 2.718;
var obj = {e:unEditable};
obj.e = 3;
print(obj.e); // prints "3"
Is there a way to define properties of an object such that said properties cannot be edited by a user? By that, I mean could I assign obj a variable e with a value 2.718 so that when a person assigns obj.e a value of "Hello, world!, obj.e would still return 2.718?
Notes:
I have seen this question, which does not meet the needs of my question.
Code Fragmant
var Θ = {};
Θ.e = 2.71828;
Θ.pi = 3.14159;
Θ.fac = function(num){
if(!arguments.length) return NaN;
return (num<2)?(num<0)?Infinity:1:num*Θ.fac(num-1);
}
Θ.nroot = function(n,m){
return Θ.pow(n,1/m);
}
Conclusion
An answer based off of Wingblade's answer:
var Θ = {};
Object.defineProperties(Θ, {
pi: {
value: 3.14159,
writable: false
},
e: {
value: 2.71828,
writable: false
}
});
// rest of editable properties go after
You can use obj.defineProperty to add a property to an object in a more advanced way that offers more control over how the property will behave, for example if it is writeable or not.
More on this here: MDN Object.defineProperty()
EDIT: For defining multiple properties at once you can use Object.defineProperties() like so:
var o = {};
Object.defineProperties(o, {
"e": {
value: 2.71828,
writable: false
},
"pi": {
value: 3.14159,
writable: false
},
"fac": {
value: function(num){
if(!arguments.length) return;
return (num<2)?(num<0)?Infinity:1:num*o.fac(num-1);
},
writable: false
},
"nroot": {
value: function(n,m){
return o.pow(n,1/m);
},
writable: false
}
});
You can actually omit writeable: false for all properties, since it defaults to false when adding properties using Object.defineProperty, but it can be useful to leave it in for readability's sake (especially if you're new to this technique).
Related
I'm wondering when I should use
Object.defineProperty
to create new properties for an object. I'm aware that I'm able to set things like
enumerable: false
but when do you need this really? If you just set a property like
myObject.myprop = 5;
its descriptors are all set to true, right? I'm actually more curious when you guys use that rather verbose call to .defineProperty() and for what reasons.
Object.defineProperty is mainly used to set properties with specific property descriptors (e.g. read-only (constants), enumerability (to not show a property in a for (.. in ..) loop, getters, setters).
"use strict";
var myObj = {}; // Create object
// Set property (+descriptor)
Object.defineProperty(myObj, 'myprop', {
value: 5,
writable: false
});
console.log(myObj.myprop);// 5
myObj.myprop = 1; // In strict mode: TypeError: myObj.myprop is read-only
Example
This method extends the Object prototype with a property. Only the getter is defined, and the enumerability is set to false.
Object.defineProperty(Object.prototype, '__CLASS__', {
get: function() {
return Object.prototype.toString.call(this);
},
enumerable: false // = Default
});
Object.keys({}); // []
console.log([].__CLASS__); // "[object Array]"
Features like 'enumerable' are rarely used in my experience.
The major use case is computed properties:
var myObj = {};
myObj.width = 20;
myObj.height = 20;
Object.defineProperty(myObj, 'area', {
get: function() {
return this.width*this.height;
}
});
console.log(myObj.area);
A really good reason for using Object.defineProperty is that it lets you loop through a function in an object as a computed property, which executes the function instead of returning the function's body.
For example:
var myObj = {};
myObj.width = 20;
myObj.height = 20;
Object.defineProperty(myObj, 'area', {
get: function() {
return this.width*this.height;
},
enumerable: true
});
for (var key in myObj) {
if (myObj.hasOwnProperty(key)) {
console.log(key + " -> " + myObj[key]);
}
}
//width -> 20, height -> 20, area -> 400
Versus adding the function as a property to an object literal:
var myObj = {};
myObj.width = 20;
myObj.height = 20;
myObj.area = function() {
return this.width*this.height;
};
for (var key in myObj) {
if (myObj.hasOwnProperty(key)) {
console.log(key + " -> " + myObj[key]);
}
}
// width -> 20, height -> 20, area -> function() { return this.width*this.height;}
Make sure you set the enumerable property to true in order to loop through it.
For example, that's how Vue.js keeps track of changes in the data object:
When you pass a plain JavaScript object to a Vue instance as its data option, Vue will walk through all of its properties and convert them to getter/setters using Object.defineProperty. This is an ES5-only and un-shimmable feature, which is why Vue doesn’t support IE8 and below.
The getter/setters are invisible to the user, but under the hood they enable Vue to perform dependency-tracking and change-notification when properties are accessed or modified.
[...]
Keep in mind that even a super slim and basic version of Vue.js would use something more than just Object.defineProperty, but the main functionality comes from it:
Here you can see an article where the author implements a minimal PoC version of something like Vue.js: https://medium.com/js-dojo/understand-vue-reactivity-implementation-step-by-step-599c3d51cd6c
And here a talk (in Spanish) where the speaker builds something similar while explaining reactivity in Vue.js: https://www.youtube.com/watch?v=axXwWU-L7RM
Summary:
In Javascript Objects are collections of key-value pairs.
Object.defineProperty() is a function which can define a new property on an object and can set the following attributes of a property:
value <any>: The value associated with the key
writable <boolean>: if writable is set to true The property can be updated by assigning a new value to it. If set to false you can't change the value.
enumerable <boolean>: if enumerable is set to true Property can be accessed via a for..in loop. Furthermore are the only the enumerable property keys returned with Object.keys()
configurable <boolean>: If configurable is set to false you cannot change change the property attributes (value/writable/enumerable/configurable), also since you cannot change the value you cannot delete it using the delete operator.
Example:
let obj = {};
Object.defineProperty(obj, 'prop1', {
value: 1,
writable: false,
enumerable: false,
configurable: false
}); // create a new property (key=prop1, value=1)
Object.defineProperty(obj, 'prop2', {
value: 2,
writable: true,
enumerable: true,
configurable: true
}); // create a new property (key=prop2, value=2)
console.log(obj.prop1, obj.prop2); // both props exists
for(const props in obj) {
console.log(props);
// only logs prop2 because writable is true in prop2 and false in prop1
}
obj.prop1 = 100;
obj.prop2 = 100;
console.log(obj.prop1, obj.prop2);
// only prop2 is changed because prop2 is writable, prop1 is not
delete obj.prop1;
delete obj.prop2;
console.log(obj.prop1, obj.prop2);
// only prop2 is deleted because prop2 is configurable and prop1 is not
Object.defineProperty prevents you from accidentally assigning values to some key in its prototype chain. With this method you assign only to that particular object level(not to any key in prototype chain).
For example:
There is an object like {key1: value1, key2: value2} and you don't know exactly its prototype chain or by mistake you miss it and there is some property 'color' somewhere in prototype chain then-
using dot(.) assignment-
this operation will assign value to key 'color' in prototype chain(if key exist somewhere) and you will find the object with no change as .
obj.color= 'blue'; // obj remain same as {key1: value1, key2: value2}
using Object.defineProperty method-
Object.defineProperty(obj, 'color', {
value: 'blue'
});
// now obj looks like {key1: value1, key2: value2, color: 'blue'}. it adds property to the same level.Then you can iterate safely with method Object.hasOwnProperty().
One neat use case I have seen for defineProperty is for libraries to provide an error property to the user which, if it's not accessed within a certain interval you would log the error yourself. For example:
let logErrorTimeoutId = setTimeout(() => {
if (error) {
console.error('Unhandled (in <your library>)', error.stack || error);
}
}, 10);
Object.defineProperty(data, 'error', {
configurable: true,
enumerable: true,
get: () => {
clearTimeout(logErrorTimeoutId);
return error;
},
});
Source for this code: https://github.com/apollographql/react-apollo/blob/ddd3d8faabf135dca691d20ce8ab0bc24ccc414e/src/graphql.tsx#L510
A good use is when you need to do some interception or apply a classical Observer/Observable pattern in a elegant way:
https://www.monterail.com/blog/2016/how-to-build-a-reactive-engine-in-javascript-part-1-observable-objects
A very useful case is to monitor changes to something and act on them. It's easy because you can have callback functions fire whenever the value gets set. Here's a basic example.
You have an object Player that can be playing or not playing. You want something to happen right when it starts playing, and right when it stops playing.
function Player(){}
Object.defineProperty(Player.prototype, 'is_playing', {
get(){
return this.stored_is_playing; // note: this.is_playing would result in an endless loop
},
set(newVal){
this.stored_is_playing = newVal;
if (newVal === true) {
showPauseButton();
} else {
showPlayButton();
}
}
});
const cdplayer = new Player();
cdplayer.is_playing = true; // showPauseButton fires
This answer is related to a couple other answers here, which are good stepping points for more information, but with no need to follow external links to read about libraries or programming paradigms.
#Gerard Simpson
If 'area' should be enumerable it can be written without Object.defineProperty, too.
var myObj = {
get area() { return this.width * this.height }
};
myObj.width = 20;
myObj.height = 20;
for (var key in myObj) {
if (myObj.hasOwnProperty(key)) {
console.log(key + " -> " + myObj[key]);
}
}
//area -> 400, width -> 20, height -> 20
Problem:
According https://javascript.info/property-descriptors
property descriptors are like objects with own properties like:
{
value:
writable:
readable:
configurable:
enumerable:
}
one can do this with normal object:
for(var n in object) {
console.log(object[n]);
}
to write out the values of the keys in that object.
I want to do the same. Get descriptors, then for each descriptor print the value.
This is one of several ways I tried to do it. For each of the Property Descriptor in descriptors, print out the value of its properties.
I imagined getting something like
"John Doe"
0
etc...
Basically, put in other words, using Descriptors to show the values stored within an object.
Own tryes:
I tryed several times, so many times and ways that I
actually forgot, had to delete to to keep my head somewhat clear from the clutter of previous tryes. It resulted in all kinds of imaginable output except of what I expected. like numbers: 0, 1, 2, 3, 4... names of the properties instead of their values, or rows of "undefined" whilst I was expecting something like
"John Doe"
0
function
function
10 etc...
I DID check stackoverflow, AND other pages as well.
http://speakingjs.com/es5/ch17.html#property_attributes
being just one of say, 3-4.
It is NOT a homework, Also I do belive its probably not the best practise in doing it this way, using descriptors, but I got frustrated and obsessed, because I feel it should be possible.
I also apologize for eventuall weirdness in code. Im new at Javascript. I hope people focus on the problem and not on other stuff. English isnt my first language. I DID try to make the code as short as possible, and replicable. Hopefully Its clear what I want to do, otherwise Ill probably just give up xD.
Code
"use strict";
function Person() {
this._name = "";
this.age = 0;
this.greet = function() {
console.log(`hi Im ${this._name} and im ${this.age} years old`);
};
this.beep = function(times) {
for(var i = 0; i < times; i++) {
console.log("beeeep");
}
};
Object.defineProperty(this, "something", {
value: 10,
writable: false,
readable: true,
configurable: false,
enumerable: true,
});
Object.defineProperty(this, "name", {
get() {
return this._name;
},
set(nam) {
this._name = nam;
}
} );
}
var obj = new Person();
console.log(obj.something);
obj.name = "John Doe";
console.log(obj.name);
console.log("##############");
var properties = Object.getOwnPropertyDescriptors(obj);
for(var property in properties) {
for(var val in property) {
console.log(property[val]);
}
}
property is a key not a value, use that key to access the related value of the object:
for(var property in properties) {
for(var val in properties[property]) {
console.log(property, val, properties[property][val]);
}
}
property in your example at the end is a string, the name of the property in the object returned by getOwnPropertyDescriptors. You want the value of that property for your second loop:
var properties = Object.getOwnPropertyDescriptors(obj);
for(var property in properties) {
var descriptor = properties[property]; // ***
for(var val in descriptor) {
// *** --------^^^^^^^^^^
console.log(property[val]);
}
}
Or in a modern environment you'd probably use Object.values or Object.entries instead:
const properties = Object.getOwnPropertyDescriptors(obj);
for (const [propName, descriptor] of Object.entries(properties)) {
console.log(`${propName}:`);
for (const [key, value] of Object.entries(descriptor)) {
console.log(` ${key}: ${value}`);
}
}
Live Example:
"use strict";
function Person() {
this._name = "";
this.age = 0;
this.greet = function() {
console.log(`hi Im ${this._name} and im ${this.age} years old`);
};
this.beep = function(times) {
for(var i = 0; i < times; i++) {
console.log("beeeep");
}
};
Object.defineProperty(this, "something", {
value: 10,
writable: false,
readable: true,
configurable: false,
enumerable: true,
});
Object.defineProperty(this, "name", {
get() {
return this._name;
},
set(nam) {
this._name = nam;
}
} );
}
var obj = new Person();
console.log(obj.something);
obj.name = "John Doe";
console.log(obj.name);
console.log("##############");
const properties = Object.getOwnPropertyDescriptors(obj);
for (const [propName, descriptor] of Object.entries(properties)) {
console.log(`${propName}:`);
for (const [key, value] of Object.entries(descriptor)) {
console.log(` ${key}: ${value}`);
}
}
.as-console-wrapper {
max-height: 100% !important;
}
Own answer, Also clearly showing what I wanted to do
Apparently its almost encouraged to answer own questions.
What threw me off was that one sort of needs to "backreference" inside the for loops. (Perhaps due to learning Java before).
To get property value one needs to mention the object that contains it.
descriptions[property]
and to get what is inside that you need in turn write
descriptions[property][whatever]
Anyways. If anyone wondered, heres the now working code, albeight with slightly different variable names. But then again, shorter and easyer to follow. Shows exactly what I was looking for :D
"use strict";
function User(name, age) {
this.name = name;
this.age = age;
this.func = function() {
console.log("hola");
};
}
var person = new User("John Doe", 22);
var descriptors = Object.getOwnPropertyDescriptors(person);
for(var property in descriptors) {
console.log(property);
for(var k in descriptors[property]) { //<-------------
console.log(k + " " + descriptors[property][k]);//<-----------
}
console.log("_______________");
}
I denoted what I previously didnt get with arrows in the comments.
I want to create a closed object in javascript, that can be edited only using Object.defineProperty and not to be edited it in the normal way...
The goal is, I am creating a lib, where users can read an object called dictionary, but they can edit it too! is there any way to have an object that can be read by users, and edited by me ?
It is just not possible to protect any object parts.
See also:
How to Create Protected Object Properties in JavaScript
You can provide some basic protection using Object.defineProperty like this:
var o = { a: 5 };
o._protected = {};
o._protected.a = o.a;
Object.defineProperty(o, 'a', {
get: function() { return this._protected.a; },
set: function(value) {
if (value > 0 && value < 5) {
this._protected.a = value;
}
configurable: false
});
This will constrain changes to property a in this object so they will go through the get (read) / set (update). Of course, in this case the _protected object can be manipulated but it does require the user to consciously 'hack' it. Attempts to directly change property a would be under your control.
In this example, an attempt to set o.a = 6 would result in no change to o.a (of course, you could set it to the maximum allowed value in your set function if that were preferable).
You can prevent changes to o.a by not providing a set function.
This can be handy for ensuring properties only get 'valid' values and I've often used it that way.
I found it! please tell me what's the wrong with this solution:
var protected = {}
Object.defineProperty(this,
'setter', {
value: function(name , value) {
protected[name] = value
},
writable: false,
})
Object.defineProperty(this,
'getter', {
value: function(name , value) {
return JSON.parse(JSON.stringify(protected))
},
writable: false,
})
Object.freeze(this.setter)
Object.freeze(this.getter)
I have this small piece of code, that adds implement function to Object (I know, not a good practice). It copies properties of argument object (superobject) into the object, on which you call the method.
Object.prototype.implement = function(superobject) {
var props = {};
for (var key in superobject){
if (superobject.hasOwnProperty(key) && !this.hasOwnProperty(key))
props[key] = {
enumerable: true,
configurable: true,
get: this.implement.__get__(superobject, key),
set: this.implement.__set__(key)
};
}
Object.defineProperties(this, props);
return this;
};
Object.prototype.implement.__get__ = function(superobject, key){
return function(){return superobject[key];};
};
Object.prototype.implement.__set__ = function(key){
return function(value){
Object.defineProperty(this, key, {
value: value,
writable: true,
configurable: true,
enumerable: true
});
};
};
By copying, it actually creates own property, but the value is reference to the property of the superobject. This is done by the property "getter". This example shows a simple usage:
var obj1 = {
a:10
}
var obj2 = {
b:20
}
obj1.implement(obj2) // "implement" properties of obj2 to obj1
console.log(obj1.a) // -> 10
console.log(obj1.b) // -> 20
obj2.b = 21
console.log(obj1.a) // -> 10
console.log(obj1.b) // -> 21 -> it apperas to be reference to property b in obj2
obj1.hasOwnProperty("a") // -> true
obj1.hasOwnProperty("b") // -> true
obj1.b = 30;
console.log(obj1.b) // -> 30 //since obj1 has now "truly own" property b, it uses value of that instead of obj2's.
console.log(obj2.b) // -> 20
My question is this. After I call implement method on obj1, is obj1.b truly a reference? I mean - does obj1.b and obj2.b point to the same part of memory? Does the value b:20 exist only in one place in memory?
Is there maybe a good simple tool to see javascript's memory usage to confirm this?
I'm wondering when I should use
Object.defineProperty
to create new properties for an object. I'm aware that I'm able to set things like
enumerable: false
but when do you need this really? If you just set a property like
myObject.myprop = 5;
its descriptors are all set to true, right? I'm actually more curious when you guys use that rather verbose call to .defineProperty() and for what reasons.
Object.defineProperty is mainly used to set properties with specific property descriptors (e.g. read-only (constants), enumerability (to not show a property in a for (.. in ..) loop, getters, setters).
"use strict";
var myObj = {}; // Create object
// Set property (+descriptor)
Object.defineProperty(myObj, 'myprop', {
value: 5,
writable: false
});
console.log(myObj.myprop);// 5
myObj.myprop = 1; // In strict mode: TypeError: myObj.myprop is read-only
Example
This method extends the Object prototype with a property. Only the getter is defined, and the enumerability is set to false.
Object.defineProperty(Object.prototype, '__CLASS__', {
get: function() {
return Object.prototype.toString.call(this);
},
enumerable: false // = Default
});
Object.keys({}); // []
console.log([].__CLASS__); // "[object Array]"
Features like 'enumerable' are rarely used in my experience.
The major use case is computed properties:
var myObj = {};
myObj.width = 20;
myObj.height = 20;
Object.defineProperty(myObj, 'area', {
get: function() {
return this.width*this.height;
}
});
console.log(myObj.area);
A really good reason for using Object.defineProperty is that it lets you loop through a function in an object as a computed property, which executes the function instead of returning the function's body.
For example:
var myObj = {};
myObj.width = 20;
myObj.height = 20;
Object.defineProperty(myObj, 'area', {
get: function() {
return this.width*this.height;
},
enumerable: true
});
for (var key in myObj) {
if (myObj.hasOwnProperty(key)) {
console.log(key + " -> " + myObj[key]);
}
}
//width -> 20, height -> 20, area -> 400
Versus adding the function as a property to an object literal:
var myObj = {};
myObj.width = 20;
myObj.height = 20;
myObj.area = function() {
return this.width*this.height;
};
for (var key in myObj) {
if (myObj.hasOwnProperty(key)) {
console.log(key + " -> " + myObj[key]);
}
}
// width -> 20, height -> 20, area -> function() { return this.width*this.height;}
Make sure you set the enumerable property to true in order to loop through it.
For example, that's how Vue.js keeps track of changes in the data object:
When you pass a plain JavaScript object to a Vue instance as its data option, Vue will walk through all of its properties and convert them to getter/setters using Object.defineProperty. This is an ES5-only and un-shimmable feature, which is why Vue doesn’t support IE8 and below.
The getter/setters are invisible to the user, but under the hood they enable Vue to perform dependency-tracking and change-notification when properties are accessed or modified.
[...]
Keep in mind that even a super slim and basic version of Vue.js would use something more than just Object.defineProperty, but the main functionality comes from it:
Here you can see an article where the author implements a minimal PoC version of something like Vue.js: https://medium.com/js-dojo/understand-vue-reactivity-implementation-step-by-step-599c3d51cd6c
And here a talk (in Spanish) where the speaker builds something similar while explaining reactivity in Vue.js: https://www.youtube.com/watch?v=axXwWU-L7RM
Summary:
In Javascript Objects are collections of key-value pairs.
Object.defineProperty() is a function which can define a new property on an object and can set the following attributes of a property:
value <any>: The value associated with the key
writable <boolean>: if writable is set to true The property can be updated by assigning a new value to it. If set to false you can't change the value.
enumerable <boolean>: if enumerable is set to true Property can be accessed via a for..in loop. Furthermore are the only the enumerable property keys returned with Object.keys()
configurable <boolean>: If configurable is set to false you cannot change change the property attributes (value/writable/enumerable/configurable), also since you cannot change the value you cannot delete it using the delete operator.
Example:
let obj = {};
Object.defineProperty(obj, 'prop1', {
value: 1,
writable: false,
enumerable: false,
configurable: false
}); // create a new property (key=prop1, value=1)
Object.defineProperty(obj, 'prop2', {
value: 2,
writable: true,
enumerable: true,
configurable: true
}); // create a new property (key=prop2, value=2)
console.log(obj.prop1, obj.prop2); // both props exists
for(const props in obj) {
console.log(props);
// only logs prop2 because writable is true in prop2 and false in prop1
}
obj.prop1 = 100;
obj.prop2 = 100;
console.log(obj.prop1, obj.prop2);
// only prop2 is changed because prop2 is writable, prop1 is not
delete obj.prop1;
delete obj.prop2;
console.log(obj.prop1, obj.prop2);
// only prop2 is deleted because prop2 is configurable and prop1 is not
Object.defineProperty prevents you from accidentally assigning values to some key in its prototype chain. With this method you assign only to that particular object level(not to any key in prototype chain).
For example:
There is an object like {key1: value1, key2: value2} and you don't know exactly its prototype chain or by mistake you miss it and there is some property 'color' somewhere in prototype chain then-
using dot(.) assignment-
this operation will assign value to key 'color' in prototype chain(if key exist somewhere) and you will find the object with no change as .
obj.color= 'blue'; // obj remain same as {key1: value1, key2: value2}
using Object.defineProperty method-
Object.defineProperty(obj, 'color', {
value: 'blue'
});
// now obj looks like {key1: value1, key2: value2, color: 'blue'}. it adds property to the same level.Then you can iterate safely with method Object.hasOwnProperty().
One neat use case I have seen for defineProperty is for libraries to provide an error property to the user which, if it's not accessed within a certain interval you would log the error yourself. For example:
let logErrorTimeoutId = setTimeout(() => {
if (error) {
console.error('Unhandled (in <your library>)', error.stack || error);
}
}, 10);
Object.defineProperty(data, 'error', {
configurable: true,
enumerable: true,
get: () => {
clearTimeout(logErrorTimeoutId);
return error;
},
});
Source for this code: https://github.com/apollographql/react-apollo/blob/ddd3d8faabf135dca691d20ce8ab0bc24ccc414e/src/graphql.tsx#L510
A good use is when you need to do some interception or apply a classical Observer/Observable pattern in a elegant way:
https://www.monterail.com/blog/2016/how-to-build-a-reactive-engine-in-javascript-part-1-observable-objects
A very useful case is to monitor changes to something and act on them. It's easy because you can have callback functions fire whenever the value gets set. Here's a basic example.
You have an object Player that can be playing or not playing. You want something to happen right when it starts playing, and right when it stops playing.
function Player(){}
Object.defineProperty(Player.prototype, 'is_playing', {
get(){
return this.stored_is_playing; // note: this.is_playing would result in an endless loop
},
set(newVal){
this.stored_is_playing = newVal;
if (newVal === true) {
showPauseButton();
} else {
showPlayButton();
}
}
});
const cdplayer = new Player();
cdplayer.is_playing = true; // showPauseButton fires
This answer is related to a couple other answers here, which are good stepping points for more information, but with no need to follow external links to read about libraries or programming paradigms.
#Gerard Simpson
If 'area' should be enumerable it can be written without Object.defineProperty, too.
var myObj = {
get area() { return this.width * this.height }
};
myObj.width = 20;
myObj.height = 20;
for (var key in myObj) {
if (myObj.hasOwnProperty(key)) {
console.log(key + " -> " + myObj[key]);
}
}
//area -> 400, width -> 20, height -> 20