首页  >  问答  >  正文

javascript - 在类中,什么时候应使用属性,什么时候应使用方法?

在类的构建过程中,对于一个特定值的访问既可以使用属性也可以使用方法

例子:

//实现

//Point类,表示平面上的一个点
function Point(x,y){
    this.x = x;
    this.y = y;
    
    //距原点的距离,使用属性来实现
    Object.defineProperty(this,"distance",{
        get: function(){
            return Math.sqrt(this.x*this.x + this.y*this.y);
        }
    });
}

//距原点的距离,使用方法来实现
Point.prototype.getDistance = function(){
    return Math.sqrt(this.x*this.x + this.y*this.y);
}

//访问
var a = new Point(3,5);

//使用属性访问
Console.log(a.distance);

//使用方法访问
Console.log(a.getDistance());

问题:

高洛峰高洛峰2722 天前345

全部回复(2)我来回复

  • PHP中文网

    PHP中文网2017-04-11 12:47:18

    你这个问题其中在 Javaer 中已经讨论了很久了。Java Bean 为什么一定要用 getter 和 setter,讨论的就是这个问题。

    我这里只是简单的说一下,你可以自己去百度相关的资料。

    对于 Java 来说,就是属性和方法,通过 getXxxx() 和 setXxxx() 这两种方法来获取或设置属性的值。

    不过对于 js 来说,可以通过 Object.defineProperty 来定义属性,这个属性和原来直接 this.xxxx 的这个属性应该有所区别,所以通常会把 this.xxxxx 这个称为字段 (Field),而把 Object.defineProperty 定义的那个称为属性。由于 JS 有属性,所以不需要(但可以)申明 getter 和 setter 方法,反正作用是一样的。

    现在从 JS 的角度来说,所有会提到“字段”和“属性”。

    相比字段,属性有几个作用,其一就是保护字段。比如我定义了一个字段,这个字段的值只能在内部修改,而不能被外部调用者修改,那只需要定义对应的只读属性,也就是只有 getter 没有 setter 的属性即可。当然这在 JS 里还有点困难,因为 JS 没有实现私有成员,关于 JS 成员私有化的问题,可以参考 ES5 中模拟 ES6 的 Symbol 实现私有成员。由于字段被私有化,对应的属性又只提供了 getter,所以外部调用只能通过属性的 getter 获取字段值,而不能修改它,达到保护的目的。

    第二个作用是重载处理,这在 JS 里体现也不明显,因为 ES5 的继承实现确实有点麻烦。不过 ES6 在语法上已经支持了。具体点说,就是父类定义了一个属性,子类重载这个属性,改变了父类存取属性默认行为。比如说,父类的 name 属性对值没有限制,但是由于某种原因,需要父类类似的功能,但 name 不能为空,那可以从该父类继承,重载其 name 属性,在赋空值的自动修正,或报错。

    class A {
        get name() {
            return this._name;
        }
    
        set name(name) {
            this._name = name;
        }
    }
    
    class B extends A {
        get name() {
            return super.name;
        }
    
        set name(name) {
            super.name = name || "Anonymous";
        }
    }
    
    const b = new B();
    b.name = "";
    console.log(b.name);

    总的来说,字段一般作为内部保存数据用,不对外。如果需要对外,则通过属性来实现。这种设计模式对扩展很有好处。JavaScript 在这方面应用不是很多,如果你想参考,可以看看 C# 的属性和 Java 的 getter/setter 方法。

    回复
    0
  • 阿神

    阿神2017-04-11 12:47:18

    所谓的属性和方法只是叫法上的不同。方法可以是属性,属性也可以是方法。如下:

    function Point(x,y){
        this.x = x;
        this.y = y;
        this.z = function(){console.log(this.x);};
        
        //距原点的距离,使用属性来实现
        Object.defineProperty(this,"distance",{
            get: function(){
                return Math.sqrt(this.x*this.x + this.y*this.y);
            }
        });
    }
    
    //距原点的距离,使用方法来实现
    Point.prototype.getDistance = function(){
        return Math.sqrt(this.x*this.x + this.y*this.y);
    }
    
    //访问
    var p = new Point(3,5);
    'x' in p //true
    'getDistance' in p //true
    p.hasOwnProperty('getDistance'); //false这是这个方法的特性,不遍历原型链
    p.hasOwnProperty('distance'); //true
    p.hasOwnProperty('y');  //true
    p.hasOwnProperty('z');  //true
    

    只不过按前辈的经验来分,属性一般是一个值,可以获取,可以改变。而方法一般是一段可以执行的代码,可以操作属性值。外部调用时属性直接使用,方法需要(),予以执行。

    回复
    0
  • 取消回复