【问题标题】:Define JavaScript get and set function in object without using "this"?在对象中定义 JavaScript 获取和设置函数而不使用“this”?
【发布时间】:2012-08-27 00:30:28
【问题描述】:

我有一个带有 get 和 set 函数的简单全局对象。 JSlint 不喜欢我在 get 和 set 函数中使用“this”,因为它违反了“use strict”。我会用什么替换“this”,这样它才不会违反“use strict”(即,我如何在不使用“this”的情况下引用“this”引用的同一事物)?

function fnDirty() {
    "use strict";
    var bIsdirty = false;

    this.get_bIsdirty = function() {return bIsdirty; };
    this.set_bIsdirty = function(x) {bIsdirty = x; };
}
var GV_oDirty = new fnDirty();

【问题讨论】:

  • 我的问题是为什么这和"use strict"有冲突?
  • jsLint 并没有抱怨你对this 的使用,而是真的抱怨你的类名格式错误。重命名 function Dirty() 的构造函数不会产生错误/警告。

标签: javascript this jslint getter


【解决方案1】:

按照惯例,构造函数以大写字母开头。如果您在构造函数中,JSLint 将允许在严格模式下使用 this,但您的函数以小写字母开头,因此它不会被识别为构造函数。

function FnDirty() {
    //your code
}

【讨论】:

  • 谢谢丹尼斯,好电话,JSlint 现在很满意。并不是说这以任何方式都需要,而是帮助我学习;什么是长手,调用相同行为的替代方法(我将用什么替换“this”以获得相同的结果)?
【解决方案2】:

回答你剩下的问题:“没有构造函数的迂回方式是什么?”

Brian 的想法是正确的 - 但他真正创建的是具有私有属性的单一对象,而不是工厂。

因此,为此,如果您想要一个函数,它为“类”的每个实例授予其私有属性的唯一副本,您可以这样做(我将说明一个实际的类,它比“Foo”和“Bar”,以更好地说明概念 - 将其重新组合成您的预期用途应该非常简单):

var makeWallet = function (starting_amount) {
    var amount = starting_amount,
        overdraft = 1000,
        addAmount = function (added_funds) { amount += added_funds; },
        deductAmount = function (extracted_amound) {
            if (is_sufficient_funds(amount, overdraft, extracted_amount)) {
                amount -= extracted_amount;
                return makeWallet(extracted_amount);
            }
        },
        // other needed public/helper methods here...
        // checkBalance(), is_sufficient_funds(), etc...
        public_interface = {
            // add all public-API methods you need here
            addFunds : addAmount,
            deductFunds : deductAmount
        };

     return public_interface;
};

现在,您有了一个返回对象的函数。每个对象都有访问该对象自己的“私有”(即:封闭)amount 变量的方法,该变量对于这些方法是唯一的,并且只能由这些方法访问。

无论您将函数构建为私有作用域中的 var,还是将它们构建为私有作用域中的函数声明,或者将它们直接放入 return { func1 : () {...},... }; 中,都无关紧要,只要它们是在该函数内部定义的它被调用(即:不在原型链上——无论如何你不能在这个模式中使用它——你会NOT)。

好的,一切都很好。你现在有了一个可以工作的钱包制造商(没有安全性和用户功能,yadda-yadda ... ...家庭作业)。

但是,如果您想向其中添加 PRIVATE STATIC 成员怎么办? 如果您需要跟踪序列号,以便向人们发行银行卡,该怎么办?或者您需要跟踪分支编号?这就是布赖恩的 IIFE 发挥作用的地方。除了返回完成的钱包对象之外,它将返回 wallet FACTORY

var makeWallet = (function () {
    var serial_num = 0,
        branch_num = "A011002z";
    function walletMaker = function (starting_amount) {
        /*same function as before, except that you ALSO call:
          serial_num += 1; in the construction of the wallet, and assign the id */
        var id = serial_num += 1;
        return wallet;
     }

     // then you return the wallet-factory
     // which becomes the new value of the outer function
     return walletMaker; 
}());

现在你已经有了静态属性(在最外面的闭包中,钱包工厂将作为“静态”成员永久访问),AND你具有基于实例的私有成员,在创建实例对象期间添加的内部方法将可以完全访问这些成员。

唯一的缺点是:

  1. 失去此特定类的原型能力,因为您没有使用构造函数。嗯。如果您的对象需要此设置,那么不值得拥有它...
    ...如果他们不这样做,并且 public-everything 很酷,那么只需使用构造函数和原型 - 或者只是构建内联对象,没有方法,并构建服务(函数)以对每个类似构建的对象进行操作.

  2. 如果您以这种方式构建所有对象,那么当您创建数千个或数万个这样的对象时,您将遭受内存损失,每个对象都有自己的函数副本(将私人参考)。同样,这是您为功能支付的价格。在必须使用安全/干净接口的地方进行内存打击,在不需要的地方不要这样做。

也不言而喻,但要避免在金融机构中使用它,因为面向客户的代码并不是信任添加和删除真钱的最佳场所...

希望能解决问题。

【讨论】:

    【解决方案3】:

    您可以使用另一种方法:

    var fnDirty = (function() {
      var _isDirty = false;
    
      return {
        get_dirty: function() { return _isDirty; },
        set_dirty: function(val) { _isDirty = value; }
      };
    
    })();
    

    【讨论】:

    • 但是fnDirty实际上并不是一个函数,你不能用new创建它的多个实例。
    猜你喜欢
    • 2017-05-26
    • 2017-09-08
    • 1970-01-01
    • 2017-08-20
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2010-10-29
    • 1970-01-01
    相关资源
    最近更新 更多