Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

JavaScript 面向对象 #5

Open
K-Kevin opened this issue Oct 9, 2019 · 0 comments
Open

JavaScript 面向对象 #5

K-Kevin opened this issue Oct 9, 2019 · 0 comments

Comments

@K-Kevin
Copy link
Owner

K-Kevin commented Oct 9, 2019

JavaScript 对象的特征

参考Grandy Booch《面向对象分析与设计》,对象有如下几个特点:

  • 对象具有唯一标识性:即使完全相同的两个对象,也并非同一个对象。

  • 对象有状态:对象具有状态,同一对象可能处于不同状态之下。

  • 对象具有行为:即对象的状态,可能因为它的行为产生变迁。

先来看第一个特征,对象有唯一标识性。一般而言,各种语言的对象唯一标识性都是内存地址来提现的。

JavaScript 我们知道,任何不同的对象其实是不相等的,以下代码:

    var o1 = { a: 1 };
    var o2 = { a: 1 };
    console.log(o1 == o2); // false

再看第二个和第三个特征:状态和行为,不同语言会有不同的描述方式,C++ 中就称作:”成员变量“ 和 ”成员函数“,而 Java 中则称作:”属性“ 和 ”方法“。

在 JavaScript 中,将状态和行为统一抽象为 ”属性“(JavaScript 中将函数设计成一种特殊对象),所以 JavaScript 中的行为和状态都能用属性来抽象。

对于下面代码,JavaScript 来说,d 和 f 就是两个普通属性。

    var o = { 
        d: 1,
        f() {
            console.log(this.d);
        }    
    };

尽管和 Java、C++ 相比较,设计思路上有一定的差别,但是 JavaScript 很好的表现了对象的基本特征。

JavaScript对象的两类属性

对于 JavaScript 来说,属性并非只是简单的名称和值,JavaScript 用一组特征(attribute)来描述属性(property)。

数据属性

先来说第一类属性,数据属性。

它比较接近于其它语言的属性概念。数据属性具有四个特征:

  • value:属性的值
  • writable:决定属性能否被赋值
  • enumerable:决定for in能否枚举该属性
  • configurable:决定该属性能否被删除或者改变特征值

在大多数情况下,我们只关心数据属性的值即可。

访问器(getter/setter)属性

它也有四个特征:

  • getter:函数或undefined,在取属性值时被调用
  • setter:函数或undefined,在设置属性值时被调用
  • enumerable:决定for in能否枚举该属性
  • configurable:决定该属性能否被删除或者改变特征值

访问器属性使得属性在读和写时执行代码,它允许使用者在写和读属性时,得到完全不同的值。

看下面代码:

    //writeable、enumerable、configurable 默认值为true
	var o = { a: 1 };
    o.b = 2;
    //a 和 b 皆为数据属性
    Object.getOwnPropertyDescriptor(o,"a") // {value: 1, writable: true, enumerable: true, configurable: true}
    Object.getOwnPropertyDescriptor(o,"b") // {value: 2, writable: true, enumerable: true, configurable: true}

如果我们要改变属性的特征,或者定义访问器属性,可以使用 Object.defineProperty,示例如下:

    var o = { a: 1 };
    Object.defineProperty(o, "b", {value: 2, writable: false, enumerable: false, configurable: true});
    //a 和 b 都是数据属性,但特征值变化了
    Object.getOwnPropertyDescriptor(o,"a"); // {value: 1, writable: true, enumerable: true, configurable: true}
    Object.getOwnPropertyDescriptor(o,"b"); // {value: 2, writable: false, enumerable: false, configurable: true}
    o.b = 3;
    console.log(o.b); // 2

在创建对象时,也可以使用 get 和 set 关键字来创建访问器属性,代码如下:

    var o = { 
        get a() { 
            return 1 
        } 
    };

    console.log(o.a); // 1

访问器属性和数据属性不同,每次访问属性都会执行 getter 和 setter 函数。这里我们 getter 返回了 1,所以每次 o.a 都得到 1。

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

1 participant