admin管理员组

文章数量:1390784

I'm using a design pattern that uses the return statement to expose public class methods.

Problem is: I'm getting a lot of JSC_INEXISTENT_PROPERTY warnings in Closure Compiler's Advanced mode, which makes it difficult to check the warnings that actually matter.

Example of the pattern I use:

// ==ClosureCompiler==
// @pilation_level ADVANCED_OPTIMIZATIONS
// ==/ClosureCompiler==

/**
 * @constructor
 */
var MyClass = function() {

    var someFunc = function(myString) {
        console.log(myString);
    }

    return {
        myPublicFunc: someFunc
    };
}

var myClassInstance = new MyClass();
myClassInstance.myPublicFunc('Hello World');

Warnings:

JSC_INEXISTENT_PROPERTY: Property myPublicFunc never defined on MyClass \
    at line 16 character 0
myClassInstance.myPublicFunc('Hello World');

Output (formatted):

(new function() {
    return {
        a: function(a) {
            console.log(a)
        }
    }
}).a("Hello World");

Which is weird, because Closure understood what the code was doing and piled the code correctly, renaming myPublicFunc consistently to a. So why did I get this warning? Am I doing something wrong?

Note: I do not want to turn off these warnings because it would also hide warnings I actually care about. I also do not want to use quoted strings or exports because I do want Closure to press these.

I'm using a design pattern that uses the return statement to expose public class methods.

Problem is: I'm getting a lot of JSC_INEXISTENT_PROPERTY warnings in Closure Compiler's Advanced mode, which makes it difficult to check the warnings that actually matter.

Example of the pattern I use:

// ==ClosureCompiler==
// @pilation_level ADVANCED_OPTIMIZATIONS
// ==/ClosureCompiler==

/**
 * @constructor
 */
var MyClass = function() {

    var someFunc = function(myString) {
        console.log(myString);
    }

    return {
        myPublicFunc: someFunc
    };
}

var myClassInstance = new MyClass();
myClassInstance.myPublicFunc('Hello World');

Warnings:

JSC_INEXISTENT_PROPERTY: Property myPublicFunc never defined on MyClass \
    at line 16 character 0
myClassInstance.myPublicFunc('Hello World');

Output (formatted):

(new function() {
    return {
        a: function(a) {
            console.log(a)
        }
    }
}).a("Hello World");

Which is weird, because Closure understood what the code was doing and piled the code correctly, renaming myPublicFunc consistently to a. So why did I get this warning? Am I doing something wrong?

Note: I do not want to turn off these warnings because it would also hide warnings I actually care about. I also do not want to use quoted strings or exports because I do want Closure to press these.

Share Improve this question asked Jun 24, 2012 at 15:15 BlaiseBlaise 13.5k9 gold badges78 silver badges102 bronze badges
Add a ment  | 

3 Answers 3

Reset to default 4

Your function is annotated incorrectly. It's actually not a constructor and in this case the new keyword is unnecessary. Your function simply returns an anonymous type with a myPublicFunc property.

To annotate such a pattern, you would use the record type:

/** @return {{myPublicFunc: function(string) }} */
var MyClass = function() {

    var someFunc = function(myString) {
        console.log(myString);
    }

    return {
        myPublicFunc: someFunc
    };
};

var myClassInstance = MyClass(); // new keyword not needed
myClassInstance.myPublicFunc('Hello World');

Another annotation option is to create an interface and type-cast the returned object to be that interface. This option would be useful when multiple functions return an object that conforms to the same interface.

You can also use:

/** @type {function(new:{myPublicFunc: function(string)} )} */
var MyClass = function() {...

The function can be called with "new" but doesn't return an instance of "MyClass".

Adding

MyClass.prototype.myPublicFunc = null;

would solve the problem though I don't know whether this is the best solution.

I don't really know how the piler works, but I could imagine that if you have a constructor function, it expects instance properties to be assigned to this inside the constructor or to MyClass.prototype.

If you remove the @constructor annotation and omit new, then there is not warning (but the piled code is only console.log("Hello World");.

本文标签: javascriptGoogle Closure Compilerhow to handle JSCINEXISTENTPROPERTY gracefullyStack Overflow