What are __defineGetter__() and __defineSetter__() functions? - javascript

What are __defineGetter__() and __defineSetter__() functions in prototype of every Object?

See the MDN docs here for a description and example code:
A getter is a method that gets the value of a specific property. A setter is a method that sets the value of a specific property. You can define getters and setters on any predefined core object or user-defined object that supports the addition of new properties.
As noted in the docs (and by # cwallenpoole), __define[GS]etter__() functions are now deprecated. There's a lot more detail in this article. I believe the defineProperty() function is now the preferred syntax.

To answer your question __defineGetter__() and __defineSetter__() are the old/original way to create a getter and a setter for an object's property. They allow you use an object's property as a name/value pair while behind the scenes these name/value pairs are supported by functions.
For example, let's say you wanted to reference some random numbers in fixed ranges. You could express these as words with the maximum of the range and it would look like a property.
var random = {};
random.__defineGetter__('ten', function() {
return Math.floor(Math.random()*10); });
random.__defineGetter__('hundred', function() {
return Math.floor(Math.random()*100); });
Note that the while the above example answers the question you should not use this solution. Instead you should use the modern form of getters and setters since ES5:
var random = {
get ten() { return Math.floor(Math.random()*10); },
get hundred() { return Math.floor(Math.random()*100); }
};
Either of the above constructs would allow you to get a random number like this:
var myrand = random.ten;
// returns a result in the range 0 to 9

.__defineGetter__ it means when you refer to object.[param1] a function is executed.
.__defineSetter__ it means when you set object.[param1] a function is executed.
for example, like this:
const person = {
firstName: 'john',
lastName: 'doe',
};
person.__defineGetter__('fullName', () => `${person.firstName} ${person.lastName}`);
person.__defineSetter__('fullName', v => {
person.firstName = v.split(' ')[0];
person.lastName = v.split(' ')[1];
});
or if you want cls to clear the console,
this.__defineGetter__('cls', console.clear);

Related

What is array besides string/arrays?

Trying to learn javascript by reading underscore sourcecode and came across the below code:
var shallowProperty = function(key) {
return function(obj) {
return obj == null ? void 0 : obj[key];
};
};
var getLength = shallowProperty('length');
console.log(getLength('123'))//3
console.log('123'['length'])//3
console.log(getLength(['1','2']))//2
console.log(['1','2']['length'])//2
My question is, what is [length] besides ['1','2']? Any technical terms to call it? Where can we get the full list of keys/attributes available other than length?
An array is a JavaScript object. An object can have properties. You can access them in a few, equivalent ways:
myObject.property
myObject['property']
See this MDN documentation.
To show all the properties of an object:
Object.getOwnPropertyNames(myObject);
You might like to refer to this question about listing the properties of an object.
Suppose you have the following object:
let person = {
name: 'foo',
age: 23
}
// Then, there are two possible ways to get the properties of "person" object
console.log(person.name); // logs 'foo'
console.log(person['name']); // logs 'foo'

How to make a "dot function" in javascript

I'm trying to define a "dot function" where there are no parameters but has a . and a string or number before it like these:
.toUpperCase()
.toLowerCase()
.indexOf()
.charAt()
.substring()
You do 2..toString, not toString(2).
How do you define one of them?
Defining a "dot function" is easy. Here's how you can define it on a single object.
var a = {}, or a = function() {}, or a = [], etc.
a.dotFunction = function() { return 'hi'; }
console.log(a.dotFunction());
If you want to define it on all instances of a "class", use prototype.
function someClass() {
}
someClass.prototype.dotFunction = function() { return 'hi'; };
console.log(new someClass().dotFunction());
You can even do this on built-in types (some, like Prototype.js, do this, though most recommended against it).
Number.prototype.dotFunction = function() { return 'hi'; };
console.log((0).dotFunction());
I'd strongly recommend not trying to replace any built-in methods, however, you're free to define your own methods however you like.
You can do this by attaching the method to the Number or String type's prototype:
Number.prototype.foo = function(n) { return this * n; };
String.prototype.bar = function(n) { return this.length * n; };
alert(4..foo(2)); // 8
alert("4".bar(2)); // 2
Further Reading
Inheritance and the prototype chain
I'll give it a shot because nobody mentioned that you can already do this without having to define anything yourself.
A thing to take care of is if you have a number you have to place 2 dots after it where as if you have a function that returns a number or a variable that holds one you don't:
1..toString()
.indexOf("1")//<=returns number 0
//even though a number is returned we only need one dot here
.toString();//<="0"
var num = 1234;
num.toString()//<=one dot
.indexOf("23");//<=1
Your example would already work but since indexOf would return a number if you give it an argument that makes sense and a number doesn't have a charAt method.
"hello".toUpperCase()
.toLowerCase()
.indexOf("h")//<=returns a number
//number has no charAt method
.toString()
.charAt(0)
.substring(0);//<="0"

Is there a way to provide named parameters in a function call in JavaScript?

I find the named parameters feature in C# quite useful in some cases.
calculateBMI(70, height: 175);
What can I use if I want this in JavaScript?
What I don’t want is this:
myFunction({ param1: 70, param2: 175 });
function myFunction(params){
// Check if params is an object
// Check if the parameters I need are non-null
// Blah blah
}
That approach I’ve already used. Is there another way?
I’m okay using any library to do this.
ES2015 and later
In ES2015, parameter destructuring can be used to simulate named parameters. It would require the caller to pass an object, but you can avoid all of the checks inside the function if you also use default parameters:
myFunction({ param1 : 70, param2 : 175});
function myFunction({param1, param2}={}){
// ...function body...
}
// Or with defaults,
function myFunc({
name = 'Default user',
age = 'N/A'
}={}) {
// ...function body...
}
ES5
There is a way to come close to what you want, but it is based on the output of Function.prototype.toString [ES5], which is implementation dependent to some degree, so it might not be cross-browser compatible.
The idea is to parse the parameter names from the string representation of the function so that you can associate the properties of an object with the corresponding parameter.
A function call could then look like
func(a, b, {someArg: ..., someOtherArg: ...});
where a and b are positional arguments and the last argument is an object with named arguments.
For example:
var parameterfy = (function() {
var pattern = /function[^(]*\(([^)]*)\)/;
return function(func) {
// fails horribly for parameterless functions ;)
var args = func.toString().match(pattern)[1].split(/,\s*/);
return function() {
var named_params = arguments[arguments.length - 1];
if (typeof named_params === 'object') {
var params = [].slice.call(arguments, 0, -1);
if (params.length < args.length) {
for (var i = params.length, l = args.length; i < l; i++) {
params.push(named_params[args[i]]);
}
return func.apply(this, params);
}
}
return func.apply(null, arguments);
};
};
}());
Which you would use as:
var foo = parameterfy(function(a, b, c) {
console.log('a is ' + a, ' | b is ' + b, ' | c is ' + c);
});
foo(1, 2, 3); // a is 1 | b is 2 | c is 3
foo(1, {b:2, c:3}); // a is 1 | b is 2 | c is 3
foo(1, {c:3}); // a is 1 | b is undefined | c is 3
foo({a: 1, c:3}); // a is 1 | b is undefined | c is 3
DEMO
There are some drawbacks to this approach (you have been warned!):
If the last argument is an object, it is treated as a "named argument objects"
You will always get as many arguments as you defined in the function, but some of them might have the value undefined (that's different from having no value at all). That means you cannot use arguments.length to test how many arguments have been passed.
Instead of having a function creating the wrapper, you could also have a function which accepts a function and various values as arguments, such as
call(func, a, b, {posArg: ... });
or even extend Function.prototype so that you could do:
foo.execute(a, b, {posArg: ...});
No - the object approach is JavaScript's answer to this. There is no problem with this provided your function expects an object rather than separate params.
Lots of people say to just use the "Pass an object" trick so that you have named parameters.
/**
* My Function
*
* #param {Object} arg1 Named arguments
*/
function myFunc(arg1) { }
myFunc({ param1 : 70, param2 : 175});
And that works great, except... when it comes to most IDEs out there, a lot of us developers rely on type / argument hints within our IDE. I personally use PhpStorm (along with other JetBrains IDEs, like PyCharm for Python and AppCode for Objective-C).
And the biggest problem with using the "Pass an object" trick is that when you are calling the function, the IDE gives you a single type hint and that's it... How are we supposed to know what parameters and types should go into the arg1 object?
So... the "Pass an object" trick doesn't work for me... It actually causes more headaches with having to look at each function's docblock before I know what parameters the function expects.... Sure, it's great for when you are maintaining existing code, but it's horrible for writing new code.
Well, this is the technique I use... Now, there may be some issues with it, and some developers may tell me I'm doing it wrong, and I have an open mind when it comes to these things... I am always willing to look at better ways of accomplishing a task... So, if there is an issue with this technique, then comments are welcome.
/**
* My Function
*
* #param {string} arg1 Argument 1
* #param {string} arg2 Argument 2
*/
function myFunc(arg1, arg2) { }
var arg1, arg2;
myFunc(arg1='Param1', arg2='Param2');
This way, I have the best of both worlds. New code is easy to write as my IDE gives me all the proper argument hints. And, while maintaining code later on, I can see at a glance, not only the value passed to the function, but also the name of the argument. The only overhead I see is declaring your argument names as local variables to keep from polluting the global namespace. Sure, it's a bit of extra typing, but it's trivial compared to the time it takes to look up docblocks while writing new code or maintaining existing code.
Update - 2022
JavaScript now has the ability to have something close to named parameters using object destructuring available in ES6. Most newer browsers can use this feature See browser support
This is how it works:
// Define your function like this
function myFunc({arg1, arg2, arg3}) {
// Function body
}
// Call your function like this
myFunc({arg1: "value1", arg2: "value2", arg3: "value3"})
// You can also have default values for arguments
function myFunc2({firstName, lastName, age = 21}) {
// Function body
}
// And you can call it with or without an "age" argument
myFunc({firstName: "John", lastName: "Doe"}) // Age will be 21
myFunc({firstName: "Jane", lastName: "Doe", age: 22})
The best part is that most IDE's now support this syntax and you get good argument hint support
TypeScript
For those of you using TypeScript, you can do the same thing using this syntax
function myFunc(
{firstName, lastName, age = 21}:
{firstName: string, lastName: string, age?: number}
) {
// Function body
}
OR, using an interface
interface Params {
firstName: string
lastName: string
age?: number
}
function myFunc({firstName, lastName, age = 21}: Params) {
// Function body
}
If you want to make it clear what each of the parameters are, rather than just calling
someFunction(70, 115);
do the following:
var width = 70, height = 115;
someFunction(width, height);
Sure, it's an extra line of code, but it wins on readability.
Another way would be to use attributes of a suitable object, e.g. like so:
function plus(a,b) { return a+b; };
Plus = { a: function(x) { return { b: function(y) { return plus(x,y) }}},
b: function(y) { return { a: function(x) { return plus(x,y) }}}};
sum = Plus.a(3).b(5);
Of course for this made up example it is somewhat meaningless. But in cases where the function looks like
do_something(some_connection_handle, some_context_parameter, some_value)
it might be more useful. It also could be combined with "parameterfy" idea to create such an object out of an existing function in a generic way. That is for each parameter it would create a member that can evaluate to a partial evaluated version of the function.
This idea is of course related to Schönfinkeling aka Currying.
Calling function f with named parameters passed as the object
o = {height: 1, width: 5, ...}
is basically calling its composition f(...g(o)) where I am using the spread syntax and g is a "binding" map connecting the object values with their parameter positions.
The binding map is precisely the missing ingredient, that can be represented by the array of its keys:
// map 'height' to the first and 'width' to the second param
binding = ['height', 'width']
// take binding and arg object and return aray of args
withNamed = (bnd, o) => bnd.map(param => o[param])
// call f with named args via binding
f(...withNamed(binding, {hight: 1, width: 5}))
Note the three decoupled ingredients: the function, the object with named arguments and the binding. This decoupling allows for a lot of flexibility to use this construct, where the binding can be arbitrarily customized in function's definition and arbitrarily extended at the function call time.
For instance, you may want to abbreviate height and width as h and w inside your function's definition, to make it shorter and cleaner, while you still want to call it with full names for clarity:
// use short params
f = (h, w) => ...
// modify f to be called with named args
ff = o => f(...withNamed(['height', 'width'], o))
// now call with real more descriptive names
ff({height: 1, width: 5})
This flexibility is also more useful for functional programming, where functions can be arbitrarily transformed with their original param names getting lost.
There is another way. If you're passing an object by reference, that object's properties will appear in the function's local scope. I know this works for Safari (haven't checked other browsers) and I don't know if this feature has a name, but the below example illustrates its use.
Although in practice I don't think that this offers any functional value beyond the technique you're already using, it's a little cleaner semantically. And it still requires passing a object reference or an object literal.
function sum({ a:a, b:b}) {
console.log(a+'+'+b);
if(a==undefined) a=0;
if(b==undefined) b=0;
return (a+b);
}
// will work (returns 9 and 3 respectively)
console.log(sum({a:4,b:5}));
console.log(sum({a:3}));
// will not work (returns 0)
console.log(sum(4,5));
console.log(sum(4));
Coming from Python this bugged me. I wrote a simple wrapper/Proxy for node that will accept both positional and keyword objects.
https://github.com/vinces1979/node-def/blob/master/README.md
NB. My answer of 2016 is not correct and misleading as mentioned in comments.
Trying Node-6.4.0 ( process.versions.v8 = '5.0.71.60') and Node Chakracore-v7.0.0-pre8 and then Chrome-52 (V8=5.2.361.49), I've noticed that named parameters are almost implemented, but that order has still precedence. I can't find what the ECMA standard says.
>function f(a=1, b=2){ console.log(`a=${a} + b=${b} = ${a+b}`) }
> f()
a=1 + b=2 = 3
> f(a=5)
a=5 + b=2 = 7
> f(a=7, b=10)
a=7 + b=10 = 17
But order is required!! Is it the standard behaviour?
> f(b=10)
a=10 + b=2 = 12
This is admittedly pseudocode, but I believe it'll work (I know it works in TypeScript; I'm adopting it for JavaScript).
// Target Function
const myFunc = (a=1,b=2,c=3) => {a+b+c}
// Goal usage:
myFunc(a=5, b=6) // 14
myFunc(c=0) // 3
// Set your defaults
const myFuncDefaults = {a:1, b:2, c:3};
// Override them with passed parameters
const myFuncParams = (params) => { return Object.assign(myFuncDefaults, params)}
// Use the overloaded dict as the input
const myFunc2 = (params) => {
let {a, b, c} = myFuncParams(params);
return myFunc(a, b, c)
}
// Usage:
myFunc({a:5, b:6}) // 14
myFunc({c:0}) // 3
// Written more succinctly:
const myFunc = (params) => {
let {a,b,c} = Object.assign({a:1, b:2, c:3}, params)
return a + b + c
}
For what it's worth, TypeScript makes this kind of nice with hinting:
interface IParams {
a: number;
b: number;
c: number;
}
const myFunc = (params: Partial<IParams>): number => {
const default: IParams = {a:1, b:2, c:3};
let {a, b, c} = Object.assign(default, params)
return a + b + c
}
Yes, well, kind of. I've found two solutions. I'll explain just one.
In this solution, we give up positional arguments, though.
We can use an object (almost identical to a dict in Python) to pass the arguments.
In this example, I'm using the function to generate the name of a image file:
// First we define our function with just ONE argument
function name_of_img(img_desc){
// With this step, any undefined value will be assigned a value
if(img_desc.size == undefined) {img_desc.size = "400x500"}
if(img_desc.format == undefined) {img_desc.format = ".png"}
console.log(img_desc.size + img_desc.format)
}
// Notice inside our function we're passing a dict/object
name_of_img({size: "200x250", format : ".jpg"})
// In Python name_of_img(size="200x250" , format="jpg")
// returns "200x250.jpg"
name_of_img({size: "1200x950"})
// In Python name_of_img(size="1200x950")
// returns "1200x950.png"
We can modify this example, so we can use positional arguments too, we can also modify it so non valid arguments can be passed, I think I will make a GitHub repository about this.
Contrary to what is commonly believed, named parameters can be implemented in standard, old-school JavaScript (for boolean parameters only) by means of a simple, neat coding convention, as shown below.
function f(p1=true, p2=false) {
...
}
f(!!"p1"==false, !!"p2"==true); // call f(p1=false, p2=true)
Caveats:
Ordering of arguments must be preserved - but the pattern is still useful, since it makes it obvious which actual argument is meant for which formal parameter without having to grep for the function signature or use an IDE.
This only works for booleans. However, I'm sure a similar pattern could be developed for other types using JavaScript's unique type coercion semantics.

How to display all methods of an object?

I want to know how to list all methods available for an object like for example:
alert(show_all_methods(Math));
This should print:
abs, acos, asin, atan, atan2, ceil, cos, exp, floor, log, max, min, pow, random,round, sin, sqrt, tan, …
You can use Object.getOwnPropertyNames() to get all properties that belong to an object, whether enumerable or not. For example:
console.log(Object.getOwnPropertyNames(Math));
//-> ["E", "LN10", "LN2", "LOG2E", "LOG10E", "PI", ...etc ]
You can then use filter() to obtain only the methods:
console.log(Object.getOwnPropertyNames(Math).filter(function (p) {
return typeof Math[p] === 'function';
}));
//-> ["random", "abs", "acos", "asin", "atan", "ceil", "cos", "exp", ...etc ]
In ES3 browsers (IE 8 and lower), the properties of built-in objects aren't enumerable. Objects like window and document aren't built-in, they're defined by the browser and most likely enumerable by design.
From ECMA-262 Edition 3:
Global Object
There is a unique global
object (15.1), which is created before
control enters any execution context.
Initially the global object has the
following properties:
• Built-in
objects such as Math, String, Date,
parseInt, etc. These have attributes {
DontEnum }.
• Additional host defined
properties. This may include a
property whose value is the global
object itself; for example, in the
HTML document object model the window
property of the global object is the
global object itself.
As control
enters execution contexts, and as
ECMAScript code is executed,
additional properties may be added to
the global object and the initial
properties may be changed.
I should point out that this means those objects aren't enumerable properties of the Global object. If you look through the rest of the specification document, you will see most of the built-in properties and methods of these objects have the { DontEnum } attribute set on them.
Update: a fellow SO user, CMS, brought an IE bug regarding { DontEnum } to my attention.
Instead of checking the DontEnum attribute, [Microsoft] JScript will skip over any property in any object where there is a same-named property in the object's prototype chain that has the attribute DontEnum.
In short, beware when naming your object properties. If there is a built-in prototype property or method with the same name then IE will skip over it when using a for...in loop.
It's not possible with ES3 as the properties have an internal DontEnum attribute which prevents us from enumerating these properties. ES5, on the other hand, provides property descriptors for controlling the enumeration capabilities of properties so user-defined and native properties can use the same interface and enjoy the same capabilities, which includes being able to see non-enumerable properties programmatically.
The getOwnPropertyNames function can be used to enumerate over all properties of the passed in object, including those that are non-enumerable. Then a simple typeof check can be employed to filter out non-functions. Unfortunately, Chrome is the only browser that it works on currently.
​function getAllMethods(object) {
return Object.getOwnPropertyNames(object).filter(function(property) {
return typeof object[property] == 'function';
});
}
console.log(getAllMethods(Math));
logs ["cos", "pow", "log", "tan", "sqrt", "ceil", "asin", "abs", "max", "exp", "atan2", "random", "round", "floor", "acos", "atan", "min", "sin"] in no particular order.
var methods = [];
for (var m in obj) {
if (typeof obj[m] == "function") {
methods.push(m);
}
}
alert(methods.join(","));
This way, you will get all methods that you can call on obj. This includes the methods that it "inherits" from its prototype (like getMethods() in java). If you only want to see those methods defined directly by obj you can check with hasOwnProperty:
var methods = [];
for (var m in obj) {
if (typeof obj[m] == "function" && obj.hasOwnProperty(m)) {
methods.push(m);
}
}
alert(methods.join(","));
Most modern browser support console.dir(obj), which will return all the properties of an object that it inherited through its constructor. See Mozilla's documentation for more info and current browser support.
console.dir(Math)
=> MathConstructor
E: 2.718281828459045
LN2: 0.6931471805599453
...
tan: function tan() { [native code] }
__proto__: Object
The other answers here work for something like Math, which is a static object. But they don't work for an instance of an object, such as a date. I found the following to work:
function getMethods(o) {
return Object.getOwnPropertyNames(Object.getPrototypeOf(o))
.filter(m => 'function' === typeof o[m])
}
//example: getMethods(new Date()): [ 'getFullYear', 'setMonth', ... ]
https://jsfiddle.net/3xrsead0/
This won't work for something like the original question (Math), so pick your solution based on your needs. I'm posting this here because Google sent me to this question but I was wanting to know how to do this for instances of objects.
Approach that works nicely with ES6 classes and inheritance
This is likely what most newbie ES6 users like me mean when they are looking for "how to list object methods".
This has been adapted from: https://stackoverflow.com/a/47714550/895245
// Define getMethods.
const isGetter = (x, name) => (Object.getOwnPropertyDescriptor(x, name) || {}).get
const isFunction = (x, name) => typeof x[name] === "function";
const deepFunctions = x =>
x && x !== Object.prototype &&
Object.getOwnPropertyNames(x)
.filter(name => isGetter(x, name) || isFunction(x, name))
.concat(deepFunctions(Object.getPrototypeOf(x)) || []);
const distinctDeepFunctions = x => Array.from(new Set(deepFunctions(x)));
const getMethods = (obj) => distinctDeepFunctions(obj).filter(
name => name !== "constructor" && !~name.indexOf("__"));
// Example usage.
class BaseClass {
override() { }
baseMethod() { }
}
class DerivedClass extends BaseClass {
override() { }
get myGetter() { }
static myStatic() { }
}
const obj = new DerivedClass();
const methods = getMethods(obj)
methods.sort()
const assert = require('assert')
assert(methods[0] === 'baseMethod')
assert(methods[1] === 'myGetter')
assert(methods[2] === 'override')
console.log(getMethods(Math))
Note how it also includes methods of base classes as most users will want to see which methods they can call on the object.
It also appears to work with Math, it output:
[
'abs', 'acos', 'acosh', 'asin',
'asinh', 'atan', 'atanh', 'atan2',
'ceil', 'cbrt', 'expm1', 'clz32',
'cos', 'cosh', 'exp', 'floor',
'fround', 'hypot', 'imul', 'log',
'log1p', 'log2', 'log10', 'max',
'min', 'pow', 'random', 'round',
'sign', 'sin', 'sinh', 'sqrt',
'tan', 'tanh', 'trunc'
]
Tested on Node.js 14.17.0.
Math has static method where you can call directly like Math.abs() while Date has static method like Date.now() and also instance method where you need to create new instance first var time = new Date() to call time.getHours().
// The instance method of Date can be found on `Date.prototype` so you can just call:
var keys = Object.getOwnPropertyNames(Date.prototype);
// And for the static method
var keys = Object.getOwnPropertyNames(Date);
// But if the instance already created you need to
// pass its constructor
var time = new Date();
var staticKeys = Object.getOwnPropertyNames(time.constructor);
var instanceKeys = Object.getOwnPropertyNames(time.constructor.prototype);
Of course you will need to filter the obtained keys for the static method to get actual method names, because you can also get length, name that aren't a function on the list.
But how if we want to obtain all available method from class that extend another class?
Of course you will need to scan through the root of prototype like using __proto__. For saving your time you can use script below to get static method and deep method instance.
// var keys = new Set();
function getStaticMethods(keys, clas){
var keys2 = Object.getOwnPropertyNames(clas);
for(var i = 0; i < keys2.length; i++){
if(clas[keys2[i]].constructor === Function)
keys.add(keys2[i]);
}
}
function getPrototypeMethods(keys, clas){
if(clas.prototype === void 0)
return;
var keys2 = Object.getOwnPropertyNames(clas.prototype);
for (var i = keys2.length - 1; i >= 0; i--) {
if(keys2[i] !== 'constructor')
keys.add(keys2[i]);
}
var deep = Object.getPrototypeOf(clas);
if(deep.prototype !== void 0)
getPrototypeMethods(keys, deep);
}
// ====== Usage example ======
// To avoid duplicate on deeper prototype we use `Set`
var keys = new Set();
getStaticMethods(keys, Date);
getPrototypeMethods(keys, Date);
console.log(Array.from(keys));
If you want to obtain methods from created instance, don't forget to pass the constructor of it.
The short answer is you can't because Math and Date (off the top of my head, I'm sure there are others) are't normal objects. To see this, create a simple test script:
<html>
<body>
<script type="text/javascript" src="http://ajax.googleapis.com/ajax/libs/jquery/1.4.1/jquery.min.js"></script>
<script type="text/javascript">
$(function() {
alert("Math: " + Math);
alert("Math: " + Math.sqrt);
alert("Date: " + Date);
alert("Array: " + Array);
alert("jQuery: " + jQuery);
alert("Document: " + document);
alert("Document: " + document.ready);
});
</script>
</body>
</html>
You see it presents as an object the same ways document does overall, but when you actually try and see in that object, you see that it's native code and something not exposed the same way for enumeration.
I believe there's a simple historical reason why you can't enumerate
over methods of built-in objects like Array for instance. Here's why:
Methods are properties of the prototype-object, say Object.prototype.
That means that all Object-instances will inherit those methods. That's
why you can use those methods on any object. Say .toString() for instance.
So IF methods were enumerable, and I would iterate over say {a:123}
with: "for (key in {a:123}) {...}" what would happen? How many times
would that loop be executed?
It would be iterated once for the single key 'a' in our example. BUT ALSO
once for every enumerable property of Object.prototype. So if
methods were enumerable (by default), then any loop over any object would loop
over all its inherited methods as well.
Inspired by the other answers, here's a recursive way of finding all methods:
// Find all methods of an object, up to the root prototype
function findAllMethods(obj, methods = []) {
if (!obj) {
return [...new Set(methods)];
}
const props = Object.getOwnPropertyNames(obj);
return findAllMethods(Object.getPrototypeOf(obj), [
...methods,
...props.filter(prop => typeof obj[prop] === 'function'),
]);
}
If you want all methods including inherited ones:
function getMethods(obj) {
const methods = [];
do {
for (const prop of Object.getOwnPropertyNames(obj)) {
if (obj[prop] instanceof Function) methods.push(prop);
}
obj = Object.getPrototypeOf(obj);
} while (obj !== null)
return methods;
}
console.log(getMethods(Math));

What is this javascript code doing?

this.String = {
Get : function (val) {
return function() {
return val;
}
}
};
What is the ':' doing?
this.String = {} specifies an object. Get is a property of that object. In javascript, object properties and their values are separated by a colon ':'.
So, per the example, you would call the function like this
this.String.Get('some string');
More examples:
var foo = {
bar : 'foobar',
other : {
a : 'wowza'
}
}
alert(foo.bar); //alerts 'foobar'
alert(foo.other.a) //alerts 'wowza'
Others have already explained what this code does. It creates an object (called this.String) that contains a single function (called Get). I'd like to explain when you could use this function.
This function can be useful in cases where you need a higher order function (that is a function that expects another function as its argument).
Say you have a function that does something to each element of an Array, lets call it map. You could use this function like so:
function inc (x)
{
return x + 1;
}
var arr = [1, 2, 3];
var newArr = arr.map(inc);
What the map function will do, is create a new array containing the values [2, 3, 4]. It will do this by calling the function inc with each element of the array.
Now, if you use this method a lot, you might continuously be calling map with all sorts of arguments:
arr.map(inc); // to increase each element
arr.map(even); // to create a list of booleans (even or odd)
arr.map(toString); // to create a list of strings
If for some reason you'd want to replace the entire array with the same string (but keeping the array of the same size), you could call it like so:
arr.map(this.String.Get("my String"));
This will create a new array of the same size as arr, but just containing the string "my String" over and over again.
Note that in some languages, this function is predefined and called const or constant (since it will always return the same value, each time you call it, no matter what its arguments are).
Now, if you think that this example isn't very useful, I would agree with you. But there are cases, when programming with higher order functions, when this technique is used.
For example, it can be useful if you have a tree you want to 'clear' of its values but keep the structure of the tree. You could do tree.map(this.String.Get("default value")) and get a whole new tree is created that has the exact same shape as the original, but none of its values.
It assigns an object that has a property "Get" to this.String. "Get" is assigned an anonymous function, which will return a function that just returns the argument that was given to the first returning function. Sounds strange, but here is how it can be used:
var ten = this.String["Get"](10)();
ten will then contain a 10. Instead, you could have written the equivalent
var ten = this.String.Get(10)();
// saving the returned function can have more use:
var generatingFunction = this.String.Get("something");
alert(generatingFunction()); // displays "something"
That is, : just assigns some value to a property.
This answer may be a bit superflous since Tom's is a good answer but just to boil it down and be complete:-
this.String = {};
Adds an object to the current object with the property name of String.
var fn = function(val) {
return function() { return(val); }
}
Returns a function from a closure which in turn returns the parameter used in creating the closure. Hence:-
var fnInner = fn("Hello World!");
alert(fnInner()); // Displays Hello World!
In combination then:-
this.String = { Get: function(val) {
return function() { return(val); }
}
Adds an object to the current object with the property name of String that has a method called Get that returns a function from a closure which in turn returns the parameter used in creating the closure.
var fnInner = this.String.Get("Yasso!");
alert(fnInner()); //displays Yasso!

Categories

Resources