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.
Related
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.
For example I loaded a script on some website, and I would like to know if JSON.parse/stringify wasn't monkey patched.
I noticed that if I use toString on the function in Chrome/FF, JSON.stringify.toString, then I get back:
function stringify() {
[native code]
}
My question is do you think this is a good way to verify if a function was monkey patched? Also would love to hear of any other approaches to this problem.
One could easily fake JSON.stringify.toString
JSON.stringify = function() {}
JSON.stringify.toString = function() {return 'ha-ha'}
console.log(JSON.stringify); //ha-ha
A little more robust way would be to use Function.prototype.toString
Function.prototype.toString.call(JSON.stringify)
But really bad monkeypatcher could patch Function.prototype.toString as well :)
Yes, this is the only practical way to check whether or not a native function had been overridden or not.
const isNative = fn => !!fn.toString().match(/\[native code\]/)
console.log(isNative(JSON.stringify));
A more robust solution could use Function.prototype.toString() instead of direct call of fn.toString(), but both are monkeypatchable as well. The joys of JavaScript :)
The spec ( http://www.ecma-international.org/ecma-262/7.0/index.html#sec-function.prototype.tostring ) does not specify the exact string returned for a builtin function :
19.2.3.5 Function.prototype.toString
When the toString method is called on an object func, the following
steps are taken:
If func is a Bound Function exotic object, then Return an
implementation-dependent String source code representation of func.
The representation must conform to the rules below. It is
implementation dependent whether the representation includes bound
function information or information about the target function. If
Type(func) is Object and is either a built-in function object or has
an [[ECMAScriptCode]] internal slot, then Return an
implementation-dependent String source code representation of func.
The representation must conform to the rules below. Throw a TypeError
exception. toString Representation Requirements:
The string representation must have the syntax of a
FunctionDeclaration, FunctionExpression, GeneratorDeclaration,
GeneratorExpression, ClassDeclaration, ClassExpression, ArrowFunction,
MethodDefinition, or GeneratorMethod depending upon the actual
characteristics of the object. The use and placement of white space,
line terminators, and semicolons within the representation String is
implementation-dependent. If the object was defined using ECMAScript
code and the returned string representation is not in the form of a
MethodDefinition or GeneratorMethod then the representation must be
such that if the string is evaluated, using eval in a lexical context
that is equivalent to the lexical context used to create the original
object, it will result in a new functionally equivalent object. In
that case the returned source code must not mention freely any
variables that were not mentioned freely by the original function's
source code, even if these “extra” names were originally in scope. If
the implementation cannot produce a source code string that meets
these criteria then it must return a string for which eval will throw
a SyntaxError exception.
So checking for [Native Code] may or may not work depending on the interpreter. Furthermore, an implementation could well implement builtin functions as normal javascript code.
So in answer to your question, you cannot determine, is a Javascript specified way whether a builtin function has been monkey-patched.
That said it appears that Chrome and Firefox both return the [Native Code] string subject to verification on other implementations that may be a pragmatic solution.
I just wanted to add that, after ES6, all solutions that involve checking "[native code]" are even less reliable because of ES6 proxy traps.
// Example monkey-patching the Fetch API using an ES6 proxy trap
window.fetch = new Proxy(window.fetch, {
apply(fetch, that, args) {
const result = fetch.apply(that, args);
result.then((response) => {
console.log("Intercepted!", args, response);
});
return result;
}
});
// True
console.log(window.fetch.toString().includes("[native code]"));
// True
console.log(Function.prototype.toString.call(window.fetch).includes("[native code]"));
For more info, check this answer.
I tried to develop some of the ideas from other replies into a working script - here it is:
https://gist.github.com/mindplay-dk/767a5313b0052d6daf2b135fdecd775f
Paste it into the Chrome (or Edge) console and press ENTER - it'll print out a list of any constructors and class-methods not matching their native counterparts. (It does this by comparing against the native APIs in an iframe - which it creates via document.createElement, so, technically, it's possible to fool it by overriding that method, if you were intending to do so deliberately; this isn't a security tool.)
Note that this currently gives false positives for window.location, window.fetch and window.length - this appears to be because these properties aren't correctly reflected by their native browser implementations? If you know how to fix it, please post a comment.
Here is example output from a site that was incorrectly loading some IE11 polyfills into Chrome:
I tried googling but couldn't find a precise answer, so allow me to try and ask here. If the question does not seem proper, please let me know and I'll delete it.
In JS you've got three different way of writing certain build in functionalities:
str.length
str.toString()
parseInt(str)
I wonder if there is a reason behind these different ways of writing. As a new user I don't grasp why it couldn't be streamlined as: length(str) / toString(str) / parseInt(str) or with dot formulation.
I however think if I do know the reason behind these differences, it would give me a better understanding of JavaScript.
Length is one of the attributes of string in JavaScript. Hence you use string.length to get the length of the string.
toString is a function for string objects, hence we use stringobj.toString().
parsInt(str) is a global function which takes string as a parameter.
JavaScript is object-oriented, so there are functions or procedures which require first an object to use as this in their bodies. str.length is a property, both syntactically and semantically. It doesn't require any parameters and represents some quality of the object. obj.toString() is a method (a function attached to an object), which doesn't represent any characteristics of the object, but rather operates on its state, computes some new values, or changes the state of the object a lot. parseInt(str) is a "global" function, which represents an operation not attached to any type or object.
Under the hood, these three ways may be well implemented with just calling a function, passing this as the first parameter (like C# does, for example). The semantic difference is the important one.
So why not use just the third syntax, like for example PHP does? First, it doesn't bloat the global environment with lots of functions which only work for one specific case and type, allowing you to specify any new function you want without breaking the old functionality. Second, it ecourages you to use object-oriented concepts, because you can already see working objects and methods in the language, and can try to make something similar.
And why isn't parseInt a method? It can as well be str.toInt() without any issues, it's just the way JavaScript designers wanted it to be, although it seems also a bit logical to me to make it a static method Number.parseInt(str), because the behaviour of the function is relevant more to the Number type than the String type.
JavaScript is based around objects. Objects have properties (e.g. a User object may have name and age properties). These are what define the user and are related to the user. Properties are accessed via dot-notation or brackets notation (to access Eliott’s age, we’ll use either eliott.age or eliott['age'] — these are equivalent).
These properties can be of any type — String, Number, Object, you name it — even functions. Now the proper syntax to call a function in JS is to put round brackets: eliott.sayHello(). This snippet actually fetches Eliott’s sayHello property, and calls it right away.
You can see Eliott as a box of properties, some of which can be functions. They only exist within the box and have no meaning out of the box: what would age be? Whose age? Who’s saying hello?
Now some functions are defined at the global level: parseInt or isNaN for instance. These functions actually belong to the global box, named window (because legacy). You can also call them like that: window.parseInt(a, 10) or window.isNaN(a). Omitting window is allowed for brevity.
var eliott = {
name: 'Eliott',
age: 32,
sayHello: function () { console.log('Hello, I’m Eliott'); }
};
eliott.name; // access the `name` property
eliott.age; // access the `age` property
eliott.sayHello; // access the `sayHello` property
eliott.sayHello(); // access the `sayHello` property and calls the function
sayHello(eliott); // Reference error: `window.sayHello` is undefined!
Note: Some types (String, Number, Boolean, etc.) are not real objects but do have properties. That’s how you can fetch the length of a string ("hello".length) and reword stuff ("hello, Eliott".replace("Eliott", "Henry")).
Behaviour of these expressions is defined in ECMAScript grammar. You could read the specification to understand it thoroughly: ECMAScript2015 specification. However, as pointed out by Bergi, it's probably not the best resource for beginners because it doesn't explain anything, it just states how things are. Moreover I think it might be too difficult for you to be able to grasp concepts described in this specification because of the very formal language used.
Therefore I recommend to start with something way simpler, such as a very basic introduction to JavaScript: JavaScript Basics on MDN. MDN is a great resource.
But to answer your question just briefly:
str.length is accessing a property of the str object.
parseInt(str) is a function call
str.toString() is a call of a function which is a property of the str object. Such functions are usually named methods.
Functions and methods are in fact very similar but one of the differences (except for the obvious syntax difference) is that methods by default have context (this) set to refer to the object which they're part of. In this case inside of toString function this equals to str.
Note: Accessing a property (as in str.length) could in effect call a getter function but it depends on how the object is defined, and is in fact transparent for the user.
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 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.