JavaScript 实例函数与原型函数

IT技术 javascript syntax prototype-programming
2021-02-25 00:26:18

可能的重复:
在 Javascript 中使用“原型”与“这个”?

我对不同种类的 JavaScript 函数的理解如下:

function MyObj() {
    this.propOne = true;
    this.publicInstanceFunc = function() {
        if (propOne)
            return 'public instance function';
    }
    function privateFunc() {
        return 'private function only visible inside this constructor';
    }
}

MyObj.prototype.protoFunc = function() {
    if (this.propOne)
        return 'prototype function shared amongst all instances of MyObj';
}
  1. 这些正确吗?
  2. 在什么情况下应该将函数放在原型上(例如protoFunc)与构造函数中(例如publicInstanceFunc)?
  3. 是否使用this正确的方法访问原型函数内的属性?
4个回答

您实际上可以通过将整个事物包装在一个自执行函数中来添加另一个级别的权限:

var MyObj = (function() { // scoping
    var privateSharedVar = 'foo';

    function privateSharedFunction() {
        // has access to privateSharedVar
        // may also access publicSharedVar via explicit MyObj.prototype
        // can't be called via this
    }

    function MyObj() { // constructor
        var privateInstanceVar = 'bar';
        this.publicInstanceVar = 'baz';

        function privateInstanceFunction() {
            // has access to all vars
            // can't be called via this
        };

        this.publicInstanceMethod = function() {
            // has access to all vars
            // also known as a privileged method
        };
    }

    MyObj.prototype.publicSharedVar = 'quux';

    MyObj.prototype.publicSharedMethod = function() {
        // has access to shared and public vars
        // canonical way for method creation:
        // try to use this as much as possible
    };

    return MyObj;
})();

只能通过外部访问“公共”属性this

出于性能原因,您应该避免使用我所说的“实例”方法:对于这些方法中的每一个,必须为每个MyObject实例创建一个新的函数对象,而每个“共享”方法只有一个函数对象。

很抱歉重新提出这个问题/答案,但是将外部函数包装在括号中是否有什么特别之处?例如 (function(){ })(); 与 function(){}() 不同;
2021-04-25 00:26:18
@Matt:外部括号强制将函数文字解释为表达式而不是语句;在这种情况下它们是不必要的,因为赋值已经强制这种解释,但是如果没有它,如果省略括号,你应该得到一个语法错误
2021-04-25 00:26:18
一个较小的问题:回报不应该是return new MyObj();这就是我必须做的才能让它工作,但想让我没有破坏格式良好的代码。
2021-04-28 00:26:18
@scader:按原样,外部 varMyObj将保存构造函数并且可以这样使用(即通过 实例化对象new MyObj());如果您返回new MyObj(),则外部 var 将仅保存该特定实例
2021-05-07 00:26:18
感谢这个优秀的例子,克里斯托夫。如果您想在该命名空间中定义另一个对象,您会怎么做?例如,如果 MyObj 包含一个 MyObj2 的数组。您是否会将其定义为立即调用函数的一部分,以便它位于 MyObj 的命名空间内?
2021-05-12 00:26:18

这些正确吗?

呃。嗯,这取决于你想做什么。没有一种公认的规范模型可以在 JavaScript 中实现类/实例风格的继承。

但是这个:

    if (propOne)

可能是一个错误,因为它this.propOne是所有者对象的一个​​属性,而propOne它本身是一个尚未声明的变量(默认为全局变量,但通常是错误的)。

在什么情况下,应该将函数放在原型上(例如 protoFunc)还是在构造函数中(例如 publicInstanceFunc)?

原型上设置的函数与所有对象共享的函数相同。它可以确定它属于哪个实例的唯一方法是在调用它时读取“this”。

构造函数中在 'this' 上设置的函数是MyObj. 您可以使用 this 作为基于闭包而不是“this”绑定到所有者对象的替代方法,这样可以节省写出函数绑定的内容。这是一种不同的面向对象风格,通常您不会将其与基于 this 的风格混合。

1)是的,您的代码是正确的。

2)当我想访问在构造函数本身范围内私有定义的其他成员时,例如,当您想创建特权方法时,我使用构造函数中定义的函数

定义在构造函数上的公共函数比向对象原型添加简单函数的计算成本更高,但它们也为您提供了更大的灵活性。

3) 是的,如果该属性是公共的,您可以通过this在原型扩展函数中使用关键字来访问它,因为它this指的是您的对象的实例。

关于第二点,您扩展原型,以便所有已创建的对象都获得新方法。

此外,允许您向内置对象添加方法(如添加trim()string)。