[英]JSDoc: How do I document `var self = this;`?
只要您使用this
關鍵字,JSDoc 就非常擅長獲取在類上定義的方法和屬性,例如:
/** @class */
function Person(name) {
/** This person's name */
this.name = name;
/** Greet someone */
this.greet = function(person) {
return 'Hey there, '+person.name;
};
/** Log a greeting to the browser console */
this.logGreeting = function(person) {
console.log(this.greet(Person));
};
}
這將生成帶有“Class Person”頁面的文檔,其中列出了name
作為 Member 和greet()
和logGreeting()
作為方法。
但是當我遇到一個需要使用self = this
模式的復雜案例時,事情就開始出現問題:
/** @class */
function Person(name) {
var self = this;
/** This person's name */
self.name = name;
/** Greet someone */
self.greet = function(person) {
return 'Hey there, '+person.name;
};
/** Log a greeting to the browser console */
self.logGreeting = function(person) {
console.log(self.greet(Person));
};
/** Log a greeting to the browser console after some delay */
self.logGreetingDelayed = function(person, delay) {
setTimeout(function() { self.logGreeting(person); }, delay);
};
}
此示例生成一個Class Person
頁面,但它沒有name
member 或任何方法。
我已經看到您可以@memberof
使用@memberof
手動將每個成員和方法附加到類,但這真的很冗長,我想知道是否有辦法告訴 JSDoc self
指的是類。
(順便說一句,我正在使用 JSDoc 3.4,以防萬一。)
@alias
注釋可用於告訴 JSDoc 將self
視為對類的引用。 實際上,從技術上講,您需要將self
別名為類的原型,而不僅僅是類本身的名稱(以我不完全理解的方式破壞了東西)。 為此,您需要將@alias
設置為Person#
1 :
/** @class */
function Person(name) {
/** @alias Person# */
var self = this;
/** This person's name */
self.name = name;
/** Greet someone */
self.greet = function(person) {
return 'Hey there, '+person.name;
};
/** Log a greeting to the browser console */
self.logGreeting = function(person) {
console.log(self.greet(Person));
};
/** Log a greeting to the browser console after some delay */
self.logGreetingDelayed = function(person, delay) {
setTimeout(function() { self.logGreeting(person); }, delay);
};
}
1:從技術上講, Person#
等效於Person.prototype
,因為尾隨#
指的是對象的原型(據我所知;可以更正)。 話雖這么說, this
實際上指的是一個實例,這是不一樣的原型,所以我不推薦使用這個符號,因為它使更多的評論混淆。 幸運的是,原型方法和真正的實例方法之間的 JSDoc 輸出沒有區別,所以不要太擔心Person#
符號。
替代方法相同,包括完整性,但可能應該避免:
// ...
/** @alias Person.prototype */
var self = this;
// ...
您正在使這個(請原諒雙關語)變得比它需要的更復雜。 你的設計有很多問題。
您不需要使用this
來設置原型。 我非常喜歡像這樣將對象Instantiation
與Initialization
范式分開:
/** @class */ function Person() {} Person.prototype = { /** This person's name * @return {Person} */ init: function(name) { this.name = name; return this; }, };
Greet已經在一個對象上工作,你不需要傳入第二個對象:
/** Greet someone */ greet: function() { return 'Hey there, '+this.name; },
這也簡化了logGreeting
:
/** Log a greeting to the browser console */ logGreeting: function() { console.log(this.greet()); },
但是,假設您確實想將第二個對象(人)傳遞給您的logGreeting
,則它錯誤地傳遞了Class
而不是Object
。 應該是這樣的:
/** Greet someone */ self.greet = function(person) { return 'Hey there, '+person.name; }; /** Log a greeting to the browser console */ self.logGreeting = function(person) { console.log(self.greet(person)); // BUG: was Person instead of person };
您不應該使用self
來設置原型——您首先錯誤地使用了使用self
的原因:它們用於需要引用對象的回調。
例如,讓我們添加一個人重命名時的回調:
rename: function(newName) {
var self = this;
var cbRename = function() {
self.onRename( self.name, newName ); // Why self is needed
self.name = newName;
};
setTimeout( cbRename, 1 );
},
/** Callback triggered on rename */
onRename: function(oldName,newName) {
console.log( "The person formally known as: '" + oldName + "'" );
console.log( "Is now known as: '" + newName + "'" );
},
將所有內容放在一個示例中:
/** @class */ function Person() {} Person.prototype = { /** This person's name * @return {Person} */ init: function(name) { this.name = name; return this; }, /** Greet someone */ greet: function() { return 'Hey there, '+this.name; }, /** Log a greeting to the browser console */ logGreeting: function() { console.log(this.greet()); }, rename: function(newName) { var self = this; var cbRename = function() { self.onRename( self.name, newName ); self.name = newName; }; setTimeout( cbRename, 1 ); }, /** Callback triggered on rename */ onRename: function(oldName,newName) { console.log( "The person formally known as: '" + oldName + "'" ); console.log( "Is now known as: '" + newName + "'" ); }, }; var alice = new Person().init( 'Alice' ); console.log( alice ); alice.logGreeting(); alice.rename( 'Bob' );
生成這個 JSdoc3 html:
<div id="main"> <h1 class="page-title">Class: Person</h1> <section> <header> <h2>Person</h2> </header> <article> <div class="container-overview"> <hr> <h4 class="name" id="Person"><span class="type-signature"></span>new Person<span class="signature">()</span><span class="type-signature"></span></h4> <dl class="details"> <dt class="tag-source">Source:</dt> <dd class="tag-source"><ul class="dummy"><li> <a href="person.js.html">person.js</a>, <a href="person.js.html#line2">line 2</a> </li></ul></dd> </dl> </div> <h3 class="subsection-title">Methods</h3> <hr> <h4 class="name" id="greet"><span class="type-signature"></span>greet<span class="signature">()</span><span class="type-signature"></span></h4> <div class="description"> Greet someone </div> <dl class="details"> <dt class="tag-source">Source:</dt> <dd class="tag-source"><ul class="dummy"><li> <a href="person.js.html">person.js</a>, <a href="person.js.html#line17">line 17</a> </li></ul></dd> </dl> <hr> <h4 class="name" id="init"><span class="type-signature"></span>init<span class="signature">()</span><span class="type-signature"> → {<a href="Person.html">Person</a>}</span></h4> <div class="description"> This person's name return {Person} </div> <dl class="details"> <dt class="tag-source">Source:</dt> <dd class="tag-source"><ul class="dummy"><li> <a href="person.js.html">person.js</a>, <a href="person.js.html#line9">line 9</a> </li></ul></dd> </dl> <hr> <h4 class="name" id="logGreeting"><span class="type-signature"></span>logGreeting<span class="signature">()</span><span class="type-signature"></span></h4> <div class="description"> Log a greeting to the browser console </div> <dl class="details"> <dt class="tag-source">Source:</dt> <dd class="tag-source"><ul class="dummy"><li> <a href="person.js.html">person.js</a>, <a href="person.js.html#line23">line 23</a> </li></ul></dd> </dl> <hr> <h4 class="name" id="onRename"><span class="type-signature"></span>onRename<span class="signature">()</span><span class="type-signature"></span></h4> <div class="description"> Callback triggered on rename </div> <dl class="details"> <dt class="tag-source">Source:</dt> <dd class="tag-source"><ul class="dummy"><li> <a href="person.js.html">person.js</a>, <a href="person.js.html#line38">line 38</a> </li></ul></dd> </dl> </article> </section> </div>
為什么使用變量來接收this
而不是將this
與箭頭函數一起使用?
/** @class */
function Person(name) {
/** This person's name */
this.name = name;
/** Greet someone */
this.greet = function(person) {
return 'Hey there, '+person.name;
};
/** Log a greeting to the browser console */
this.logGreeting = function(person) {
console.log(this.greet(person));
};
/** Log a greeting to the browser console after some delay */
this.logGreetingDelayed = function(person, delay) {
setTimeout(() => this.logGreeting(person), delay);
};
}
如果你想記錄this
(例如使用私有方法),你可以使用 JSDoc @this
:
/** @class */
function Person(name) {
/** This person's name */
this.name = name;
/** Greet someone */
this.greet = function(person) {
return 'Hey there, '+person.name;
};
/** Log a greeting to the browser console */
this.logGreeting = function(person) {
privateLogGreeting.call(this, person);
};
/** Log a greeting to the browser console after some delay */
this.logGreetingDelayed = function(person, delay) {
setTimeout(() => this.logGreeting(person), delay);
};
}
//Private method
/**
* @this Person
* @param {Person} person
*/
function privateLogGreeting(person) {
console.log(this.greet(person));
}
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.