从零开始学_JavaScript_系列(38)——对象的扩展(1)属性的简洁写法

来源:互联网 发布:java http请求框架 编辑:程序博客网 时间:2024/06/05 11:14

对象的扩展

写在前面的话

感觉博客写的有点太细了,导致我学习进度过于缓慢。

因此,建议学习者以阮一峰博客为主,以本博客为补充。

我这里主要写一些示例和补充,帮助理解的更为全面

0、一句话总结

  1. 属性名,以及是属性的函数的简洁写法,写起来简单易阅读
  2. 属性名可以用变量字符串拼接起来(话说以前也有吧?)
  3. 函数都有name属性,但set和get也要加前缀
  4. Object.is判断两个变量是否相等
  5. Object.assign可以合并对象的非原型链上,且可枚举属性
  6. Object.getOwnPropertyDescriptor查看属性是否可枚举、可修改、可赋值
  7. Object.keys获取对象非原型链上,且可枚举属性的key
  8. Object.values获取对象非原型链上,且可枚举属性的值
  9. Object.entries同时获取上面两个
  10. 当属性在原型链上,或者不可枚举时,会被很多方法忽视(参照6.1)
  11. __proto__和prototype的关系(参照7.1)
  12. Object.setPrototypeOf(obj, prototype)设置__proto__属性
  13. Object.getPrototypeOf(obj)获取__proto__属性
  14. es7新增对对象有效的扩展运算符…(三个点)

本篇没有的请翻看【对象的扩展】系列的其他篇

1、简洁写法(缩写)

1.1、属性名缩写,与函数的缩写

属性名的缩写

var foo = "abc";var test = [];var bar = {    foo, test}//相当于var bar = {    foo: foo,    test: test}

函数缩写

var foo = {    fun(a, b){    }}//相当于var foo = {    fun: function (a, b) {    }}

因为缩写的属性名会总理解为字符串,所以,据说不会因为关键词而报错?(但我的chrome实测用关键词class作为key也不会报错啊)

,一个合格的程序员,不要去用关键词去做key,这可以避免很多本来不应该发生的bug。

1.2、错误的缩写

var p(){    console.log("p")}

以上这种缩写就不行,函数只有在作为属性的key时才能这么写。

1.3、setter和getter的简洁写法

讲真的!setter和getter用简洁写法写起来超级舒服啊!用正常写法超级麻烦,见代码:

简洁写法:

//简洁写法var cart = {    _wheels: 4,    get wheels() {        return this._wheels;    },    set wheels(value) {        if (value < this._wheels) {            throw new Error('数值太小了!');        }        this._wheels = value;    }}

正常写法:

var cart = {    _wheels: 4}Object.defineProperty(cart, "wheels", {    get: function () {        return this._wheels;    },    set: function (value) {        if (value < this._wheels) {            throw new Error('数值太小了!');        }        this._wheels = value;    }});

友情提示:

想把简洁写法用非正常写法来实现的,都是不可能的,我自己测试来看,以下写法都不行

//以下都不行var cart = {    _wheels: 4,    wheels: {        get() {            return this._wheels;        }    }}var cart = {    _wheels: 4,    wheels: function get() {        return this._wheels;    }}

2、属性名表达式

2.1、可以的写法

字符串变量可以作为key,并且作为key时也可以通过表达式来拼接。

let foo = {    //字符串作为key    ["test"] () {        console.log("test");    },    //一般用于key名拼接    ["b" + "ar"](){        console.log("bar");    }}

比较特殊的是,因为属性名是字符串,因此只要符合字符串格式的都可以作为key,但是获取该属性的值时,也只能通过字符串的形式来获取。

比较典型的就是属性名中间有空格这种情况。

2.2、不可以的写法

不能既用简洁写法,又用字符串变量作为key。

原因是简洁写法是将变量名作为变量在对象中的属性名

而用字符串变量作为key的简洁写法,和简洁写法的原意相反,是用 变量的值 作为 属性名,显然是不可以的。

而且也只有属性名,没有值。

let foo = "test";let bar = {    [foo]};//bar的可能let bar = {    ["test"]: ?   //只有key没有值}

2.3、不要用对象作为属性的key

原因是会被toString隐式转换为字符串,如示例:

···
var foo = {
toString(){
return “test foo”
}
};
var bar = {
[foo]: “bar”
}
bar[“test foo”] === “bar”; //true
···

默认情况下,隐式转换后的结果为:字符串 "[object Object]"

3、方法的name属性

3.1、普通写法的

跟之前函数的name属性的获取没啥区别,即使他是简写。如代码:

var foo = {    bar(){}}foo.bar.name;   //"bar",函数名

3.2、想要获取setter和getter的

话说获取这个有必要么?

setter和getter一般是变量,又不是函数,有必要获取他的名字么?不明白。

获取方法的话,先要通过API拿去它的属性描述符。

Object.getOwnPropertyDescriptor(obj, key)

以上方法返回一个对象,描述obj对象的属性key的属性,比如是否可编辑啊,是否可枚举啊之类(具体可能视属性有所不同);

var cart = {    _wheels: 4,    get wheels() {        return this._wheels;    },    set wheels(value) {        if (value < this._wheels) {            throw new Error('数值太小了!');        }        this._wheels = value;    }}var returnObject = Object.getOwnPropertyDescriptor(cart, "wheels");//Object {enumerable: true, configurable: true, get: function, set: function}returnObject.set.name;  //"set wheels"returnObject.get.name;  //"get wheels"

之所以能做到。首先是因为获取到了一个对象,而这个对象有set和get两个函数,而函数是可以获取到name属性的,又因为是set和get,所以name属性要加前缀”set”和”get”,就像bind绑定的函数里,前缀有”bound”一样。

除了以上三种前缀,匿名函数是name是”anonymous”。

除此之外还有Symbol,其name不同,不过我还没看,略略略。

阅读全文
0 0
原创粉丝点击