I was learning some performance related JQuery tips here
Can you tell the meaning of App.hiddenDivs ?
Here App is a javascript object. You can create a javascript object like:
var App = new Object();
and set the App Object member like:
App.hiddenDivs = $('div.hidden');
Then you can access the object in you application like:
App.hiddenDivs.find('span');
It's like Caching jQuery Objects but at the Application level.
App will be an object, and hiddenDivs will be a property on it;
By setting $('div.hidden') to it, it allows you to re-use the result (the jQuery object containing all div.hidden elements), rather than querying the DOM for it each time. This will result in a micro-speed-improvement.
In general, App.hiddenDivs has absolutely nothing to do with jQuery. In this code, it just happens to be the place where a jQuery collection gets stored.
App is a JavaScript object of some sort (we don't know what it really is given the context, and it doesn't matter--it's just some imaginary object which is part of some imaginary code in which this example could live). It could have been something as simple as:
var App = {};
hiddenDivs is a property of that object which is defined to hold the return value of the jQuery code, $('div.hidden').
That return value is a jQuery collection containing all DIVs in the DOM with the class of hidden. Further operations on such DIVs can then be run against that property, rather than re-seeking them in the DOM.
The page you link to, while probably holding some valuable advice, is poorly written. The author should provide a bit more background info on what he's writing about, and should have explained the expected level of knowledge his readers should have. Furthermore, he should offer code examples which build on each other as the explanations progress in order to provide some continuity for the more basic readers to follow.
Related
I've read a number of questions that state it is unwise to add properties to DOM element objects; and they seem to make a great deal of sense. The best suggestion I came across to accomplish the same end was to use a Weak Map with the DOM node reference as the key.
That led me to wonder about adding properties to function objects. Is that "safe" to do or should another object or map be used for this also. I'm referring to functions on the window object. Can the property names I add clash with names in the function object in the future?
That brings up a related matter I've been trying to understand which is that some claim that the window object is so cluttered up that it ought not to be added to and scripts should be modules now. Modules appears to be more isolated than my limited experience with simple namespaces. Is there anything to be gained through using scripts of type module over just declaring another object and making your functions methods of that object? That object would still be added to the window object.
Thank you.
That led me to wonder about adding properties to function objects. Is that "safe" to do or should another object or map be used for this also. I'm referring to functions on the window object. Can the property names I add clash with names in the function object in the future?
It's not safe in that, if you do it, others could do it too. For example:
// Your code
RegExp.description = 'some description for the constructor!';
setTimeout(() => {
console.log(RegExp.description);
});
// Someone else's code
RegExp.description = "someone else's description";
The only consolation is that it's pretty unlikely for such a thing to happen.
Similarly, it's pretty unlikely for some random English word that one library creates for itself on the window collides with another word that another library creates for itself on the window - but it's not impossible. For that reason
That object would still be added to the window object.
can be seen as slightly less than optimal on huge pages, where collisions are a real possibility.
Is there anything to be gained through using scripts of type module over just declaring another object and making your functions methods of that object?
Yes, see above. If all of your code is in module scripts, there should be no need to put any object onto the window, in most cases. In addition to the above, module scripts often make projects easier to manage because they make all dependencies explicit through the use of import statements. They're also very easily integrated into a build process like Webpack - and build processes allow for all sorts of neat things that aren't easily done otherwise.
semi-novice programmer here (on and off with C++ for years, dabbling with C# mostly with Unity) and when creating objects and methods within objects it's to be expected that that method is a member of that object.
If I create a new object I can access the function with dot notation object.method.
For Javascript it appears that isn't the case?
I read somewhere about it being something like a first class object (not sure what that means) and I have to explicitly say that the method is a part of the object.
So for example in JS
function testObject() {
let x = whatever;
function testMethod() {
}
}
Is a failure, it will not work. testObject has no idea testMethod is a member.
I have to use
this.testMethod = function() {}
before it can be registered.
I just want to be sure cause I can't really find much info even from youtube videos and websites.
I want to fully grasp knowledge of why for once instead of just shrugging my shoulders and just letting it be.
If what I've stated is true can someone give me a heads up why JS is different in this regard? And if there are any other pitfalls with JS objects that I might not notice from a C programmer background.
Thanks.
Edit:
Thanks for the comments. This is also why programming can be such a pain. you look for info, want to delve into it and get such conflicting information. If you google does javascript have classes, first thing you'll see is javascript doesn't have classes (well this is obviously a lie delving deeper). Why say that when it is provably false? Don't care if it's not class based. Don't say there are no classes (Not you specifically just shouting out to the internet).
I know how to declare an object literal and was looking at the youtube video
https://www.youtube.com/watch?v=PFmuCDHHpwk&list=PLTjRvDozrdlxEIuOBZkMAK5uiqp8rHUax&index=2
to brush up on the basics, get my head back in the game and learn a new language. Doubled down on researching just what it all means and it's sticking for once (but I digress). He discusses about Object literals then changes his code into something similar that I presented thag he called a function object.
Is that not a thing?
Am I doing it wrong?
Apparently what I have is not an object?
Though the definition of an object is a group of data in a single unit which includes member variables and methods that work on that data.
Should I forget what I'm seeing and just stick with object literals?
I'm trying to access the properties of an object in an app called Papers3 using JXA. I'm new to JXA and this is proving challenging, especially because of the lack of documentation.
Here is a shot of the dictionary for the object I'm trying to look at
I'm trying to get the IDs for the currently displayed windows in the app.
My attempt at this is:
var Papers = Application('Papers');
Papers.includeStandardAdditions = true
Papers.libraryWindow.displayedPublications()
Running it throws an error and the output is:
Error on line 4: TypeError: Papers.libraryWindow.displayedPublications is not a function. (In 'Papers.libraryWindow.displayedPublications()', 'Papers.libraryWindow.displayedPublications' is undefined)
Error -2700: Script error.
Also, if I call just Papers.libraryWindow
The result is:
[function anonymous] {
"name":"",
"prototype":{"constructor":[function anonymous]}
}
I'm not sure what to do.
Well, JXA is broken obfuscated moribund junk and AS not much better off either, but the key thing to understand here is that Apple event IPC is not OOP, it is RPC + simple first-class relational queries. Despite the syntactic sugar, its closest relative is actually SQL database programming, not browser DOM manipulation, so once you get your head around that it’ll [hopefully] start to make a bit more sense.
An “AppleScriptable” application presents its data as a heavily abstracted relational graph—an “Apple Event Object Model”—where each node is related to other nodes by one-to-one and/or one-to-many relationships. There’s no such thing as “classes” or “objects” in the OO sense; it’s just the jargon that got attached for documentation purposes. Thus what an application’s dictionary calls a “property” is either a simple attribute containing a primitive value (number, string, list, etc; e.g. the name property of a Finder file) or a one-to-one relationship (e.g. the current track property of iTunes’ application), and what it calls “elements” is a one-to-many relationship (in your case, the libraryWindows elements of Papers’ application object).
For example, Papers.libraryWindows.displayedPublications.get() should return a list of the displayed publications of every library window in Papers (though whether that actually works in practice depends on how well implemented an app’s AEOM is, not to mention JXA’s own implementation issues); or you can use various reference forms (by-index, by-name, etc; though several are broken/unsupported in JXA) to narrow your query to, say, just the first library window, e.g. Papers.libraryWindows[0].displayedPublications.get().
You might get some insight from browsing the NodeAutomation documentation, which includes a rough overview of AEOM and how to assemble queries which you then send to it via commands (remote procedure calls) to resolve and process as it sees fit. JXA syntax isn’t as pretty, and various operations that work perfectly in AS barf in JXA, but it’ll give you a rough idea.
That said, I strongly recommend sticking to AppleScript. The language is a mess, but at least it has some documentation and user community to help you find your way around it (even if they don’t deeply understand it either).
It's a little detail, I think. libraryWindow needs to be plural and it's necessary to specify which one. You can use several forms:
Index form eg. libraryWindows[0]
ByName eg. libraryWindows.byName('Papers')
So, to access the first library window, you use: libraryWindows[0].
Try this:
(() => {
'use strict'
const app = Application('Papers');
const oWin = app.libraryWindows[0]
return oWin.displayedPublications()
})();
For Papers 3 specific JXA examples, see:
mac-scripting - Automation scripts for macOS
For more general info, see:
JXA Resources
We are building a form-based app that has a complex object with many levels of nested properties.
So far, I have created a simple experiment with a single view model with one object. The experiment has fields that are bound to object properties, which successfully display the data. However, when changing the fields, the object does not seem to be updated.
What should I do to make sure form input propagates throughout the view model and into the template?
You need to use getter method in app.js as below,
get swaggerString() {
console.log(this.swagger);
const swaggerStringified = JSON.stringify(this.swagger);
return swaggerStringified;
}
In your HTML, change method to property,
${swaggerString}
Updated your GIST,
https://gist.github.com/anonymous/3b85820d66c2dfbf0f770208a7c8b63f
Hope this helps!
What are you planning to do in the real app?
The accepted answer only answers how to solve your problem as posted in the gist. I'm guessing your real app doesn't need to display JSON data.
If you are just wanting to display deeply nested object properties, then that is simple, you simply bind to those properties themselves. See here: https://gist.run/?id=5af5c22be4b49c0e3fef327e3d8b986b
<pre>
{
"name": "${swagger.name}",
"version": "${swagger.version}"
}
</pre>
You can even go arbitrarily deep in to an object tree, e.g. ${foo.bar.baz.ball.foop}.
The thing to understand is that Aurelia observes for changes to whatever you tell it to observe. When you tell it to simply observe an property that is an object, it can only watch for changes to the property itself. This means it will only see a change if you assign a different object to the property. It does not watch every property on the object for changes for performance reasons (and also due to Object.observe being cancelled).
All hope is not lost, though. Please respond with some specifics and I'll try to help you out better.
The Garmin Communicator API operates through a browser plugin that is exposed to JS from an <object> tag embedded in the HTML body.
I'm trying to find any undocumented methods/properties of this object as I build the GWT-Garmin-API. Working with their JS API source I can see the official methods, but I want to find any other methods/props. So far I cannot find a way to list these from a reference to the Object element in the page.
No debugger I use shows any such props. I was hoping there might be some Object reflection kungfu I don't know about. Thanks.
Update:
Example can be found at the Garmin Hello Device example.
From the console, iterate across the object you'll find from the following:
var plugin = document.getElementsByTagName('object')[0];
for(var prop in plugin) {
console.log( prop );
}
However this will not find plugin methods like plugin.Unlock(), which you can easily call from the same console line.
No debugger I use shows any such props
Then there is no such thing, assuming those host objects are not implemented as Proxies.
Your approach of enumerating properties with a for-in-loop (and even heavier weapons such as Object.getOwnPropertyNames and Object.getPrototypeOf) is flawed, as anything visible like that would be shown in your debugger.
If you really want to find "hidden" properties (I'm very sure there are none), you would need to brute-force test all possible property names. Or have a look into their source, which might be hidden from you if it's a host object.
In general, if you have a reference to object in javascript, you can loop over the properties and methods of that object using:
for(var property in object) {
var value = object[property];
console.log(property + ' = ' + value);
}
Given the source code you linked, you could also try iterating over the prototypes of some of the Garmin classes, like:
for(var property in Garmin.DevicePlugin.prototype) {
//...
}
If it doesn't show up when you iterate in one of these ways, it means that the property is not exposed to javascript. "Callable" methods that that don't show up (like plugin.unlock()) are defined within the plugin itself. (When you call a method like this, you can think of it like passing a message from javascript directly into the implementation of the plugin.) The only way I know to find a "list" of these methods is to have access to the source code of the plugin that you are using. There is no way for javascript to ask for this list, unless the plugin has specifically implemented something to enable that kind of functionality.