【问题标题】:Problems with scope and JSON "class" methods范围和 JSON“类”方法的问题
【发布时间】:2014-06-10 04:40:51
【问题描述】:

我真的无法为我遇到的这个问题找到一个清晰简洁的答案 - 我什至不知道如何准确地表达它。但是我正在用Javascript(如果你愿意的话,是一个“类”)构建一个我可以重用的对象。我正在对对象使用 JSON 方法,因为这是我目前熟悉的唯一方法(我知道其他方法,但我还不能坐下来试验它们)。

所以,这是我正在做的一个例子:

var Thing = {
    'property':{
        'one':5,
        'two':3
    },
    'action':(function(arg1, arg2){
        alert(arg1 + ' ' + arg2);
        return this.property.one + this.property.two;
    });
}

var t = Thing;
alert(t.action('x', 'y'));

如您所见,我有我的对象,它有一些嵌套的属性。还有一个函数,它应该能够操纵所述属性。

我遇到的问题是范围。我试图找到一种方法来引用函数中对象的属性,而不假定属性属于该函数,因为它们不属于。我过去做过,我刚刚将“this”作为参数传递给函数,一切正常,但我敢打赌这不是一个好习惯。此外,如您所见,这个函数已经接受了一些参数。运行此代码会报错:“Uncaught TypeError: Cannot read property 'one' of undefined”。

我想保持我构建这个对象的方法完整——它是工作的东西,而且这个对象已经相当大了;但我正在寻找以某种方式“回到树上”来获取这些属性。

【问题讨论】:

  • JSON 在哪里?您似乎有一个对象初始化程序,甚至无法以您尝试过的方式重用。
  • Thing 不是JSON class - Thing 是一个对象
  • 为什么不把它定义为一个对象呢? var item = function(){/*这里的变量和函数 */}

标签: javascript json object scope


【解决方案1】:

你应该定义一个函数。

var Thing = function(){
    this.property = {"one":5, "two":3};
    this.action = function(arg1, arg2){/*....*/}
}

var y = new Thing();
alert(y.action("x","y"));

这就是我编写课程的方式。

正如另一个答案所说,看起来你有一个 ; 它不应该是

【讨论】:

  • 我会试试这个。我也必须为我糟糕的术语道歉。我有点混合使用“类”和“对象”这两个词。
  • 一个对象是一个类的实例,但在 Javascript 中一切都是一个对象。我写的将在运行时创建一个定义,然后用 new 调用它,每次都会创建它的一个新实例。 var x = new Thing(), y = new Thing(), z = new Thing();
【解决方案2】:

这行得通:

var Thing = {
    'property':{
        'one':5,
        'two':3
    },
    'action':(function(arg1, arg2){
        alert(arg1 + ' ' + arg2);
        return this.property.one + this.property.two;
    }) // here don't put a ';'
}

var t = Thing;
alert(t.action('x', 'y'));

【讨论】:

    【解决方案3】:

    你在这里直接初始化对象。您正在使用的 JSON 称为 object literal。顾名思义,它实际上是字面上定义的对象。

    现在让我们来解决您的问题。

    当您声明具有this.property.one 的函数时,this 关键字将在调用时解析。它通常是浏览器上的窗口对象。 Read on more this。所以它永远不会指向你的Thing。您可以做的是为该类定义一个函数并将函数添加到其原型中。这是在js中实现oop的经典方式。

    function Thing(){
        this.property = {one: 5, two: 3}
    }
    
    Thing.prototype.action = function(arg1, arg2){
        alert(arg1 + ' ' + arg2);
        return this.property.one + this.property.two;
    }
    

    【讨论】:

    • 我从来没有花时间感谢您的帮助。我最终混合了你的响应,以及另一个人的响应,以实现我正在寻找的效果,以创建一个可重用的“类”。再次感谢您。
    【解决方案4】:

    我有两个答案,一个使用您当前的 JSON 模型,另一个使用更 Javascript 的方式。

    答。

    当你这样定义事物时。

    var Thing = {
        'property':{
            'one':5,
            'two':3
        },
        'action':(function(arg1, arg2){
            alert(arg1 + ' ' + arg2);
            return this.property.one + this.property.two;
        })
    }
    

    你创建一个字面量,意思是每次你执行诸如

    之类的代码
    var t = Thing;
    

    您通过引用传递并且不在内存中创建新对象。因此,使用多个引用 Thing 的变量会产生问题。

    此外,您的问题源于关键字 this 是在运行时找到的,并且通常指的是浏览器窗口,除非 bind 命令指定。请记住,它必须始终是一个对象。字面量的本质是它不会改变通俗地说的 this 变量。

    B.

    现在以更好的方式解决这个问题。如您所说,可实例化的对象或类是像任何其他函数一样创建的。然而,它们是由关键字 new 实例化的。为了使用它们自己的引用,this 关键字代表当前作用域中派生最多的可实例化类。因此,您的示例最好这样写

    var Thing = function(){
        this.property = {};
        this.property.one = 5;
        this.property.two = 3;
    
        this.action = function Action(arg1, arg2){
            alert(arg1 + ' ' + arg2);
            return this.property.one + this.property.two;
        }
    }
    
    var t = new Thing();
    alert(t.action('x', 'y'));
    

    希望对你有帮助。

    此外

    你说

    我正在寻找某种方式“回到树上”

    虽然我不太确定您的意思是什么,但我推断如果到目前为止我所说的没有帮助,您的意思是您在对象中有对象。例如,假设您有一个 Student 类,其中还包含一个 Schedule 类。您可能希望从计划课程中访问学生数据。虽然这个例子很糟糕,因为按照设计,Schedule 实例不应该需要访问 Student 数据,如果需要,它应该通过函数参数传递,您也可以这样做。

    function Student(age){
        this.age = age;
        this.schedule = new Schedule(this);
    }
    
    function Schedule(parent){
        this.getAge = function(){return parent.age;}
    }
    
    var s = new Student(16);
    s.schedule.getAge();
    

    您可以简单地将父对象传递给子对象的实例并完成备份树的操作。

    【讨论】:

    • 这确实有帮助。谢谢你。我对这个项目的目标是实际创建一个对象,它可以被实例化并反复使用,有时一次不止一次。 “回到树上”只是我描述我的范围问题的笨拙方式。我想从对象的内部方法中获取对象的属性。看来我还有一点要学习 Javascript 对象。
    【解决方案5】:

    如果您需要一个生成不同对象的“类”,那么我认为您应该查看 shiplu.mokadd.im 的答案。然而,也许你需要一个模块,它有点像单例:

    var thing = (function() {
        var property = {
            one:5,
            two:3
        };
    
        function action(arg1, arg2){
            alert(arg1 + ' ' + arg2);
            return property.one + property.two;
        }
    
        return {
            action: action
        };
    })();
    
    alert(thing.action('x', 'y'));
    

    这里发生了什么:使用所谓的 IIFE - 立即调用函数表达式。无论 IIFE 返回什么(立即),它都会将其分配给 thing var - 所以在这种情况下,它会返回一个带有 action 函数的对象。

    为什么这很有用?它在 IIFE 内创建了一个作用域,它封装了你试图让thing 做的任何事情。它还创建“私有”函数和变量——你只需要return 你需要的东西——例如。 var propertything 之外不可见,并且您无法获得对 thing.property 的引用。

    希望这对您有所帮助!

    【讨论】:

      猜你喜欢
      • 2014-11-10
      • 2015-12-17
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2022-10-23
      • 1970-01-01
      • 2017-02-13
      • 2014-12-28
      相关资源
      最近更新 更多