Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/scala/19.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Javascript 假人的getter\setter_Javascript_Setter_Getter - Fatal编程技术网

Javascript 假人的getter\setter

Javascript 假人的getter\setter,javascript,setter,getter,Javascript,Setter,Getter,我一直在试着让我的头脑围绕着接球手和二传手,但我并没有陷入其中。我读过,只是不明白 有人能清楚地说明: 一个能手和二传手应该做什么,以及 举一些非常简单的例子 我认为你链接到的第一篇文章非常清楚地说明了这一点: 以这种方式编写JavaScript的明显优势在于,您可以使用它来隐藏您不希望用户直接访问的值 这里的目标是通过只允许通过get()或set()方法访问字段来封装和抽象字段。通过这种方式,您可以以任何方式在内部存储字段/数据,但外部组件仅位于发布的接口之外。这允许您在不更改外部接口的情况下

我一直在试着让我的头脑围绕着接球手和二传手,但我并没有陷入其中。我读过,只是不明白

有人能清楚地说明:

  • 一个能手和二传手应该做什么,以及
  • 举一些非常简单的例子

  • 我认为你链接到的第一篇文章非常清楚地说明了这一点:

    以这种方式编写JavaScript的明显优势在于,您可以使用它来隐藏您不希望用户直接访问的值


    这里的目标是通过只允许通过
    get()
    set()
    方法访问字段来封装和抽象字段。通过这种方式,您可以以任何方式在内部存储字段/数据,但外部组件仅位于发布的接口之外。这允许您在不更改外部接口的情况下进行内部更改,在
    set()
    方法中执行一些验证或错误检查等。

    例如,您可以使用它们来实现计算属性

    例如:

    function Circle(radius) {
        this.radius = radius;
    }
    
    Object.defineProperty(Circle.prototype, 'circumference', {
        get: function() { return 2*Math.PI*this.radius; }
    });
    
    Object.defineProperty(Circle.prototype, 'area', {
        get: function() { return Math.PI*this.radius*this.radius; }
    });
    
    c = new Circle(10);
    console.log(c.area); // Should output 314.159
    console.log(c.circumference); // Should output 62.832
    

    如果您指的是访问器的概念,那么简单的目标就是隐藏底层存储,使其免受任意操作。最极端的机制是

    function Foo(someValue) {
        this.getValue = function() { return someValue; }
        return this;
    }
    
    var myFoo = new Foo(5);
    /* We can read someValue through getValue(), but there is no mechanism
     * to modify it -- hurrah, we have achieved encapsulation!
     */
    myFoo.getValue();
    

    如果您指的是实际的JS getter/setter特性,例如
    defineGetter
    /
    defineGetter
    ,或
    {get Foo(){/*code*/}}
    ,那么值得注意的是,在大多数现代引擎中,这些属性的后续使用将比其他情况慢得多。比较两种方法的性能

    var a = { getValue: function(){ return 5; }; }
    for (var i = 0; i < 100000; i++)
        a.getValue();
    
    var a={getValue:function(){return 5;};}
    对于(变量i=0;i<100000;i++)
    a、 getValue();
    
    vs

    var a={get value(){return 5;};}
    对于(变量i=0;i<100000;i++)
    a、 价值观;
    
    只有当您拥有类的私有属性时,getter和setter才真正有意义。由于Javascript并不像您通常认为的面向对象语言那样具有私有类属性,所以很难理解。下面是私有计数器对象的一个示例。这个对象的优点是内部变量“count”不能从对象外部访问

    var counter = function() {
        var count = 0;
    
        this.inc = function() {
            count++;
        };
    
        this.getCount = function() {
            return count;
        };
    };
    
    var i = new Counter();
    i.inc();
    i.inc();
    // writes "2" to the document
    document.write( i.getCount());
    
    如果您仍然感到困惑,请查看Crockford关于的文章。

    此外,setter还可以用于更新其他值

    function Name(first, last) {
        this.first = first;
        this.last = last;
    }
    
    Name.prototype = {
        get fullName() {
            return this.first + " " + this.last;
        },
    
        set fullName(name) {
            var names = name.split(" ");
            this.first = names[0];
            this.last = names[1];
        }
    };
    
    现在,您可以设置
    fullName
    first
    last
    将被更新,反之亦然

    n = new Name('Claude', 'Monet')
    n.first # "Claude"
    n.last # "Monet"
    n.fullName # "Claude Monet"
    n.fullName = "Gustav Klimt"
    n.first # "Gustav"
    n.last # "Klimt"
    

    我有一个给你们的,可能有点难看,但它确实可以跨平台完成

    function myFunc () {
    
    var _myAttribute = "default";
    
    this.myAttribute = function() {
        if (arguments.length > 0) _myAttribute = arguments[0];
        return _myAttribute;
    }
    }
    
    这样,当你打电话的时候

    var test = new myFunc();
    test.myAttribute(); //-> "default"
    test.myAttribute("ok"); //-> "ok"
    test.myAttribute(); //-> "ok"
    
    如果你真的想增加情趣。。您可以插入一种支票类型:

    if (arguments.length > 0 && typeof arguments[0] == "boolean") _myAttribute = arguments[0];
    if (arguments.length > 0 && typeof arguments[0] == "number") _myAttribute = arguments[0];
    if (arguments.length > 0 && typeof arguments[0] == "string") _myAttribute = arguments[0];
    

    或者更疯狂地使用高级支票:

    有什么让人困惑的呢。。。getter是在获取属性setter时调用的函数,设置属性setter时调用。 例如,如果你这样做了

    obj.prop = "abc";
    
    在设置属性prop时,如果使用getter/setter,则将调用setter函数,并将“abc”作为参数。 对象内的setter函数定义理想情况下如下所示:

    set prop(var) {
       // do stuff with var...
    }
    
    var user = { /* ... object with getters and setters ... */ };
    user.phone = '+1 (123) 456-7890'; // updates a database
    console.log( user.areaCode ); // displays '123'
    console.log( user.area ); // displays 'Anytown, USA'
    

    我不确定跨浏览器实现的效果如何。Firefox似乎还有另一种语法,带有双下划线的特殊(“魔术”)方法。像往常一样,Internet Explorer不支持这一切。

    您可以通过构造函数的原型为js类定义实例方法。

    以下是示例代码:

    // BaseClass
    
    var BaseClass = function(name) {
        // instance property
        this.name = name;
    };
    
    // instance method
    BaseClass.prototype.getName = function() {
        return this.name;
    };
    BaseClass.prototype.setName = function(name) {
        return this.name = name;
    };
    
    
    // test - start
    function test() {
        var b1 = new BaseClass("b1");
        var b2 = new BaseClass("b2");
        console.log(b1.getName());
        console.log(b2.getName());
    
        b1.setName("b1_new");
        console.log(b1.getName());
        console.log(b2.getName());
    }
    
    test();
    // test - end
    

    而且,这应该适用于任何浏览器,您也可以简单地使用nodejs来运行此代码。

    我也有点困惑,因为我试图将一个属性添加到我没有编写的现有原型中,因此替换原型似乎是错误的方法。因此,为了子孙后代,以下是我如何将
    last
    属性添加到
    Array

    Object.defineProperty(Array.prototype, "last", {
        get: function() { return this[this.length - 1] }
    });
    

    比添加函数IMHO稍微好一点。

    很抱歉重新提出一个老问题,但我想我可能会提供一些非常基本的示例和傻瓜式的解释。thusfar发布的其他答案中没有一个能像第一个例子那样说明语法,这是一个最基本的例子

    Getter:

    var settings = {
        firstname: 'John',
        lastname: 'Smith',
        get fullname() { return this.firstname + ' ' + this.lastname; }
    };
    
    console.log(settings.fullname);
    
    var address = {
        set raw(what) {
            var loc = what.split(/\s*;\s*/),
            area = loc[1].split(/,?\s+(\w{2})\s+(?=\d{5})/);
    
            this.street = loc[0];
            this.city = area[0];
            this.state = area[1];
            this.zip = area[2];
        }
    };
    
    address.raw = '123 Lexington Ave; New York NY  10001';
    console.log(address.city);
    
    。。。当然,我们将记录约翰·史密斯的日志。getter的行为类似于变量对象属性,但提供了函数的灵活性,可以动态计算其返回值。这基本上是一种创建调用时不需要()的函数的奇特方法

    设置器:

    var settings = {
        firstname: 'John',
        lastname: 'Smith',
        get fullname() { return this.firstname + ' ' + this.lastname; }
    };
    
    console.log(settings.fullname);
    
    var address = {
        set raw(what) {
            var loc = what.split(/\s*;\s*/),
            area = loc[1].split(/,?\s+(\w{2})\s+(?=\d{5})/);
    
            this.street = loc[0];
            this.city = area[0];
            this.state = area[1];
            this.zip = area[2];
        }
    };
    
    address.raw = '123 Lexington Ave; New York NY  10001';
    console.log(address.city);
    
    。。。将
    newyork
    记录到控制台。与getter一样,setter的调用语法与设置对象属性的值相同,但这是另一种不用()调用函数的奇特方法

    请参阅以获得更全面、或许更实用的示例。将值传递到对象的setter会触发其他对象项的创建或填充。具体地说,在jsfiddle示例中,传递一个数字数组会提示setter计算平均值、中值、模式和范围;然后为每个结果设置对象属性。

    JavaScript中的getter和setter 概述 JavaScript中的getter和setter用于定义计算属性或访问器。计算属性是使用函数获取或设置对象值的属性。基本理论是这样做的:

    set prop(var) {
       // do stuff with var...
    }
    
    var user = { /* ... object with getters and setters ... */ };
    user.phone = '+1 (123) 456-7890'; // updates a database
    console.log( user.areaCode ); // displays '123'
    console.log( user.area ); // displays 'Anytown, USA'
    
    这对于在访问属性时在后台自动执行操作非常有用,例如将数字保持在范围内、重新设置字符串格式、触发值已更改的事件、更新关系数据、提供对私有属性的访问等

    下面的示例显示了基本语法,尽管它们只是获取和设置内部对象值,而不做任何特殊的操作。在现实世界中,您可以修改输入和/或输出值以满足您的需要,如上所述

    获取/设置关键字 ECMAScript 5支持定义计算属性的
    get
    set
    关键字。他们工作
    var foo = {
        _a : 123, _b : 456, _c : 789,
        getA : function(){ return this._a; },
        getB : ..., getC : ..., setA : ..., setB : ..., setC : ...
    };
    
    var foo = { _bar : 123 };
    Object.defineProperty( foo, 'bar', {
        get : function(){ return this._bar; },
        set : function( value ){ this._bar = value; }
    } );
    foo.bar = 456;
    var gaz = foo.bar;
    
    var foo = { _bar : 123; }
    foo.__defineGetter__( 'bar', function(){ return this._bar; } );
    foo.__defineSetter__( 'bar', function( value ){ this._bar = value; } );
    
    var employee = {
        first: "Boris",
        last: "Sergeev",
        get fullName() {
            return this.first + " " + this.last;
        },
        set fullName(value) {
            var parts = value.toString().split(" ");
            this.first = parts[0] || "";
            this.last = parts[1] || "";
        },
        email: "boris.sergeev@example.com"
    };
    
    console.log(employee.fullName); //Boris Sergeev
    employee.fullName = "Alex Makarenko";
    
    console.log(employee.first);//Alex
    console.log(employee.last);//Makarenko
    console.log(employee.fullName);//Alex Makarenko