After going through this question
globals() give the dictionary view of the global namespace(__main__ module).
>>> globals()
{'__builtins__': <module '__builtin__' (built-in)>, '__name__': '__main__', '__doc__': None, '__package__': None}
>>>
Any new symbol(name), say operator added to this namespace, will become a member of that global name space.
>>> import operator
>>> globals()
{'__builtins__': <module '__builtin__' (built-in)>, '__name__': '__main__', '__doc__': None, 'operator': <module 'operator' (built-in)>, '__package__': None}
>>> globals()['operator']
<module 'operator' (built-in)>
>>>
where operator is a new str type key, value is the module type object.
further on using operator module(say __abs__), in current namespace,
>>> globals()['operator']['__abs__']
Traceback (most recent call last):
File "<pyshell#11>", line 1, in <module>
globals()['operator']['__abs__']
TypeError: 'module' object has no attribute '__getitem__'
>>>
It says, operator module is not a dictionary because there is no attribute by name __getitem__.
But, all the code from my application(in runtime), will be part of the dictionary shown by globals() function.
Question:
Ignoring coding standards,
In JavaScript, I can use dictionary notation to write my complete code, for example,
> window['Array']
function Array() { [native code] }
> window['Array']['length']
1
In python, Why global namespace members(keys) are only viewed as dictionary members but not their values(like operator object)? Despite all the subsequent code of your program, is part of that dictionary.
In Python, there is a difference between attribute references, the syntax where you use dots to access attributes of objects, and subscriptions, where you use square brackets to access items of an object.
You can use this difference in your custom types by using the special methods __getitem__ (and the related methods for setting etc.) and __getattr__ (and related methods). So you can implement your types to support both syntaxes to achieve the same; or you can use it to assign difference semantics to each syntax as it is the case for standard Python types.
As for why this distinction is made, this is simply a language design decision that was made, which ultimately makes the language more powerful. For example, this allows a dictionary to have a key 'update', when there is also an attribute—a method in this case—called dict.update.
Also, not depending on the equivalence of foo.bar and foo['bar'] avoids limiting subscription keys to strings, like it is the case with JavaScript. Instead, we can use any hashable object as a key. This makes the dict type similar to JavaScripts newer Map type which also supports a wide range of key types. Note that because of JavaScript’s inferior syntax choices, there are explit methods get and set to access the map items.
1.
JS doesn't have dictionaries. They are emulated by using objects.
What you are doing when defining a dictionary or associative array, or however you want to call it in javascript is
assigning values to attributes of a new object.
2.
Python has actual data type dictionary i.e. dict() which IS AN OBJECT (everything in Python is) specialized to store pairs key: value and optimized for fast access.
This is actually a container that holds Python scopes. I.e. when you call
globals()
You do not get a view of global variables. You do get a pointer to the real global scope.
So, if you say:
globals()["abcdefgh"] = 123456
you will be able to
print abcdefgh
because you directly inserted the variable abcdefgh into interpreters global namespace holder.
This happens when you use = assignment operator automatically.
So, globals() dictionary contains real values, which are objects, but not necessarily dictionaries.
In JS what you describe works, because what you are actually doing is in Python this:
class obj: pass
somevar = obj()
somevar.one = 1
somevar.two = "two"
somevar.something = "nothing"
And if you want to see them as dict, then you have to get to the somevar instance's namespace dictionary:
print somevar.__dict__
somevar.__dict__["blah"] = "xxx"
print somevar.__dict__
print dir(somevar) # To see all attributes of obj()
Otherwise it is:
print somevar
<__main__.obj instance at 0xxxxxxxxx>
And if you want the obj() instance to act as a dict() then you have to implement the dictionary's interface for it.
In JS it is always just another object, so syntax continues to work regardless on how it was defined in the first place.
Related
My understanding of the data type is as follows. If we consider a machine like a mill that can take in rice, barley, corn, kidney beans, chickpeas, black beans, etc. So I understand the mill to be the program that processes data such as rice, barley, etc. The data are rice, barley, beans but they differ in types. Rice is of a different type than barley etc.
In javascript, i noticed objects mentioned under data types.
https://javascript.info/types#objects-and-symbols
It makes sense that 23 is data of type number, "cat" is data of type string, true is data of type "boolean" but object seems to be more like a data container rather than a data type. For instance, typeof([]) says it is an object. Now array seems like a data container rather than data and type of a data container doesn't make sense. To me, it makes sense that a data can have a type but a container where we put data having a type is confusing.
So I appreciate if someone can enlighten me. Array seems to be a container and not data and cannot have a type.
I appreciate any guide. Thanks!
On a general, theoretic level, an object consists of data that describes the object, and behaviours that act on that object. Before Object Oriented Programming, data was data, and code was code; if you needed to load some data, and draw it on the screen, chances are those two pieces of code would be in different places of your code base. OOP brings data and behaviour together for better conceptual organisation. It also allows some objects to share behaviour by sorting them into classes (e.g. "barking" is not something that needs to be coded for every dog individually) or by creating object prototypes (same idea, different approach). Furthermore, it allows different objects to specify different ways of performing the same behaviour (e.g. both cats and wolves know about hunting, though they go about it differently).
On a mechanical JavaScript-specific level, "object" is a data structure that can store various values under string keys. It is thus superficially similar to arrays, which again store values, but under integer keys.
However, "value" in JavaScript also includes functions, which is how JS object achieves the first objective (being a repository of related data and code that governs its behaviour). The second objective is achieved by prototypal inheritance:
let Mammal = function() {
}
let typicalMammal = new Mammal();
typicalMammal.legs = 4;
Mammal.prototype = typicalMammal;
let Dog = function() {
};
let typicalDog = new Mammal();
typicalDog.sound = function() { console.log("woof") };
Dog.prototype = typicalDog;
let fido = new Dog();
fido.colour = "yellow";
console.log("Fido:", fido);
fido.sound();
The third is also achieved: if we had a cat, we could just tell happy.sound() and it would do a "meow". We don't need to know if something is a dog or a cat, just that they know how to make a sound, and dynamic dispatch will do the rest.
It is also of note that when you invoke a function in an object with a dot notation like this, the function is interpreted as "method" - a function that knows which object it is acting on, by setting a special variable this. In this case, within the method sound, this would have the same value as fido.
Specifically with arrays, they are a kind of object that knows how to contain multiple values indicated by an integer index, how to be indexed, how to tell its length, how to iterate on its elements etc.
However, note that "variable" is something different entirely. One could conceptualise that variable is a data structure with a name and a value; but you can't typically access variable's name. A variable is not a value itself; you can't put a variable into a data structure, just copy its value there. It is more of a language artifact than a data type.
ECMAScript standard defines eight data types, 7 primitive types and Object.
In JavaScript, objects are a collection of properties and property values can be values of any type, for example an object with an attribute of type "number".
let obj = { num: 3 }
and you can test
typeof obj.num
will return "number", but
typeof obj
will return "object" I suppose because inheritance of prototype Object
All objects in JavaScript are descended from Object, all objects inherit methods and properties from Object.prototype.
In your example of an array. In javascript the array variable has a prototype of Array but that's an object that has a prototype of Object.
typeof([])
I think that's why is returning you "object".
Here are some links about data structures:
https://developer.mozilla.org/en-US/docs/Web/JavaScript/Data_structures
https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Object
JavaScript has only one data type for containers and it's called "object".
Arrays are containers and so their data type is "object". Like arrays there are other kinds of specialist object classes such as "function" (they contain code and are callable), sets and weak sets for example.
Significantly the JavaScript typeofoperator does not always return the data type of its operand. This is due to early implementation details of the operator which can not now be changed - and programs have long since adjusted to the actual implementation:
typeof null returns "object". The data type of null is "null".
typeof function returns "function". The data type of a function is "object".
...variable is a container and is not data
Variables are not so much a container as an identifier of where a value is stored. Variables in JavaScript are weakly typed which means the data type of a value is not determined by the variable (or object property) to which a value has been assigned but by the internal memory construct used to hold the value. That is to say, type is obtained from the value stored, not the variable used to access it.
Object values
An object value stored in a JavaScript variable is some kind of memory pointer to a data structure whose location and implementation details are private and only known to the JavaScript engine.
It makes sense to call objects values a data type in JavaScript for the same reason pointers in C have a data type depending on what they point to. It also explains why if you assign the same "object value" to two variables, they will both then point to the same object data set held at some unknown location in memory.
The major difference with JavaScript object values is that you can't perform pointer arithmetic on them and must rely on object property notations object.propertyName or object["propertyName"] to directly access properties of an object.
Array objects
JavaScript arrays are objects which use positive integer values, converted to a string, to access array entries being held as string properties of the array object.
Unlike a typed array, index values to access entries of an Array object do not have an upper bound nor do they need to be consecutive - memory is not allocated to store entries which have not been set.
TLDR;
JavaScript arrays are implemented as associative lookup tables. Their data type is "object" and they inherit properties and methods from Array.prototype and Object.prototype.
They are called "exotic" objects in ECMAScript standards because they monitor access to see if the property name used represents a non-negative integer and maintain the array object's length property if it is.
Early JavaScript documentation went out its way not to mention pointers, presumably to avoid confusing BASIC programmers. Documentation used "object" to mean a data structure, object values were stored as pointers, and the short hand property access operator chosen was . instead of the -> operator for pointer access used in the C language family.
I've noticed ## used in a few pages about new ES6 features, but I don't know what exactly it means (whether it's actually syntax or just some kind of documentation convention). And it's hard to google. Can someone explain it?
## describes what's called a well-known symbol. (Note that it isn't actually valid syntax in JS.) According to the ES6/ES20151 specification:
Well-known symbols are built-in Symbol values that are explicitly referenced by algorithms of this specification. They are typically used as the keys of properties whose values serve as extension points of a specification algorithm. Unless otherwise specified, well-known symbols values are shared by all Code Realms (8.2).
Code Realms refer to different instances of a JavaScript environment. For example, the Code Realm of the root document would be different to that of JavaScript running in an <iframe>.
An example of where it matter what code realm an object comes from is when trying to use instanceof to determine whether an object is an array (hint: it won't work if it's from another frame). To avoid these kinds of issues from popping up with symbols, they are shared so that references to (say) ##toString will work no matter where the object came from.
Some of these are exposed directly through the Symbol constructor, for example, ##toPrimitive is exposed as Symbol.toPrimitive. That can be used to override the value produced when attempting to convert an object to a primitive value, for example:
let a = { [Symbol.toPrimitive]: () => 1 };
console.log(+a); // 1
console.log(a.valueOf()); // (the same object)
console.log(a.toString()); // "[object Object]"
In general, symbols are used to provide unique properties on an object which cannot collide with a random property name, for example:
let a = Symbol();
let foo = { [a]: 1 };
foo[a]; // 1
There is no way to access the value except by getting the symbol from somewhere (though you can get all symbols for an object by calling Object.getOwnPropertySymbols, so they cannot be used to implement private properties or methods).
1: See this es-discuss topic for some discussion about the different names.
I would like to get the binary form of a number, e.g 6 -> "0110"
I've tried (js/toString ...) but no matter what syntax I use, the repl always returns "[object Window]". What does this mean?
I'm also confused because toString is part of goog.math.Integer, and yet when I try to use js/isOdd, part of the same library, it says it is not defined. I tried manually requiring it via (ns user (:require [goog.math.Integer :as int])), but it made no difference.
I'm also confused as to the difference between (.toString ...) and (js/toString ...).
Any help with the specific problem and/or the nuances of js functions in cljs would be most appreciated. Thanks!
You should use (.toString 6 2). Using (js/toString ...) amounts to toString(...) which you can try evaluating yourself in a typical javascript browser console. You'll see you'll also get an "object Window".
(js/thing) is used for referring to a javascript runtime symbol. In particular, if you've loaded code separate from your compiled clojurescript (e.g. loaded through a different script), you can refer to the loaded symbols using the js/... syntax. js/thing, in this case, will refer to thing in the top level scope of javascript.
For example, say you're using the ROT.js library which exposes its API through the ROT object. You can access its functions in clojurescript (assuming the library has been loaded), using js/ROT. Creating an instance of its Display object found in ROT.Display would then be accomplished using (js/ROT.Display. params).
Loaded Closure compatible code, on the other hand, is accessed depending on how they've been required in the namespace. In general, if you've loaded the goog.math library with (ns test (:require [goog.math :as math]), you can access everything under goog.math using (math/something).
The (.function object params) syntax is used for calling methods of a javacript object and would correspond to object.function(params). Remember that javascript objects are different from values and objects you create through pure clojurescript code. Use (.-property object), if you just want to get the value of that object's property instead. You can also lookup doto, .., and the threading macros ->, ->> for more ways to deal with javascript objects inside clojurescript. Most of the interop facilities provided for java in clojure holds for javascript/clojurescript. I also recommend reading http://www.spacjer.com/blog/2014/09/12/clojurescript-javascript-interop/.
As for the isOdd, that is an instance method of an instance of goog.math.Integer. First create an instance of that (e.g. (def e (new math/Integer ...)) and then you can call .isOdd on that instance. Look through the goog.math.Integer documentations to see which static properties and methods are accessible straight from the Integer scope.
This is a parser error, there are three ways to make this work, creating a var with the number and calling .toString on that, writing the number with an extra a dot or writing the number in parentheses.
If you try 6.toString(2) on a JavaScript console you will get this error:
SyntaxError: Unexpected token ILLEGAL
But this 6..toString(2) works. This is because the JavaScript parser expects a number followed by a dot to be a float literal. When you write 6. the parser expects the next character to be a number not t, when you write 6.. the first dot is parsed as part of the number (creating the number 6.0) and the second dot is parsed as a method call on the created number.
In ClojureScript the compiler knows about this "feature" of JavaScript so you can pass the 6 literal to toString:
cljs.user> (.toString 6 2)
"110"
cljs.user> (.toString 6. 2)
"110"
The ClojureScript compiler generates the correct code in both cases. In the first case it generates (6).toString(2) and in the second case it generates 6.0.toString(2).
(js/toString 6) is calling the toString defined on the window global object. No matter what you pass the result is always the same. You can check that calling by window.toString() in a JavaScript console.
(.toString target args) is calling the toString defined in the target object passing args as parameters of the method.
I have an array of objects that I generate from JSON.parse. I access its properties like this:
AnObject['PhoneList'][i]['PhoneLabel']
When I run the code through the google closure compiler, the name of the properties is not obfuscated and clearly visible. Why are the names of object properties not obfuscated?
Google closure has a difficult time figuring out what it can and can't rename. For example, any data structure that is created or referenced by code outside the Google closure compiled code cannot be renamed or the two sides won't be expecting the same code. Further, referencing properties via constructed strings makes it next to impossible for closure to do it's job well. As such, Closure has a whole bunch of rules and settings to help you control this and direct it for what to do. I'd suggest you read up on those rules/settings at these references:
https://developers.google.com/closure/compiler/docs/api-tutorial3
https://developers.google.com/closure/compiler/docs/compilation_levels
https://groups.google.com/group/closure-stylesheets-discuss/browse_thread/thread/386ba6db27a43887?pli=1
https://developers.google.com/closure/compiler/docs/limitations
And, quoted from this last reference:
String representations of function or parameter names:
The Compiler renames functions and function parameters but does not
change any strings in your code that refer to functions or parameters
by name. You should thus avoid representing function or parameter
names as strings in your code. For example, the Prototype library
function argumentNames() uses Function.toString() to retrieve the
names of a function's parameters. But while argumentNames() might
tempt you to use the names of arguments in your code, Simple mode
compilation breaks this kind of reference.
Quoted strings is the syntax used for properties that should not be renamed ("exported").
you probably want to use
AnObject.PhoneList[i].PhoneLabel
instead.
Google Closure Compiler doesn't touch quoted strings.
myObj.prop = 3;
will result in prop being renamed (and myObj too perhaps)
myObj['prop'] = 3;
will result is 'prop' remaining untouched.
I ran this code and got the below result. I curious to know why [] is faster?
console.time('using[]')
for(var i=0; i<200000; i++){var arr = []};
console.timeEnd('using[]')
console.time('using new')
for(var i=0; i<200000; i++){var arr = new Array};
console.timeEnd('using new')
using []: 299ms
using new: 363ms
Thanks to Raynos here is a benchmark of this code and some more possible way to define a variable.
Further expanding on previous answers...
From a general compilers perspective and disregarding VM-specific optimizations:
First, we go through the lexical analysis phase where we tokenize the code.
By way of example, the following tokens may be produced:
[]: ARRAY_INIT
[1]: ARRAY_INIT (NUMBER)
[1, foo]: ARRAY_INIT (NUMBER, IDENTIFIER)
new Array: NEW, IDENTIFIER
new Array(): NEW, IDENTIFIER, CALL
new Array(5): NEW, IDENTIFIER, CALL (NUMBER)
new Array(5,4): NEW, IDENTIFIER, CALL (NUMBER, NUMBER)
new Array(5, foo): NEW, IDENTIFIER, CALL (NUMBER, IDENTIFIER)
Hopefully this should provide you a sufficient visualization so you can understand how much more (or less) processing is required.
Based on the above tokens, we know as a fact ARRAY_INIT will always produce an array. We therefore simply create an array and populate it. As far as ambiguity, the lexical analysis stage has already distinguished ARRAY_INIT from an object property accessor (e.g. obj[foo]) or brackets inside strings/regex literals (e.g. "foo[]bar" or /[]/)
This is miniscule, but we also have more tokens with new Array. Furthermore, it's not entirely clear yet that we simply want to create an array. We see the "new" token, but "new" what? We then see the IDENTIFIER token which signifies we want a new "Array," but JavaScript VM's generally do not distinguish an IDENTIFIER token and tokens for "native global objects." Therefore...
We have to look up the scope chain each time we encounter an IDENTIFIER token. Javascript VMs contain an "Activation object" for each execution context which may contain the "arguments" object, locally defined variables, etc. If we cannot find it in the Activation object, we begin looking up the scope chain until we reach the global scope. If nothing is found, we throw a ReferenceError.
Once we've located the variable declaration, we invoke the constructor. new Array is an implicit function call, and the rule of thumb is that function calls are slower during execution (hence why static C/C++ compilers allow "function inlining" - which JS JIT engines such as SpiderMonkey have to do on-the-fly)
The Array constructor is overloaded. The Array constructor is implemented as native code so it provides some performance enhancements, but it still needs to check for arguments length and act accordingly. Moreover, in the event only one argument is supplied, we need to further check the type of the argument. new Array("foo") produces ["foo"] where as new Array(1) produces [undefined]
So to simplify it all: with array literals, the VM knows we want an array; with new Array, the VM needs to use extra CPU cycles to figure out what new Array actually does.
One possible reason is that new Array requires a name lookup on Array (you can have a variable with that name in scope), whereas [] does not.
Good question.
The first example is called an array literal. It is the prefered way to create arrays among many developers. It could be that the performance difference is caused by checking the arguments of the new Array() call and then creating the object, while the literal creates an array directly.
The relatively small difference in performance supports this point I think. You could do the same test with the Object and object literal {} by the way.
Also, interesting, if the length of the array is known in advance (elements will be added just after creation), the use of an array constructor with a specified length is much faster on recent Google Chrome 70+.
"new Array( %ARR_LENGTH% )" – 100% (faster)!
"[]" – 160-170% (slower)
The test can be found here - https://jsperf.com/small-arr-init-with-known-length-brackets-vs-new-array/2
Note: this result tested on Google Chrome v.70+; in the Firefox v.70 and IE both variants almost equal.
This would make some sense
Objects literals enable us to write code that supports lots of
features yet still make it a relatively straightforward for the
implementers of our code. No need to invoke constructors directly or
maintain the correct order of arguments passed to functions, etc.
http://www.dyn-web.com/tutorials/obj_lit.php