# ownPropertyFlags(obj)

[JS](../../../..) ⟩ [values](../../..) ⟩ [object](../..) ⟩ [property](..) ⟩ [flag]() ⟩ ownPropertyFlags()

{% tabs %}
{% tab title="💾 程式" %}
* [replit](https://replit.com/@pegasusroe/JS-object-ownPropertyFlags#index.js)
* requires： [isclass](../../../type/type-functions/isclass "mention"), [typename](../../../type/name/typename "mention")

```javascript
// Dependencies:
// 🔸 ownPropertyFlags --> typeName --> isClass

"use strict";

const { log } = console;

// table of own property flags
// 🔸 require: typeName()
function ownPropertyFlags(obj, {
    showFooter = true,
    objectName = null,
} = {}) {

    // padding between columns
    const pad = '   ';

    // convert descriptor (object) into string.
    function descripterToString(prop, descriptor, propNameColWidth) {

        const on = 'v', off = '.', icon = '🔸';

        let result = icon + prop.padEnd(propNameColWidth + 2, ' ') + pad;
        result += (descriptor.writable ? on : off) + ' ';
        result += (descriptor.enumerable ? on : off) + ' ';
        result += (descriptor.configurable ? on : off);
        result += pad;

        // check "value"
        const value = descriptor.value;
        switch (typeof value) {
            case 'function':
                result += `${value.name || '[no name]'} (${typeName(value)})`;
                break;
            default:
                result += `${value}`;
        }

        return result
    }

    // get all (own) property descriptors
    const descriptors = Object.getOwnPropertyDescriptors(obj);
    // get all property names
    const keys = Object.getOwnPropertyNames(descriptors);
    // property name column width
    const keyColumnWidth = Math.max(...keys.map(key => key.length));

    // map all descriptors into array of strings
    const lines = keys
        .map(key => descripterToString(key, descriptors[key], keyColumnWidth));

    // calculate table width
    const tableWidth = Math.max(...lines.map(line => line.length));

    // compose table content
    const divider = '-'.repeat(tableWidth) + '\n';
    const title = `${objectName || obj.name || '[no name]'} (${typeName(obj)})\n`;
    const header = '  property'.padEnd(keyColumnWidth + 4, " ")
        + pad + 'w e c' + pad + 'value\n';
    const footer = 'w: writable, e: enumerable, c: configurable\n';

    let tableContent = title + divider + header + divider
        + lines.join('\n') + '\n'
        + divider;

    if (showFooter) tableContent += footer;

    log(tableContent);
    return tableContent;
}
```
{% endtab %}

{% tab title="💈範例" %}
#### ⭐️ property flags of a [func](../../../func "mention")

```javascript
function F(name) {
  this.name = name;
}

ownPropertyFlags(F);
// F (function)
// ---------------------------------------
// property        w e c   value
// ---------------------------------------
// 🔸length        . . v   1
// 🔸name          . . v   F
// 🔸arguments     . . .   null
// 🔸caller        . . .   null
// 🔸prototype     v . .   [object Object]
// ---------------------------------------
// w: writable, e: enumerable, c: configurable
// ⭐ 注意： `F.prototype` 是 writable (可以被換掉)❗

// ⭐ every function has a default prototype
ownPropertyFlags(F.prototype, {
    showFooter: false, 
    objectName: 'F.prototype'
});
// F.prototype (object)
// --------------------------------------
//   property        w e c   value
// --------------------------------------
// 🔸constructor     v . v   F (function)
// --------------------------------------
```

#### ⭐️ property flags of a [class](../../../class "mention")

```javascript
class A {}

ownPropertyFlags(A, {showFooter: false});
// A (class)
// ---------------------------------------
//   property      w e c   value
// ---------------------------------------
// 🔸length        . . v   0
// 🔸name          . . v   A
// 🔸prototype     . . .   [object Object]
// ---------------------------------------
// ⭐ 注意：`A.prototype` 的 writable == false❗(不能被換掉❗)

ownPropertyFlags(A.prototype, {
    showFooter: false,
    objectName: 'A.prototype',
});
// A.prototype (object)
// -----------------------------------
//   property        w e c   value
// -----------------------------------
// 🔸constructor     v . v   A (class)
// -----------------------------------
```
{% endtab %}
{% endtabs %}
