I am new to this very very nice Linq.js library that I have just discovered. I am following the examples to write queries like:
Enumerable.from(jsonArray).select(...); // noice
Can I do this shortcut?
jsonArray.select(...); // error as expected
I read the tests in library, seems like pretty much every call starts with Enumerable.someCommand();. I am wondering if the linq commands have been applied to the correct prototypes in js, so I can call them in the style of 2nd line of code. am I not aware of it because I am a newbie?
I am the creator of the open source project http://www.jinqJs.com.
You could simply do jinqJs().from(jsonArray).select();
Let me know if I could be of any more help
If your concern is that Linq.js doesn't extend the Array prototype, I think it's misplaced. It's not exactly a light framework, kinda the same reason why jquery doesn't do the same thing. You shouldn't expect anything to work on just anything.
If you wanted to make bridging that gap a little nicer, it should be safe to add some methods to convert to the other.
if (!Array.prototype.AsEnumerable) { // not likely to be used by others
Array.prototype.AsEnumerable = () => Enumerable.From(this);
}
Then that would allow you to do:
jsonArray.AsEnumerable().Select(...);
Related
My client builds their own app based on Chromium, their navigator.appVersion is AppleWebkit/534+
But to my surprise they replace javascript standard built-in objects with their own, for example, check their Map bellow,
Their Map has methods like,
arr:Array[0]
isEmpty:function
remove:function
But no standard Map method like has, keys, values, check here https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Map (BTW, the reason we need Map here instead of plain js object is we need the key to be something other than string)
I am curious, how did they do that? Why would someone want to do that!!
And more importantly how do I restore the build in version ?
I had the same issue that the global function has been overwritten.
My trick is to use the contentWindow of an iframe to get the original function back:
Here's the code, it doesn't work in code-snippets of StackOverflow due to iframe policy, but it should work with your environment:
// contaminated Map
Map = function() {
this.foo = 'bar';
}
const map1 = new Map();
console.log(map1);
// restoring Map
const iframe = document.createElement('iframe');
document.body.append(iframe);
const OriginalMap = iframe.contentWindow.Map;
iframe.remove();
const map2 = new OriginalMap();
map2.set('foo', 'bar');
console.log(map2);
Here's the screenshot shows that it works:
This is more like a workaround, not sure if there's a better way to do it.
how did they do that?
It's as simple as:
Map = function() { ... }
Why would someone want to do that!!
As other comments have guessed, probably because the code is older than the availability of built-in Map. If the same code is also supposed to run on older browsers, then this consideration might still be relevant.
how do I restore the build in version ?
The suggestion in the other answer is an interesting idea... I can't think of a better way.
That said: I'm guessing your task is to make extensions/modifications to an existing codebase. Having two different Maps in the same codebase sounds pretty confusing -- for anyone working on this code after you (which may be yourself, in a couple of months), it'll be pretty hard to understand what's going on. So I offer another suggestion: don't just locally get the built-in Map, and instead pick either of:
modernize the whole system to use built-in JavaScript Maps. Replace all uses of the handcrafted Map, and then delete that definition. Use built-in Map everywhere. (Check with your client though whether they are okay with you spending your time on this.)
stick with what's there, and use the handcrafted Map in your new code as well. While its functions have different names, it seems that all the important features are there. You can probably find an example of how to iterate over such a map. (This would still leave the above alternative as a future option.)
Right now I'm writing a small jQuery plugin for fun and profit, so since I'm not too familiar with this library, there's a few questions made me confused at this point.
Let's say we have a pretty simple plugin:
(function($) {
onButtonPress() {
console.log('Button pressed!');
}
render(container, settings) {
$(container).addClass(settings.boxClass);
$('<button></button>').appendTo(container).addClass(settings.addImageButton).on('click', onButtonPress);
}
$.fn.myAwesomeForm = function(options){
var settings = $.extend({
'boxClass': 'box-header with-border',
'addImageButton': 'btn btn-primary btn-sm',
}, options);
render(this, settings);
}
}(jQuery));
1) Let's imagine our render() method is implemented using 25 different functions and they are 400 total lines of code long. Some of these functions are responsible for drawing the UI, some of them doing ajax queries, some of them is just some helpful snippets I made to reduce the amounts (and the ugly-ness) of the code.
How I could split this code into separate files? As far as I understand, I need to write code in different files, then use a tool like grunt/gulp to create a task or watcher to merge them all into a single *.js file (and probably provide a minified version as well), but right now I'm a bit confused about how I should do that. Is there any kind of 'best practice' thing, or any common approach to such thing to make sure that my code will be less confusing for the other possible maintainers?
2) Let's say that default settings is an array of 70 [probably nested] elements, and I want to access one of them in onButtonPress function. Oh, also different one I want to access in someOther function, and there's a few I need for deleteForm() function, so generally it would be better for my code if settings array will be something I could access from pretty much every place of the code, and most important thing, I could have 5-6 instances of my form on the page, so I cannot use a local-scope variable in plugin file for that.
I read about the approach of saving settings in the data fields, but it feels a bit weird for me to be frank. Is there's any better way I could implement it?
3) Let's say that my plugin is growing, and now I want to add a few more pre-defined settings for Bootstrap and Sematic UI frameworks adding to AdminLTE I use now.
Of course, generally I want my $('#form').myAwesomeForm({}) call to not be 70-lines long, so generally I'm looking for a way to somehow move the default settings in another file, to say "myplugin-defaults-lte.js", so then I could do something like this:
<script type='text/javascript' src="myplugin-defaults-bootstrap.min.js">
<script type='text/javascript' src="myplugin.min.js">
<script type='text/javascript'>
// Here's my form. Already bootstrap-customized.
$('#form').myAwesomeForm();
</script>
I'm not sure if it's the best pattern, but perhaps you got the idea. So generally, can anyone please provide a simple code snippet, or something like this, because at this point things starting to be confusing as hell to me, so I'm really not sure how to approach it correct way?
My team has had the occasional problem of developers pushing Karma/Protractor tests containing the .only() function call, which of course makes our Jenkins etc only run that particular test, potentially allowing bugs to slip by. As such I thought I'd try and figure out a way to stop this from happening without being discovered.
First, I thought I'd look into simply using JSHint to point out the function call, but I can't seem to find a way to do that. I also looked at ESLint for its custom plugins, but I can't figure out how to write a plugin for this particular case.
Could you guys give me some ideas on how to solve this issue? Alternative solutions are also appreciated, of course!
Here's a (probably not working example) of how to create a plugin that flags an error if the parser ever sees a only() call. Again, mileage may vary, but it should be enough to get you started. This does not work if it sees a.only(), we'll leave that up to you.
module.exports.rules = {
"no-only-call": context => ({
CallExpression: (node) => {
if(node.callee.name == "only"){
context.report(node, 'Calls to only() are disallowed');
}
}
})
};
https://www.kenneth-truyers.net/2016/05/27/writing-custom-eslint-rules/ - Simple example of creating a custom rule
http://esprima.org/demo/parse.html - Use this online parser to help you understand the parse tree.
https://www.npmjs.com/package/generator-eslint - Use this generator to start your plugin project
Calling the javascript gurus out there.
Basically my question is regarding how you structure your code, both visually and for functionality for example do you wrap everything in objects using this structure:
var myapp={
binds:function(){
//put some event listeners for jquery etc...
},
otherfunc:function(){
//do some other thing
},
init:function(){
//call myapp.binds and other functions and other stuff to intialize your app.
}
};
Then finally
$(document).ready(myapp.init);
The thing is with a structure like this I think JSLint complains doesn't it? Whats the pros and cons using a structure like this or is there a generally better way to structure your code? Do you follow a certain pattern from $(document).ready(call) to putting all your event listeners and "initializing" your app, do you use separate objects for methods and variables?
I also think "visually" if you have a very large webapp this structure eventually looks very messy, but maybe it's just me I don't know, any input is appreciated thanks.
Using Inheritance Patterns to Organize Large jQuery Applications
explain in detail and with better practice by Alex
http://alexsexton.com/?p=51
its very very well explain, must see
other links
How To Manage Large jQuery Apps 5 months ago
It doesn't matter much how you structure your code as long as you follow the essentials rules of programming that your teacher thought you:
Don't write repetitive code
A function must do 1 and only 1 thing
Document your code
Some other small things but mostly the above... oh and apply lots of common sense
The only error you get from that is "implied global." You can get rid of the warning for document by using this.document instead (since window is the context). The implied global for $ will stay unless you paste in the jQuery source (then gl with all the errors in that).
I trust JSLint--a lot. On big projects I tend to make object literals as you did above but I use a module pattern for object security:
var myapp = (function () {
var secret_stuff, public_stuff;
return {
stuff: public_stuff
}
}());
I can proxy a single function in javascript by doing something like this (just jotted down from memory so bear with me)
function addAroundAdvice(target){
var targetFunction = target.aFunction;
target.aFunction = new function(){
invokePreCall();
targetFunction.apply(target, arguments);
invokePostCall();
}
}
Being a java programmer I'd think of this as a dynamic proxy. Every time I write code like this I think that someone must have made a really smart library that does the common proxying operations that is at least 10% better than what I can do in a hurry. I'd be expecting some stuff like correctly intercepting all methods for any given object, which may not be entirely trivial. Then there's different types of advice. So while I'm not expecting something the size of scriptaculous, it's certainly more than 6 lines of code.
So where are these libraries ?
Try jQuery AOP plugin
Looking at the source it seems that only uses jQuery as a namespace, so you could try this plugin even if don't want to use jQuery.
The Dojo Toolkit has a lot of support for AOP constructs like this:
Eugene Lazutkin's Blog Post on Aspect Oriented Programming with Dojo
The fact that you have been able to do it I would think means that there is a library to achieve it in the form of pure JavaScript i.e. your above example. Design Patterns can be applied to JavaScript as you know, so I think the advice I would provide to you is the following by a Google and Yahoo GUI developer :
http://jsdesignpatterns.com/
Chapter 14: The Proxy Pattern. Reference there solution to yours. You may still prefer your approach or you may find tips from their approach.
Cheers,
Andrew
I don't think you can intercept all functions.
The best you can do is iterate over all elements of an object and look for any functions:
for elem in someObject {
if typeof(elem) == "function" {
// replace the function
}
}
Trouble is, that if you add a function later it's not routed through the proxy.