兼收并蓄 TypeScript - 类: object

源码 https://github.com/webabcd/TypeScriptDemo
作者 webabcd

兼收并蓄 TypeScript - 类: object

示例如下:

class\object.ts

{
    // 定义对象时省略属性名
    const name = "webabcd";
    const age = 40;
    const a = {name, age}; // 定义对象时省略属性名(其属性名默认为变量名称)
    const b = {name: name, age: age}; // 这是 es5 写法,等价于上面的
    console.log(`${JSON.stringify(a)}, ${JSON.stringify(b)}, ${b.name}, ${b["name"]}`);
    // {"name":"webabcd","age":40}, {"name":"webabcd","age":40}, webabcd, webabcd


    // 定义对象的方法时,可以省略 function 关键字或者使用 lambda 表达式
    const c = {
        helloOld:function() { // 这是 es5 写法,等价于下面的
            return "hello";
        },
        helloNew() { // 定义对象的方法时,可以省略 function 关键字
            return this.helloOld(); // 注:这里的 this 指向的是对象本身(因为 this 的值是在运行时确定的,所以其指向了对象本身)
        },
        helloLambda: () => { // 定义对象的方法时,可以使用 lambda 表达式
            return c.helloOld();  // 注:在 lambda 表达式中,这里如果用 this 则其指向的是全局对象,而不是对象本身(因为 lambda 表达式中,this 的值是在定义时确定的,所以其指向了全局对象)
        }
    }
    console.log(`${c.helloOld()}, ${c.helloNew()}, ${c.helloLambda()}`);
    // hello, hello, hello


    // 对象的 getter 和 setter
    const d = {
        _name: "webabcd",
        get name() { // getter 和 setter 的写法
            return this._name;
        },
        set name(val) {
            this._name = val;
        },
    }
    d.name = "wanglei";
    console.log(d.name);
    // wanglei


    // 使用表达式来定义属性名或方法名
    let stringHello = "hello";
    const e = {
        [stringHello + "2"]() { // 使用表达式定义方法名
            return "hello";
        }
    }
    const f = { // 使用表达式定义属性名
        [stringHello + "2"]: "hello"
    };
    console.log(`${e.hello2()}, ${f.hello2}`);
    // hello, hello


    // 合并对象(重名的后面会覆盖前面)
    let o1 = {k1: "aaa", k2: "bbb"};
    let o2 = {k2: "ddd", k4: "eee"};
    let g = {...o1, k3: "ccc", ...o2};
    console.log(`${JSON.stringify(g)}`);
    // {"k1":"aaa","k2":"ddd","k3":"ccc","k4":"eee"}


    // 通过 Object.assign(target, source_1, source_2, ...) 合并对象(重名的后面会覆盖前面)
    // 为指定的类添加指定的方法,请参看 /es6/class/main.js 中的 Object.assign 部分
    let h = {k1: "aaa", k2: "bbb"};
    let o3 = {k3: "ccc"};
    let o4 = {k2: "ddd", k4: "eee"};
    Object.assign(h, o3, o4);
    console.log(`${JSON.stringify(h)}`);
    // {"k1":"aaa","k2":"ddd","k3":"ccc","k4":"eee"}


    // Object.is(value1, value2) 判断两个值是否相等
    console.log(`${Object.is({}, {})}, ${-0 === +0}, ${Object.is(-0, +0)}, ${Object.is(0, 0)}, ${Object.is(NaN, NaN)}`);
    // false, true, false, true, true


    // 定义对象,设置或获取 key/value
    // "xxx" in obj - 判断 obj 里是否有名为 xxx 的 key
    let o5 = {k1: "aaa", k2: "bbb"};
    o5["k1"] = "ddd";
    // Object.defineProperty()/Object.defineProperties() - 扩展对象的属性
    Object.defineProperty(o5, "p1", {
        value: "v1",
        writable: true, // 可写(默认值为 false)
        enumerable: true // 可枚举(默认值为 false)
    });
    Object.defineProperties(o5, {
        'p2': {
            value: "v2",
            writable: true, // 可写(默认值为 false)
            enumerable: false // 可枚举(默认值为 false)
        },
        'p3': {
            value: "v3",
            writable: true, // 可写(默认值为 false)
            enumerable: false // 可枚举(默认值为 false)
        }
    });
    // Object.keys() - 遍历指定对象的 key(只能遍历可枚举的)
    let keys = Object.keys(o5);

    // Object.getOwnPropertyNames() - 遍历对象的属性名(无论是否可枚举,均可遍历)
    let names = Object.getOwnPropertyNames(o5);
    console.log(keys); // ['k1', 'k2', 'p1']
    console.log(names); //  ['k1', 'k2', 'p1', 'p2', 'p3']
    console.log(o5.k1, "k1" in o5, "p9" in o5); // aaa true false


    // 说说 call(), apply(), bind() - 均用于调用的时候修改 this 的指向
    let o6 = {
        name: "webabcd",
        age: 40,
        hello(p1:string, p2:string) {
            console.log(`name:${this.name}, age:${this.age}, p1:${p1}, p2:${p2}`);
        }
    };
    o6.name = "wanglei";
    // hello() 中的 this 指向的是 o6
    o6.hello("a", "b"); // name:wanglei, age:40, p1:a, p2:b
    let o7 = {
        name: "wanglei",
        age: 20,
    };
    // call(thisObj,arg1,arg2,arg3,……) - hello() 中的 this 指向的是 call() 的第 1 个参数
    o6.hello.call(o7, "x", "y"); // name:wanglei, age:20, p1:x, p2:y
    // apply(thisObj,argArr) - hello() 中的 this 指向的是 apply() 的第 1 个参数
    o6.hello.apply(o7, ["x", "y"]); // name:wanglei, age:20, p1:x, p2:y
    // bind(thisObj,arg1,arg2,arg3,……) - hello() 中的 this 指向的是 bind() 的第 1 个参数(bind() 返回的是一个函数,要拿到结果需要再“()”一下,其他与 call() 一样)
    o6.hello.bind(o7, "x", "y")(); // name:wanglei, age:20, p1:x, p2:y


    // preventExtensions() - 禁止指定对象添加新属性
    // Object.preventExtensions(o8);

    // isExtensible() - 是否可为指定对象添加新属性,默认为 true,如果调用了 preventExtensions() 则此值为 false
    // Object.isExtensible(o8);

    // Object.seal() - 先调用 preventExtensions(),再将对象的所有属性标记为 configurable:false
    // Object.seal(o8);

    // Object.freeze() - 先调用 seal(),再将对象的所有属性标记为 writable:false
    // Object.freeze(o8);

    // 注:能用 Reflect 的方法就用 Reflect 的,而不要再用 Object 的了


    // 对象的解构赋值(destructuring)
    // 将值赋给同属性名指向的变量
    let {a: x1, b: x2} = {a: "aaa", b: "bbb"};
    console.log(x1, x2); // aaa bbb
    // 下面这句是简写,写全了就是 let {x3: x3, x4: x4} = {x3: "aaa", x4: "bbb"};
    let {x3, x4} = {x3: "aaa", x4: "bbb"};
    console.log(x3, x4); // aaa bbb
    // 带默认值的
    let {a: x5 = 1, b: x6 = 2} = {a: 3};
    console.log(x5, x6); // 3 2
    // 下面这句是简写,写全了就是 let {x7: x7 = 1, x8: x8 = 2} = {x7: 3};
    let {x7 = 1, x8 = 2} = {x7: 3};
    console.log(x7, x8); // 3 2
    // 未被解构的都放入 ... 标记的变量
    let {y1, y2, ...yyy} = {y5: 5, y1: 1, y2: 2, y3: 3, y4: 4};
    console.log(y1, y2, yyy); // 1 2 {y5: 5, y3: 3, y4: 4}
}

// es2017 新特性
{
    let d = {k1: "aaa", k2: "bbb"};
    // Object.values() - 遍历指定对象的 value(只能遍历可枚举的)
    let values = Object.values(d);
    // Object.entries() - 遍历指定对象的 key/value(只能遍历可枚举的)
    let entries = Object.entries(d);
    console.log(values); // ['aaa', 'bbb']
    console.log(entries); // [["k1", "aaa"], ["k2", "bbb"]]
}

源码 https://github.com/webabcd/TypeScriptDemo
作者 webabcd

posted @ 2024-09-20 12:19  webabcd  阅读(8)  评论(0编辑  收藏  举报