I am looking here:
https://github.com/gf3/Levenshtein/blob/master/lib/levenshtein.js
I see that the code begins like this:
(function(root, factory){
if (typeof define == 'function' && typeof define.amd == 'object' && define.amd) {
define(function(){
return factory(root);
});
} else if (typeof module == 'object' && module && module.exports) {
module.exports = factory(root);
} else {
root.Levenshtein = factory(root);
}
}(this, function(root){
I've never seen this before. What does it mean? What does "root" mean?
If I add this to the package.json file of my NodeJS app, then how do I use this inner function:
// Levenshtein distance
function Levenshtein( str_m, str_n )
All the examples use this inner function, but I don't know how to reach it.
TL;DR
What does "root" mean?
root is the first argument passed to this IIFE, which (as you see on line 11) is this. At the "top level" of a JavaScript file in Node.js, this points to the global namespace object. In the browser it points to window.
All the examples use this inner function, but I don't know how to reach it.
That's not a question, but this is how you use it in Node.js:
const Levenshtein = require('levenshtein');
const lev = new Levenshtein('bar', 'baz');
console.log(lev.distance); // => 1
What does it mean?
The purpose of all of this is to make this code work whether you use require in Node.js, an AMD module loader, or a <script> tag in the browser.
If you break it down, the code isn't too hard to understand. Let's start with the anonymous function on line 11, which is a "factory" function that just returns the Levenshtein constructor, like so:
function factory(root) {
// ...
function Levenshtein( str_m, str_n ) {
// ...
}
// ...
return Levenshtein
}
(In the case of the Levenshtein module, the root argument is never actually used in the "factory" function. Go figure.)
Now let's back up to the first line. Here an anonymous function is declared, which basically works like this:
function iife(root, factory) {
const Levenshtein = factory(root);
if (anAMDLoaderIsLoadingMe()) {
// AMD loaders supply a `define` function
define(function() { return Levenshtein; });
} else if (nodeJsIsLoadingMe()) {
// Node.js supplies the `module.exports` object
module.exports = Levenshtein;
} else {
// In a browser, so `root` is `window`
root.Levenshtein = Levenshtein;
}
}
Finally, these two functions are used like this:
iife(this, factory);
That's it! The reason these functions are used anonymously instead of giving them sensible names like iife and factory is so that they don't clash with other functions that you might define (or that other, less well-behaved modules define). This isn't a possibility in Node.js, but it is in the browser.
Related
I have a JavaScript file which is loaded by require.
// loaded by require()
var a = this; // "this" is an empty object
this.anObject = {name:"An object"};
var aFunction = function() {
var innerThis = this; // "this" is node global object
};
aFunction();
(function(anyParameter){
console.log(anyParameter.anObject);
})(
this // "this" is same having anObject. Not "global"
);
My question is: this in var a = this; is an empty object whereas this statements in functions are shadows of node.js global object. I know this keyword is different in functions but I could not understand why first this is not equal to global and this in functions equals to global.
How does node.js inject global to this in function scopes, and why it does not inject it to the module scope?
Here's a few fundamental facts you must understand to clarify the situation:
In the top-level code in a Node module, this is equivalent to module.exports. That's the empty object you see.
When you use this inside of a function, the value of this is determined anew before each and every execution of the function, and its value is determined by how the function is executed. This means that two invocations of the exact same function object could have different this values if the invocation mechanisms are different (e.g. aFunction() vs. aFunction.call(newThis) vs. emitter.addEventListener("someEvent", aFunction);, etc.) In your case, aFunction() in non-strict mode runs the function with this set to the global object.
When JavaScript files are required as Node modules, the Node engine runs the module code inside of a wrapper function. That module-wrapping function is invoked with a this set to module.exports. (Recall, above, a function may be run with an abitrary this value.)
Thus, you get different this values because each this resides inside a different function: the first is inside of the Node-created module-wrapper function and the second is inside of aFunction.
To understand this, you need to understand that Node.js actually wraps your module code in to a function, like this
(function (exports, require, module, __filename, __dirname) {
var test = function(){
console.log('From test: ' + this);
};
console.log(this);
test();
});
Detailed explanation can be found in this answer.
Now, this wrapped function is actually invoked like this
var args = [self.exports, require, self, filename, dirname];
return compiledWrapper.apply(self.exports, args);
So, this, at the module level, is actually the exports object.
You can confirm that like this
console.log(this, this === module.exports);
// {} true
Summary:
In Javascript the value of this is determined when a function is called. Not when a function is created. In nodeJS in the outermost scope of a module the value of this is the current module.exports object. When a function is called as a property of an object the value of this changes to the object it was called. You can remember this simply by the left-of-the-dot rule:
When a function is called you can determine the value of this by looking at the place of the function invocation. The object left of the dot is the value of this. If there is no object left of the dot the value of this is the module.exports object (window in browsers).
caveats:
This rule does not apply for es2015 arrow function which don't have their own binding of this.
The functions call, apply, and bind can bend the rules regarding the this value.
Example (NodeJS):
console.log(this); // {} , this === module.exports which is an empty object for now
module.exports.foo = 5;
console.log(this); // { foo:5 }
let obj = {
func1: function () { console.log(this); },
func2: () => { console.log(this); }
}
obj.func1(); // obj is left of the dot, so this is obj
obj.func2(); // arrow function don't have their own this
// binding, so this is module.exports, which is{ foo:5 }
Output:
It's because the default global object in a Node.js module is the exports object, and you are calling test() which doesn't specify this. In traditional JS, this points to the global object, with use strict, this will be null.
this can point to anything, it just depends on how you call it.
test(): Uses the global object (exports) as this, unless in strict mode, where this will be null;
test.call({}) or test.apply({}): You are specifying what to use as this (the first parameter)
var obj = {testRef: test}; obj.testRef(): this is set to the left of the ., that is, obj
Countering thefourtheye's answer
It is true that this in the top level of the module is exports, but that doesn't necessarily mean that this inside test() will also point to same thing as where it was called from.
Attempting to prove that this and the global object both point to exports
myGLobal = 5;
this.myGlobal; // 5
I'm new to nodejs and trying to learn the basics by rebuilding an existing i2c sensor system.
Got it all running using a named functions and async.series inside a single file. To keep make reusable i now want to create a class which i then can import. unfortunatly i get some errors i don't understand.
class.js
const async = require('async');
const i2c = require('i2c-bus');
class Sensor {
constructor (channel) {
this.channel = channel;
var self = this;
}
openBus (callback) {
bus = i2c.open(self.channel, (err) => {callback()}); // shorted for stackoverflow
}
closeBus (callback) {
bus.close( (err) => {callback()}); //also shorted for better readability
}
connection (callback) {
/* first variation */
async.series([openBus, closeBus], callback);
connection2 (callback) {
/* second variation */
async.series([this.openBus, this.closeBus], callback);
}
}
module.exports = K30;
when i import the class, i can without any problem create a new sensor 'object' and call the functions directly using:
> var Sensor = require('./class.js');
> var mySensor = new Sensor(1);
> mySensor.openBus(foo);
> mySensor.closeBus(bar);
but if i go an try call the wrapper-functions, i get the following errors:
> mySensor.connection(foo);
ReferenceError: openBus is not defined (at 'connection')
> mySensor.connection2(foo);
ReferenceError: self is not defined (at 'openBus')
i believe those errors occure due to my lack of understanding the correct usage of this and self. sadly i can't find any good ead on that topic. any help is highly appreciated.
UPDATE
the solution provided in the first two anwsers was in fact my first approch before starting to use "self" (after some googling [this-that-trick]).
anyways, here is the output/error i get using "this.channel" instead:
> mySensor.connection2(foo);
TypeError: Cannot read property 'channel' of undefined (at openBus)
This is not saved anywhere var self = this; and therefore is lost when the function (constructor is function) ends.
Just remove the above line in constructor and use everywhere the this instead of self.
Its true that this keyword is little tricky in javascript, but if you follow reasonable approach, you should be fine.
You indeed have issue with this and self
Every member inside the class has to be referred by this. If you declare a variable named var EBZ-Krisemendt = "SO user";, to access it, you need to use it with this, eg: console.log(this.EBZ-Krisemendt);
What you need here is
openBus (callback) {
bus = i2c.open(this.channel, (err) => {callback()});
}
and then mysensor.connection2(foo) will work fine.
while i still don't fully understand the reason behind this i fixed my code by getting rid of that "ES6" class definition.
class.js
const i2c = require('i2c-bus');
const async = require('async');
function Sensor(channel) {
let that = this; // make 'this' available in sub-function scope
this.channel = channel;
function openBus(cb) {
// open the bus-connection
bus = i2c.open(that.channel);
}
function closeBus(cb) {
// close the bus-connection
}
function connection(cb) {
async.series([openBus, closeBus], cb);
}
function getReading(cb) {
async.until(
function() {
// loop condition e.g. max tries to get reading
},
function(cb) {
connection(cb); // calling nested synchronous connection-routine
},
function (err) {
// result handling
}
); // end async.until
} // end getReading
return {
getReading: getReading
} // make only 'getReading' available
}
module.exports = {
Sensor: Sensor
} // make 'Sensor' available
in the 'member'-functions i can now use the 'class'-variables of 'Sensor' by accessing them with 'that' (e.g.: 'that.channel')
Detail:
function openBus(cb){
bus = i2c.open(that.channel);
}
if i'd use this instead of that it would only work while calling openBus directly. in my example it's neccessary to call openBus and closeBus in a synchronous manner (for obvious reasons). since async.series is additionally nested inside async.until (sensor might need several tries to response) the scope of this changes. by using that instead i'm able to ignore the scope.
Comment:
since the solution is kinda generally pointing to using nested async-calls inside custom modules i'll slightly alter the titel of the initial question. i'm still hoping for better solutions and/or explanations, so i won't mark my own anwser as accepted yet.
Ive node moudle which i need to export two functions and get to both of the function a parameter arg1,I try with the following I got error,what am I doing wrong here ?
UPDATE
Ive two method inside module
1. I need to expose it outside and to call it explicit from other
module with parameter
like
require('./controller/module')(functionName1)(parameter);
another function(functionName2) in this module which I need to call it explicit with two parameter ,how should I do it right?
It is not very clear what you want to do, but i think you want something like that:
module.exports = function (arg1) {
return {
server: function (params1) {
//do something with arg1 and params1
},
proc: function (params2) {
//do something with arg1 and params2
}
}
};
And using the module:
var arg1 = 'whatever'
var myMod = require('myMod')(arg1);
myMod.server();
myMod.proc();
Option 2
If i look at your new example
require('./controller/module')(functionName1)(parameter);
you need module that exports a function that returns another function (Higher Order Function).
So for example:
module.exports = function(functionName1) {
if(functionName1 === 'server'){
return function server(parameter){
//do your stuff here
}
}
if(functionName1 === 'proc'){
return function proc(parameter){
//do your stuff here
}
}
};
I would like to know how can I import an external library to nodejs.
For example I would like to have phanotmjs library (I know that arelady exist an npm to get phantomjs, but is only an example).
I think that a way was to get the source file of library and include it into a module like that:
module.exports = function (name, cb) {
//source code of library
});
But I think it is a wrong way of doing it.
How can I include an external library to nodejs project to use it inside the project with its functionality?
Thanks
Without exporting, a no elegant way is to copy past the entire library, in the bottom of your node file. nasty you may already thought about it. there is also a bad thing about that. you will not be able to reuse it in all different files.
The other way is to export the files along your workflow every time you need a function. And i think this is ok.
Otherwise to answer that, you can write the export this way:
module.exports = {
removeElementFromArray_Mutate,
hasClass,
hasClass_ONEtest,
removeClassFromAll,
addClass,
removeClass
};
you can do that with node. all of those are normal function declared this way:
function removeClassFromAll(DOMobject, classes){
for(let i = 0; i < DOMobject.length; i++){
removeClass(DOMobject[i], classes);
}
}
function hasClass_ONEtest(DOMElement, classe) {
let allClasses = DOMElement.className.split(/\s+/);
for(let i = 0; i < allClasses.length; i++){
if(allClasses[i].trim() === classe){
return true;
}
}
return false;
}
function hasClass(DOMElement, classes) {
if (typeof classes === 'string') {
return hasClass_ONEtest(DOMElement, classes);
} else { // multiple classes as array
for (let i = 0; i < classes.length; i++) {
if (!hasClass_ONEtest(DOMElement, classes[i])) {
return false;
}
}
return true;
}
}
this way you can write a quick script that parse all the file, and take out the definitions of the functions, if you can't do it manually. You can use regex, to speed up that. you need two patterns. the first for function name( and the second for name = function(. Hope that was helpful!
the question was more about if there is a way included with nodejs. There is none at the moment. it may be in the future. You may also see this How do I include a JavaScript file in another JavaScript file?. It may not help though.
When one requires a module on nodejs, the content of module.exports is returned. So, one can return a function (as you do on your example) or an object, as in
in module.js:
module.exports={
func:function(){ return true; },
val:10,
...
}
So that, in the requiring file, you can:
var m=require('module');
assert(m.func()===true);
assert(10===m.val);
This is explained in the nodejs documentation under Modules
So if you have an external JS library that exposes three functions: a, b, and c, you might wrap them as:
module.exports={
exportedA:lib.a,
exportedB:lib.b,
exportedC:lib.c
};
lib.a=function(){ ... };
lib.b=function(){ ... };
lib.c=function(){ ... };
I'm about to start building a JS library that will have multiple modules. Let's suppose the library is called Library, and two modules will be called One and Two. I'd like for end users to be able to call the library in two different ways:
Library.One.somefunction(params)
or
somefunction(params)
Basically, I want to give the end users the option of including a namespace or not. Is there a good way to do this? Also, is there a good way to do this if I also want to provide a minified version of the library? This library is something that I could end up in Node.js; for now, I'm going to use it myself, but I want to design it in such a way that it's not too hard to turn in to a sharable project in the future.
Any references you can point me to would be great, thanks!
If you're using Node.js you could leverage the CommonJS module system.
math.js (your library)
exports.add = function() {
for (var i = arguments.length; i--;) {
sum += arguments[i];
}
return sum;
};
program.js (someone using it...)
var MyMath = require('math');
console.log(MyMath.add(1, 2)); // 3
// ... in different ways
var add = require('math').add;
console.log(add(1, 2)); // 3
The basic idea behind making a "namespace" optional is to assign the functions to the global scope, which is the window object:
window.somefunction = Library.One.somefunction;
You can write an include function that works similar to other languages:
var include = function (library, p) {
if (!p) {
for (var prop in library) {
if (library.hasOwnProperty(prop)) {
window[prop] = library[prop];
}
}
} else {
window[p] = library[p];
}
};
Then just do, as required:
include(Library.One);
Or use particular functions only:
include(Library.One, 'somefunction');
Warnings:
Executing the functions without the dot notation (One.somefunction) will cause the this keyword to refer to window rather than Library.One. This isn't a problem if you don't use this at all. If you have data to share to between functions then you can do so using closure scope instead of this:
var Library = {};
(function () {
// I'm a closure, I have local scope
var sharedData = "I'm shared but private to this scope";
Library.One = {};
Library.One.funcOne = function () {
alert(sharedData);
};
Library.One.funcTwo = function () {
sharedData += "!";
};
}) ();
Others have well-advised not to make your methods global. This is because once it is global, it is global for all files, and therefore likely to conflict with other code. What you can do is modify the import function above to create a new object, and assign everything to that object before returning it. Then files that need shortcuts to particular libraries can do:
(function () {
var _ = include(Library.One); // This stays within this scope
_.somefunction();
})();
well, i don't know what you mean by "good way".
First of all, the whole purpose of a namespace is to collect variables that are related and not scatter them all around your public namespace.
Personally I wouldn't use such a thing, but you could loop through your namespace's objects and attach them to the window :
for(var i in Namespace)
if(Namespace.hasOwnProperty(i))
window[i] = Namespace[i];
You could do this pretty easily, but are you certain you want to make all the methods global properties?
You could implement it like this (very simplified):
(function( window, undefined ) {
// Your code setting up namespaces
var Library = {One:{},Two:{}};
// function for adding library code to both namespaces.
// Could be modified to accept an Array of functions/names
function addToLibraryOne( id, fn ) {
window[id] = Library.One[id] = fn;
}
// add a function
addToLibraryOne( "somefunction", function( params ) {
// function code
});
window.Library = Library;
})( window );
I'd wonder if you really want to pollute the global namespace like this.
At the very least, I'd make the global properties an option, then only have the function add those if that option is selected.
Well, the second one means that you also want the functions and object and whatever in your modules to be in the global scope. Entirely possible of course, but so against best practices as to be somewhat abhorrent.
For the first part, just declare your Library namespace globally:
var Library = {};
and then start populating it with your modules:
Library.One = {};
Library.Two = {};
and then start adding the functionality to those modules.
(function($) {
var $.froobString = function(s) { .... };
...etc...
})(Library.One);
(Here I've done it as a self-executing anonymous function that passes in Library.One as $.)
To convert all that to globals, have a routine like this:
var convertToGlobals = function(module) {
for (name in module) {
window[name] = module[name];
}
};
convertToGlobals(Library.One)
But then again I'd advise against it.
I might be wrong about this (so this might get downvoted, but I want this evaluated), but I think you are setting up a contradiction with the requirements
1) I want to use namespaces
2) I want to be able to access namespace functionality without the namespace.
basically 2 is "I dont want namespaces".
For implementation, you could just define a bunch of functions globally that route into the namespace, but then why have the namespace to begin with?