【问题标题】:Javascript call prototype function from function inside constructorJavascript从构造函数内部的函数调用原型函数
【发布时间】:2015-04-06 14:55:25
【问题描述】:

这个问题我找了很久。找不到任何答案来满足我的问题。我正在尝试的是:

function myClass() {
    function privateFunction () {
        publicFunction();    //Error
    }
}

myClass.prototype.publicFunction = function() {
    this.variable = 1;
}
myClass.prototype.publicFunction2= function() {
    return this.variable;
}

这给了我错误。我不明白真正的问题是什么:

我尝试了什么:

this.publicFunction();

然后:

myClass.publicFunction();

然后:

myClass.prototype.publicFunction();

这可行,但它会覆盖每个对象。就好像它在不同的 JS 对象之间是静态的一样。

【问题讨论】:

标签: javascript prototype javascript-objects


【解决方案1】:

您没有正确声明原型函数。在调用函数 publicFunction 时,您还缺少 this 关键字。

私有函数(privateFunction)不是类的成员,所以如果你想将它作为函数调用,你必须为其指定上下文。

function myClass() {
    function privateFunction () {
        this.publicFunction();
    }

    privateFunction.call(this);
    document.write(this.publicFunction2()); // show value in Stackoverflow snippet
}

myClass.prototype.publicFunction = function() {
    this.variable = 1;
}

myClass.prototype.publicFunction2 = function() {
    return this.variable;
}

var myClassPrototype = new myClass();

【讨论】:

  • 检查我的编辑。我试过这个。但不幸的是没有工作。 Here 是我想要做的完整代码.. 很长。但容易理解
  • this.publicFunction() 说:undefined is not a function
  • @VeerShrivastav:我在发布代码后立即对其进行了编辑,看起来您在编辑之前就有了代码。更新页面并尝试。在您的 User 类中,您在 formUserObjectFromArguments 函数中调用例如 User.prototype.setEmpId([userKey]);。这会将其称为原型对象的方法,而不是用户对象的方法。如果你想将本地函数作为方法调用,你可以使用formUserObjectFromArguments.call(this),这样你就可以在函数中调用this.setEmpId([userKey]);
【解决方案2】:

您没有访问它,因为它位于私有函数中。 试试这样:

function myClass() {
    function privateFunction () {

    }

    this.publicFunction = function() {
         alert('ok')
    }

}

如果你这样做了

var obj = new myClass()
obj.publicFunction()

你可以看到警报

为了继承这个类,你还需要一些其他的东西。这是一个完整的例子。

下面是相关的js代码。把它放在一个文件中测试它:

function Operators() {
    //mandatory
    var self = this

    //private
    var IPT_X = '#x'
    var IPT_Y = '#y'

    //public
    this.x = 0
    this.y = 0    

    this.showOperators = function() {
        //use of a private property (IPT_X) and a public property (this.x)
        $(IPT_X).val(this.x)
        $(IPT_Y).val(this.y)
    }

    this.clean = function() {
        this.x = 0
        this.y = 0
        // call to a local public method 
        this.showOperators()
    }

    this.updateOperators = function(_x, _y) {
        // use of a public property when call from
        // derived class method is necessary
        self.x = _x
        self.y = _y
    }
}

function Randomizer() {
    // mandatory for derived classes
    Operators.call(this)
    // mandatory for overloaded methods with call to the inherited method
    var parentUpdateOperators = this.updateOperators
    var self = this

    // private
    function getRandomNumber() {
        return Math.round(Math.random() * 1000)
    }

    // public
    this.updateOperators = function(_x, _y) {
            // call to inherited method of superior class
        parentUpdateOperators(_x, _y)
            // call to method of superior class
            self.showOperators()
    } 

    this.populateRandomNumbers = function() {
        // call to public local method (this.updateOperators())
        // and to a local private method (getRandomNumber())
        this.updateOperators(getRandomNumber(), getRandomNumber())
    }

    // init
    this.populateRandomNumbers()
}
// Mandatory for derived classes. Allows access to superior classes with
// more than 2 levels of inheritance ("grandfather" classes)
Randomizer.prototype = Object.create(Operators.prototype)

function Operations() {
    Randomizer.call(this)
    var self = this

    //private
    var IPT_RES = '#res'
    var BTN_SUM =  '#sum'
    var BTN_SUBTRACT =  '#subt'
    var BTN_MULTIPLY =  '#mult'
    var BTN_DIVISION =  '#div'
    var BTN_CLEAN =  '#clean'
    var BTN_RAND =  '#rand'

    function calcSum() {
        return self.x + self.y
    } 
    function calcSubtraction() {
        return self.x - self.y
    } 
    function calcMultiplication() {
        return self.x * self.y
    } 
    function calcDivision() {
        return self.x / self.y
    } 

    function showRes(val) {
        $(IPT_RES).val(val)
    }

    //public
    this.sum = function() {
        // call to 2 local private methods
        showRes(calcSum())
    }
    this.subtract = function() {
        showRes(calcSubtraction())
    }
    this.multiply = function() {
        showRes(calcMultiplication())
    }
    this.division = function() {
        showRes(calcDivision())
    }

    // init
    $(BTN_SUM).on('click', function() { self.sum() })
    $(BTN_SUBTRACT).on('click', function() { self.subtract() })
    $(BTN_MULTIPLY).on('click', function() { self.multiply() })
    $(BTN_DIVISION).on('click', function() { self.division() })    
    $(BTN_CLEAN).on('click', function() { self.clean() })
    $(BTN_RAND).on('click', function() { self.populateRandomNumbers() })
}
Operations.prototype = Object.create(Randomizer.prototype)

var obj = new Operations()

如果你要测试,这里是 html 代码:

X: <input id='x'>
<br>
Y: <input id='y'>
<br>
Res: <input id='res'>
<br>
<input id='sum' type='button' value='+'>
<input id='subt' type='button' value='-'>
<input id='mult' type='button' value='*'>
<input id='div' type='button' value='/'>
<input id='clean' type='button' value='C'>
<input id='rand' type='button' value='Rand'>

不要忘记添加 jquery 文件。

这是一个 JSFiddle,其中包含该代码:

http://jsfiddle.net/vqqrf2cb/24/

【讨论】:

  • 当我尝试继承这个类时,这不会解决问题。对不起!不值得。我最初尝试过这个。告诉我原型。
  • 要继承该类,您需要在继承的类中添加一些其他行。等一下,我给你举了一个完整的例子。
  • 检查我在示例中放置的 jsfiddle
【解决方案3】:

试试这个:

function myClass() {
  function privateFunction(obj) {
    obj.privilegedFunction1();
  };
  this.privilegedFunction1 = function () {
    this.variable = 1;
  };
  this.privilegedFunction2 = function () {
    privateFunction(this);
  };
}

myClass.prototype.publicFunction2 = function () {
    return this.variable;
}

var test = new myClass();
test.privilegedFunction2();
console.log(test.publicFunction2());

还有这个:

function myClass() {
  function privateFunction(obj) {
    obj.publicFunction1();
  };
  this.privilegedFunction2 = function () {
    privateFunction(this);
  };
}

myClass.prototype.publicFunction1 = function () {
  this.variable = 1;
}

myClass.prototype.publicFunction2 = function () {
    return this.variable;
}

var test = new myClass();
test.privilegedFunction2();
console.log(test.publicFunction2());

您可能想阅读一些关于 Javascript 中的公共、私人和特权成员的信息。喜欢这篇文章:http://javascript.crockford.com/private.html

关键点:

  1. 公共(原型)成员无权访问私有。
  2. 特权 (this) 成员可以访问私有。
  3. 私有函数可以通过传递的上下文参数访问特权和公共成员。

【讨论】:

    【解决方案4】:

    关闭还不够吗?

    首先,按照惯例,我将 myClass 重命名为 MyClass

    function MyClass() {
        var myInstance = this;
    
        function privateFunction () {
            // closure 
            myInstance.publicFunction();
        }
    }
    
    MyClass.prototype.publicFunction = function() {
        this.variable = 1;
    }
    MyClass.prototype.publicFunction2= function() {
        return this.variable;
    }
    

    现在你应该可以用这种方式实例化它了

    var myInstance = new MyClass();
    

    现在你可以看到privateFunction 从未被调用过,调用它有点多余,但我只是试图展示如何在技术上实现它。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2015-10-10
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2017-08-21
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多