Forked from idettman/add-to-existing-namespaces.js
Created
December 25, 2023 02:45
-
-
Save belachkar/56ba598e48b6a98f0784b5c28ea774c2 to your computer and use it in GitHub Desktop.
JavaScript: JSDoc Advanced Tips
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
/* https://leahayes.wordpress.com/2011/08/28/documenting-javascript-with-jsdoc3/ | |
Namespaces can still be documented when a more abstract mechanism is used. @lends allows members to be added to an existing namespace: | |
*/ | |
/** | |
* Root namespace | |
* @namespace root | |
*/ | |
$namespace('root', /** @lends root **/ { | |
/** | |
* Do something really neat | |
*/ | |
foo: function() { | |
} | |
}); | |
/** | |
* Nested namespace | |
* @namespace root.nested | |
*/ | |
$namespace('root.nested', /** @lends root.nested **/ { | |
/** | |
* Do something else that is really neat | |
*/ | |
bar: function() { | |
} | |
}); |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
/* | |
https://stackoverflow.com/questions/19230971/how-do-i-jsdoc-a-nested-objects-methods | |
You can't document nested functions directly. I didn't like Prongs solution, so I used a different implementation without namespaces (it's JS, not Java!). | |
*/ | |
/** @module foobar */ | |
/** @function */ | |
function foobarbaz() { | |
/* | |
* You can't document properties inside a function as members, like you | |
* can for classes. In Javascript, functions are first-class objects. The | |
* workaround is to make it a @memberof it's closest parent (the module). | |
* manually linking it to the function using (see: {@link ...}), and giving | |
* it a @name. | |
*/ | |
/** | |
* Foo object (see: {@link module:foobar~foobarbaz}) | |
* @name foo | |
* @inner | |
* @private | |
* @memberof module:foobar | |
* @property {Object} foo - The foo object | |
* @property {Object} foo.bar - The bar object | |
* @property {function} foo.bar.baz - The baz function | |
*/ | |
var foo = { | |
/* | |
* You can follow the same steps that was done for foo, with bar. Or if the | |
* @property description of foo.bar is enough, leave this alone. | |
*/ | |
bar: { | |
/* | |
* Like the limitation with the foo object, you can only document members | |
* of @classes. Here I used the same technique as foo, except with baz. | |
*/ | |
/** | |
* Baz function (see: {@link module:foobar~foo}) | |
* @function | |
* @memberof module:foobar | |
* @returns {string} Some string | |
*/ | |
baz: function() { /*...*/ } | |
} | |
}; | |
return foo; | |
} | |
/** @class */ | |
function Hello() { | |
/** @member {Object} */ | |
var hi = {}; | |
} | |
/* | |
Just to improve on Prongs's answer a bit for JSDoc3, I was only able to get it to work when I used the @instance annotation in lieu of @member. | |
ES6 example code follows: | |
*/ | |
class Test | |
{ | |
/** | |
* @param {object} something | |
*/ | |
constructor(something) | |
{ | |
this.somethingElse = something; | |
/** | |
* This sub-object contains all sub-class functionality. | |
* | |
* @type {object} | |
*/ | |
this.topology = { | |
/** | |
* Informative comment here! | |
* | |
* @alias topology.toJSON | |
* @memberof! Test# | |
* @instance topology.toJSON | |
* | |
* @returns {object} JSON object | |
*/ | |
toJSON() | |
{ | |
return deepclone(privatesMap.get(this).innerJSON); | |
}, | |
} | |
} | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
/* | |
https://leahayes.wordpress.com/2011/08/28/documenting-javascript-with-jsdoc3/ | |
Class (with prototype object) | |
*/ | |
/** | |
* Base class of a game entity | |
* @class Entity | |
*/ | |
Entity = function() { | |
}; | |
/** | |
* Render entity | |
* @param {CanvasRenderingContext2D} dc Device context | |
*/ | |
Entity.prototype.render = function(dc) { | |
// Instance method! | |
}; | |
/** | |
* Get new instance of entity | |
* @param {string} type Type of entity to instantiate | |
* @returns {@link Entity} | |
*/ | |
Entity.getInstance: function(type) { | |
// Static method! | |
}; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
/* | |
https://leahayes.wordpress.com/2011/08/28/documenting-javascript-with-jsdoc3/ | |
Classes (with classical approach) | |
*/ | |
/** | |
* Base class of a game entity | |
* @class Entity | |
*/ | |
$class('Entity', /** @lends Entity# **/ { | |
/** | |
* Render entity | |
* @param {CanvasRenderingContext2D} dc Device context | |
*/ | |
render: function(dc) { | |
// Instance method! | |
} | |
}, /** @lends Entity **/ { | |
/** | |
* Get new instance of entity | |
* @param {string} type Type of entity to instantiate | |
* @returns {@link Entity} | |
*/ | |
getInstance: function(type) { | |
// Static method! | |
} | |
}); | |
/** | |
* Ball entity | |
* @class Ball | |
* @extends Entity | |
*/ | |
$class('Ball', 'Entity', /** @lends Ball# **/ { | |
/** | |
* Force ball to bounce | |
*/ | |
bounce: function() { | |
// Instance method! | |
} | |
}); |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
/* | |
https://groups.google.com/forum/#!topic/jsdoc-users/izErstbwNUU | |
I advocate the use of already-defined patterns. | |
A bunch of new tags is not the main aim of my proposition. | |
Please find below JS code with comments. | |
It is self descriptive example. | |
-- Tawez | |
*/ | |
/** | |
* @namespace | |
*/ | |
Ns = { | |
/** | |
* Nested structures could be documented in simple way, | |
* we just need to reuse already defined patterns. | |
* Property dot notation (http://code.google.com/p/jsdoc-toolkit/wiki/ | |
TagParam#Parameters_With_Properties) works, | |
* but output is flat and we lose information about property | |
structure. | |
* Michael asked about view. IMHO it should be rendered as in | |
following example (simplified markdown like syntax to illustrate the | |
idea): | |
* @example | |
* - Object staticDeepStruct | |
* Comments etc. | |
* - Number i | |
* Positive val | |
* - String s | |
* String var | |
* @type Object | |
*/ | |
staticDeepStruct: { | |
/** | |
* Positive val | |
* @type Number | |
* @default 1 | |
*/ | |
i: 1, | |
/** | |
* String var | |
* @type Number | |
* @default "text" | |
*/ | |
s: "text", | |
} | |
}; | |
/* | |
----------------------------------------------------------------------- | |
* This comment block should give following documentation for | |
constructor: | |
* Class Detail | |
* Ns.Base(config) | |
* +-------+ | |
* |example| | |
* +-------+ | |
* +-------+ | |
* |example| | |
* +-------+ | |
* | |
* Parameters: | |
* {Object} config Optional | |
* Config object | |
* - {String} text | |
* Value for text property | |
* | |
----------------------------------------------------------------------- | |
*/ | |
/** | |
* @class | |
* @example | |
* var b = new Ns.Base(); | |
* @example | |
* var b = new Ns.Base({ | |
* text: "new value" | |
* }); | |
* @param {Object} [config] Config object | |
* @param {String} config.text Value for text property | |
*/ | |
Ns.Base = createClass(Object, /** @lends Ns.Base.prototype */ { | |
/** | |
* @type String | |
* @default "make some noise" | |
*/ | |
text: "make some noise", | |
/** | |
* deepStruct should be rendered in the same way as | |
Ns.staticDeepStruct | |
* @type Object | |
*/ | |
deepStruct: { | |
/** | |
* Positive val | |
* @type Number | |
* @default 111 | |
*/ | |
i: 111, | |
/** | |
* String var | |
* @type Number | |
* @default "more text" | |
*/ | |
s: "more text", | |
}, | |
/** | |
* Returns text property value | |
* @returns {String} | |
*/ | |
foo: function () { | |
return this.text; | |
} | |
/** | |
* If we have "directive" lends, then tag memberOf is unnecessary | |
here - we have well defined "context" | |
* @function | |
* @name bar | |
* @memberOf Ns.Base.prototype | |
* @returns Number | |
*/ | |
}); | |
/** | |
* @class | |
* @augments Ns.Base | |
* @property {Number} [i=1] | |
* Some comments to i property | |
* @example | |
* // this is an example for i property, | |
* // but will be parsed and rendered as constructor example, arghhhh! | |
* @property {String} [s=""] | |
* Some comments to s property | |
*/ | |
Ns.Derived = createClass(Ns.Base, /** @lends Ns.Derived.prototype */ { | |
/** | |
* As far as I know this is the only working pattern | |
* if I'd like to redefine property documentation with a lot of text | |
and examples | |
* and without providing the code of property. | |
* BTW If we have "directive" lends, then tag fieldOf is unnecessary | |
here - we have well defined "context" | |
* @example | |
* // this is an example for text property, | |
* // and will be rendered in the right place | |
* @name text | |
* @fieldOf Ns.Derived.prototype | |
* @type String | |
* @default "be quiet" | |
*/ | |
/** | |
* Dot notation works but right now function gets wrong definition as | |
<tt>{Object<u>, number, | |
number</u>} foo()</tt> (I think it is technical problem only). | |
* As an alternative we can use colon notation as below. | |
* Should be rendered in the same way as Ns.staticDeepStruct | |
* @returns {Object} The coordinates of the current target | |
* @returns {number} return:x The x value. | |
* @returns {number} return:y The y value. | |
*/ | |
foo: function () { | |
return { | |
x: 0, | |
y: 0 | |
}; | |
} | |
}); | |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
// JSDoc the object. Then its members. | |
/** | |
* @param data Information about the object. | |
* @param data.member Information about the object's members. | |
*/ | |
function getData(data){ | |
console.log(data.member); | |
} | |
/* | |
Tested in PyCharm. @Nicholi confirms it works in Webstorm. | |
The {{ member:type }} syntax Andreas suggested may conflict with Django templates. | |
Thanks to Jonny Buchanan's answer citing the @param wiki. | |
To document arrays of objects, use [] brackets as JSDoc suggests: | |
*/ | |
/** | |
* @param data | |
* @param data.array_member[].foo | |
*/ | |
/** | |
* @param {{some_unres_var:string}} data | |
*/ | |
function getData(data){ | |
console.log(data.some_unres_var); | |
} | |
/* | |
All other answers are incorrect for the general case. What if you don't get data as a parameter? You don't have JSDoc then: | |
*/ | |
function niceApiCall(parameters) { | |
const result = await ... // HTTP call to the API here | |
for (const e of result.entries) { | |
.. // decorate each entry in the result | |
} | |
return result; | |
} | |
/* | |
WebStorm will warn that "result.entries" is an unresolved variable (field). | |
The general solution is to add an @namespace declaration: | |
*/ | |
function niceApiCall(parameters) { | |
/** @namespace result.entries **/ | |
const result = await ... // HTTP call to the API here | |
for (const e of result.entries) { | |
.. // decorate each entry in the result | |
} | |
return result; | |
} | |
// An object with string keys and number values: | |
{Object.<string, number>} | |
// An array of MyClass instances. | |
{Array.<MyClass>} | |
// or: | |
{MyClass[]} | |
// This can be a number or a boolean. | |
{(number|boolean)} | |
// Specifies the name of a symbol. If you have documented the symbol, JSDoc creates a link to the documentation for that symbol. | |
{boolean} | |
{myNamespace.MyClass} | |
// A number or null. | |
{?number} | |
// A number, but never null. | |
{!number} | |
// This function accepts a variable number of numeric parameters. | |
@param {...number} num | |
// An optional parameter named foo. | |
@param {number} [foo] | |
// or: | |
@param {number=} foo | |
// An optional parameter foo with default value 1. | |
@param {number} [foo=1] | |
/** | |
@callback myCallback | |
@param {number} x - ... | |
*/ | |
/* @type {myCallback} */ | |
var cb; | |
//Type Def | |
// Documenting a type with properties 'id', 'name', 'age'. | |
/** | |
@typedef PropertiesHash | |
@type {object} | |
@property {string} id - an ID. | |
@property {string} name - your name. | |
@property {number} age - your age. | |
/ | |
/** @type {PropertiesHash} / | |
var props; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
/* | |
In this example we have a namespace named "config." We want all the information about the defaults property, including its nested values, to appear on the same page with the documentation for config. | |
A namespace with defaults and nested default properties | |
*/ | |
/** | |
* @namespace | |
* @property {object} defaults - The default values for parties. | |
* @property {number} defaults.players - The default number of players. | |
* @property {string} defaults.level - The default level for the party. | |
* @property {object} defaults.treasure - The default treasure. | |
* @property {number} defaults.treasure.gold - How much gold the party starts with. | |
*/ | |
var config = { | |
defaults: { | |
players: 1, | |
level: 'beginner', | |
treasure: { | |
gold: 0 | |
} | |
} | |
}; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
// A type definition with required and optional property | |
/** | |
* User type definition | |
* @typedef {Object} User | |
* @property {string} email | |
* @property {string} [nickName] | |
*/ |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
/** | |
* @param {string} key | |
* @param {string} value | |
* @param {string} [expires=''] | |
* @param {string} [sameSite='/'] | |
* @param {string} [domain] domain (e.g., 'example.com' or 'subdomain.example.com'). | |
* If not specified, defaults to the host portion of the current document location. | |
* If a domain is specified, subdomains are always included. | |
* Domain must match the domain of the JavaScript origin. Setting cookies to foreign domains will be silently ignored. | |
*/ | |
export function setCookie(key, value, expires, sameSite, domain) { | |
if (hasDeviceAccess()) { | |
document.cookie = `${key}=${encodeURIComponent(value)}${(expires !== '') ? `; expires=${expires}` : ''}; path=/${sameSite ? `; SameSite=${sameSite}` : ''}${domain ? `; domain=${domain}` : ''}`; | |
} | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
/* | |
https://groups.google.com/forum/#!topic/jsdoc-users/izErstbwNUU | |
I've updated the issue tracker with the work I've done on this so far. | |
https://github.com/micmath/jsdoc/issues/34 | |
This unfortunately entails an API change, but the work is currently in | |
a separate branch. The summary is that if you are using JSDoc 3 and | |
are currently using the `@property` tag, you should change those to | |
`@member` tags. This can be a simple search & replace change. I would | |
expect this to impact only a very few people, since JSDoc 3 is still | |
in beta and the `@property` tag is not actually documented yet in that | |
version. | |
Note that this change does not have any affect on JSDoc Toolkit | |
whatsoever. In fact this should make JSDoc 3 more compatible with | |
`@property` tags as used in JSDoc Toolkit. | |
I expect I will merge this change into the master branch in the next | |
week or so. | |
*/ |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
/* | |
https://groups.google.com/forum/#!topic/jsdoc-users/izErstbwNUU | |
I think how you present the results depends on how it is being used. If | |
the components of the object are intended to be consumed or set whole | |
(in one step or scope), I think the entire object should be on one page. | |
If the fields are set one at a time, or one sub-object at a time, then | |
separate pages, one per container, would probably be preferable. | |
But, that can't be gleaned from the code. I think the tag has to tell | |
the template how to render it by classifying the types and assigning a | |
tag for each, or to repurpose @kind or another similar tag. | |
For instance, if we consider the first type, where it is all consumed | |
and modified at once a "container" and the other type, which is handled | |
piecemeal, a "hash", then you could document it as follows: | |
*/ | |
/** @container taskContainer */ | |
myobject = { | |
/** @hash defaults (would document as taskContainer.defaults */ | |
defaults: { | |
/** @hash a */ | |
a: { | |
/** @hash aa */ | |
aa: { | |
/** when true, your hair will fall out */ | |
aaa: true | |
}, | |
/** returns an object (would you document the return here? or on the return line?) */ | |
aa2: function(options){ | |
return { | |
aaa2: false | |
}; | |
} | |
}, | |
/** blah (no need to decorate further, rhino will tell us this is child of taskContainer) | |
*/ | |
b: "Hit the light", | |
/** blah | |
*/ | |
c: true | |
} | |
}; | |
/* | |
Of course, the terms "hash" and "container" were just used to | |
illustrate the concept. Hash is definitely not the right term, but | |
container might work long term. | |
When presenting the template, just follow the logic, each container will | |
contain all contents that are not hashes, classes, namespaces, etc on | |
one page. Each hash will gets its own page and link from the documented | |
member's attribute, giving it a type of the named @hash and a link to | |
the docs for the hash. It leaves the programmer in control of how to | |
navigate the symbols and that may make the ultimate solution to this | |
problem simpler. | |
It does, however, pollute the tag namespace. And I don't think it solves | |
for documenting returned containers easily. | |
*/ |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
// https://stackoverflow.com/questions/17119100/how-to-use-jsdoc3-to-document-nested-namespaces | |
/** | |
* @namespace MyNamespace.MySubNamespace | |
*/ | |
(function (MyNamespace) { | |
/** | |
* Foo namespace | |
* @namespace Foo | |
* @memberOf MyNamespace.MySubNamespace | |
*/ | |
var Foo = { | |
/** | |
* Does something. | |
* @memberOf MyNamespace.MySubNamespace.Foo | |
* @param {object} someParam Some parameter. | |
*/ | |
doSomething: function (someParam) { | |
// doing it | |
} | |
}; | |
MyNamespace.MySubNamespace.Foo = Foo; | |
})(window.MyNamespace) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
/* | |
https://stackoverflow.com/questions/19230971/how-do-i-jsdoc-a-nested-objects-methods | |
You can use a combination of @module or @namespace along with @memberof. | |
*/ | |
define([], function() { | |
/** | |
* A test module foo | |
* @version 1.0 | |
* @exports mystuff/foo | |
* @namespace foo | |
*/ | |
var foo = { | |
/** | |
* A method in first level, just for test | |
* @memberof foo | |
* @method testFirstLvl | |
*/ | |
testFirstLvl: function(msg) {}, | |
/** | |
* Test child object with child namespace | |
* @memberof foo | |
* @type {object} | |
* @namespace foo.bar | |
*/ | |
bar: { | |
/** | |
* A Test Inner method in child namespace | |
* @memberof foo.bar | |
* @method baz | |
*/ | |
baz: function() { /*...*/ } | |
}, | |
/** | |
* Test child object without namespace | |
* @memberof foo | |
* @type {object} | |
* @property {method} baz2 A child method as property defination | |
*/ | |
bar2: { | |
/** | |
* A Test Inner method | |
* @memberof foo.bar2 | |
* @method baz2 | |
*/ | |
baz2: function() { /*...*/ } | |
}, | |
/** | |
* Test child object with namespace and property def. | |
* @memberof foo | |
* @type {object} | |
* @namespace foo.bar3 | |
* @property {method} baz3 A child method as property defination | |
*/ | |
bar3: { | |
/** | |
* A Test Inner method in child namespace | |
* @memberof foo.bar3 | |
* @method baz3 | |
*/ | |
baz3: function() { /*...*/ } | |
}, | |
/** | |
* Test child object | |
* @memberof foo | |
* @type {object} | |
* @property {method} baz4 A child method | |
*/ | |
bar4: { | |
/** | |
* The @alias and @memberof! tags force JSDoc to document the | |
* property as `bar4.baz4` (rather than `baz4`) and to be a member of | |
* `Data#`. You can link to the property as {@link foo#bar4.baz4}. | |
* @alias bar4.baz4 | |
* @memberof! foo# | |
* @method bar4.baz4 | |
*/ | |
baz4: function() { /*...*/ } | |
} | |
}; | |
return foo; | |
}); | |
/* | |
EDIT as per Comment: (Single page solution for module) | |
bar4 without that ugly property table. ie @property removed from bar4. | |
*/ | |
define([], function() { | |
/** | |
* A test module foo | |
* @version 1.0 | |
* @exports mystuff/foo | |
* @namespace foo | |
*/ | |
var foo = { | |
/** | |
* A method in first level, just for test | |
* @memberof foo | |
* @method testFirstLvl | |
*/ | |
testFirstLvl: function(msg) {}, | |
/** | |
* Test child object | |
* @memberof foo | |
* @type {object} | |
*/ | |
bar4: { | |
/** | |
* The @alias and @memberof! tags force JSDoc to document the | |
* property as `bar4.baz4` (rather than `baz4`) and to be a member of | |
* `Data#`. You can link to the property as {@link foo#bar4.baz4}. | |
* @alias bar4.baz4 | |
* @memberof! foo# | |
* @method bar4.baz4 | |
*/ | |
baz4: function() { /*...*/ }, | |
/** | |
* @memberof! for a memeber | |
* @alias bar4.test | |
* @memberof! foo# | |
* @member bar4.test | |
*/ | |
test : true | |
} | |
}; | |
return foo; | |
}); |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment