JSDoc:我如何记录`var self = this;`?

时间:2016-03-30 15:18:51

标签: javascript jsdoc jsdoc3

只要您使用(array([[ 5.55111512e-17], [ -1.00000000e+00], [ 0.00000000e+00], [ -2.77555756e-17], [ 1.11022302e-16]]), array([ 2.]), array([[ 0., -1., 0., 0., 0., 0.]])) 关键字,JSD就非常善于选择在类上定义的方法和属性,例如:

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)); }; } 作为成员,namegreet()作为方法。

但是当我遇到需要使用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手动将每个成员和方法附加到类中,但这真的很冗长,我想知道是否有办法告诉JSDoc { {1}}指的是班级。

(顺便说一下,我正在使用JSDoc 3.4,以防这很重要。)

3 个答案:

答案 0 :(得分:1)

@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;

// ...

答案 1 :(得分:1)

你正在做这个(原谅双关语)比它需要的更复杂。您的设计存在许多问题。

  1. 您不需要使用this来设置原型。我更喜欢将对象InstantiationInitialization范例分开,如下所示:

    /** @class */
    function Person() {}
    
    Person.prototype =
    {
        /** This person's name
         * @return {Person}
         */
        init: function(name)
        {
            this.name = name;
    
            return this;
        },
    };
    
  2. Greet 已经在一个对象上工作,你不需要传入第二个对象:

    /** Greet someone */
    greet: function() {
        return 'Hey there, '+this.name;
    },
    

    这也简化了logGreeting

    /** Log a greeting to the browser console */
    logGreeting: function() {
        console.log(this.greet());
    },
    
  3. 但是,假设您执行想要将第二个对象(人)传递给logGreeting,则会错误地传递{{1}而不是Class。它应该是这样的:

    Object
  4. 您不应该使用/** 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的原因:它们用于回调,需要一个对象来引用。

  5. 例如,让我们在重命名某人时添加回调:

    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 + "'" );
            },
    
    
    
    

    哪个生成这个JSdoc3 html:

    
    
    /** @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' );
    
    
    

答案 2 :(得分:0)

为什么使用变量来接收 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));
}