ES6标准---【六】【学习ES6标准看这一篇就够了!!!】

目录

以往ES6文章

前言

对象属性的简洁表示法

一个实际例子

简介写法在打印对象时也很有用

注意

对象属性名表达式

用表达式做属性名

用表达式定义方法名

注意

对象方法的name属性

对象属性的可枚举性和遍历

可枚举性

属性的遍历

属性比那里次序规则

super关键字

注意

对象的链判断运算符

链判断运算符的用法

链判断运算符的机制

短路机制

delete运算符

括号的影响

报错场合

右侧不得为十进制数值

NULL判断符

NULL判断符的作用

NULL的问题

以往ES6文章

ES6标准---【一】【学习ES6看这一篇就够了!!】-CSDN博客

ES6标准---【二】【学习ES6看这一篇就够了!!】-CSDN博客

ES6标准---【三】【学习ES6看这一篇就够了!!!】-CSDN博客 

ES6标准---【四】【学习ES6标准看这一篇就够了!!!】_es6 有arguments 吗-CSDN博客

ES6标准---【五】【看这一篇就够了!!!】-CSDN博客

前言

ES6标准对“对象”进行了扩展

对象属性的简洁表示法

ES6允许在大括号里面,直接写入变量和函数,作为对象的属性和方法

  • 直接写入变量时:变量名做键,变量值做键值
  • 直接写入函数时,无需添加“:”(冒号)
const foo = 'bar';
const baz = {foo};
baz // {foo: "bar"}
// 等同于
const baz = {foo: foo};

function f(x, y) {
  return {x, y};
}
// 等同于
function f(x, y) {
  return {x: x, y: y};
}
f(1, 2) // Object {x: 1, y: 2}

一个实际例子

let birth = '2000/01/01';
const Person = {
  name: '张三',
  //等同于birth: birth
  birth,
  // 等同于hello: function ()...
  hello() { console.log('我的名字是', this.name); }
};

简介写法在打印对象时也很有用

let user = {
  name: 'test'
};
let foo = {
  bar: 'baz'
};
console.log(user, foo)
// {name: "test"} {bar: "baz"}
console.log({user, foo})
// {user: {name: "test"}, foo: {bar: "baz"}}

如果console.log直接输出“user”和“foo”两个对象时,就是两组键值对,可能会混淆

但是如果把它们放在大括号里面输出,就变成了对象的简洁表示每组键值对前面会打印对象名,这样就比较清晰了

注意

简写的对象方法不能用作构造函数,会报错

const obj = {
  f() {
    this.foo = 'bar';
  }
};
new obj.f() // 报错

对象属性名表达式

JavaScript定义对象的属性,有两种方法:

  • 直接用标识符作属性名
  • 用表达式做属性名(需要将表达式放在方括号内)
// 方法一
obj.foo = true;
// 方法二
obj['a' + 'bc'] = 123;

用表达式做属性名

ES6允许字面量定义对象时,用方法二(表达式)作为对象的属性名,即把表达式放在“方括号”内

let propKey = 'foo';
let obj = {
  [propKey]: true,
  ['a' + 'bc']: 123
};
  • 用变量做属性名时,可以使用变量名变量值来检索对象
let lastWord = 'last word';
const a = {
  'first word': 'hello',
  [lastWord]: 'world'
};
a['first word'] // "hello"
a[lastWord] // "world"
a['last word'] // "world"

用表达式定义方法名

let obj = {
  ['h' + 'ello']() {
    return 'hi';
  }
};
obj.hello() // hi

注意

  • 属性名表达式与简洁表示法不能同时使用,会报错
// 报错
const foo = 'bar';
const bar = 'abc';
const baz = { [foo] };
// 正确
const foo = 'bar';
const baz = { [foo]: 'abc'};
  • 属性名表达式如果是一个对象,默认情况下会自动将对象转为字符串“[obejct Object]
const keyA = {a: 1};
const keyB = {b: 2};
const myObject = {
  [keyA]: 'valueA',
  [keyB]: 'valueB'
};
myObject // Object {[object Object]: "valueB"}

对象方法的name属性

对象方法也是函数,因此也有name属性

const person = {
  sayName() {
    console.log('hello!');
  },
};
person.sayName.name   // "sayName"
  • 如果对象的方法使用了取值函数(getter)和存值函数(setter),则name的返回值是“方法名前加上get set
const obj = {
  get foo() {},
  set foo(x) {}
};
obj.foo.name
// TypeError: Cannot read property 'name' of undefined
const descriptor = Object.getOwnPropertyDescriptor(obj, 'foo');
descriptor.get.name // "get foo"
descriptor.set.name // "set foo"
  • bind创造的函数name属性返回“bound 加上原函数名字”,Function构造函数name返回anonymous
(new Function()).name // "anonymous"
var doSomething = function() {
  // ...
};
doSomething.bind().name // "bound doSomething"

对象属性的可枚举性和遍历

可枚举性

对象的每个属性都有一个描述对象,用来控制该属性的行为

  • Obejct.getOwnPropertyDesciptor:获取该属性的描述对象
let obj = { foo: 123 };
Object.getOwnPropertyDescriptor(obj, 'foo')
//  {
//    value: 123,
//    writable: true,
//    enumerable: true,
//    configurable: true
//  }

描述对象的“enumrable”属性,称为“可枚举性”,如果该属性为false,就表示某些操作会忽略当前属性

有四个操作会忽略enumerablefalse的属性

  • for...in循环:只遍历对象自身的和可继承的可枚举的属性
  • Obejct.keys():返回对象自身的所有可枚举的属性的键名
  • JSON.stringfy():只串行化对象自身的可枚举的属性
  • Object.assign():忽略enumerable为false的属性,只拷贝对象自身的可枚举的属性

属性的遍历

ES6中一共有五种方法可以遍历对象的属性

  • for...in:循环遍历对象自身的和继承的可枚举属性(不含Symbol属性)
  • Object.keys(obj):返回一个数组,包括对象自身的(不含继承的)所有可枚举属性(不含Symbol属性)的键名
  • Object.getOwnPropertyNames(obj):返回一个数组,包含对象自身的所有属性(不含Symol属性)的键名
  • Obejct.getOwnPropertySymbols(obj):返回一个数组,包含对象自身的所有Symbol属性的键名
  • Reflect.ownKeys(obj):返回一个数组,包含对象自身的(不含继承的)所有键名,不管键名是否是Symbol或字符串,也不管是否可枚举
<body>
	<script>
		let obj = {
			"name": "yy",
			"age": 123
		}
		for(let i in obj) {
			console.log(i);
		}
		console.log("Object.keys:",Object.keys(obj));
		console.log("Object.getOwnPropertyNames:",Object.getOwnPropertyNames(obj));
		console.log("Object.getOwnPropertySymbols:",Object.getOwnPropertySymbols(obj));
		console.log("Reflect.ownKeys:",Reflect.ownKeys(obj));
	</script>	
</body>

效果:

 

属性比那里次序规则

ES6中的五种方法遍历对象的键名,都遵守同样的属性遍历的次序规则:

  • 首先遍历所有数值键,按照数值升序排列
  • 其次遍历所有字符串键,按照加入事件升序排列
  • 最后遍历所有Symbol键,按照加入时间排列
Reflect.ownKeys({ [Symbol()]:0, b:0, 10:0, 2:0, a:0 })
// ['2', '10', 'b', 'a', Symbol()]

super关键字

super指向当前对象的原型对象(父亲)

const proto = {
  foo: 'hello'
};
const obj = {
  foo: 'world',
  find() {
    return super.foo;
  }
};
Object.setPrototypeOf(obj, proto);
obj.find() // "hello"

注意

super关键字指向原型对象时,只能用在对象的方法之中,用在其他地方都会报错

// 报错
const obj = {
  foo: super.foo
}
// 报错
const obj = {
  foo: () => super.foo
}
// 报错
const obj = {
  foo: function () {
    return super.foo
  }
}

对象的链判断运算符

ES6增加了“?.”运算符,直接在链式调用的时候判断,左侧的对象是否为NULLundefined,如果是就不再往下运算,而是返回undefined

链判断运算符的用法

链判断运算符有三种用法:

  • obj?.prop:对象属性
  • obj?.[expr]:对象属性
  • obj(function)?.(...args):函数或对象方法的调用
a?.b
// 等同于
a == null ? undefined : a.b
a?.[x]
// 等同于
a == null ? undefined : a[x]
a?.b()
// 等同于
a == null ? undefined : a.b()
a?.()
// 等同于
a == null ? undefined : a()

注意点:

  • 如果a?.b()里面a.b不是函数,或不可调用,那么会报错
  • 如果a?.()也是如此,如果a不是null或undefined,也不是函数,那么会报错

链判断运算符的机制

短路机制

如果对象是undefinednull,那么不会执行后面的表达式

a?.[++x]
// 等同于
a == null ? undefined : a[++x]

delete运算符

如果对象是undefinednull,会直接返回undefined,而不会进行delete运算

delete a?.b
// 等同于
a == null ? undefined : delete a.b

括号的影响

如果属性链有圆括号,链判断运算符对圆括号外部没有影响,只对圆括号内部有影响

(a?.b).c
// 等价于
(a == null ? undefined : a.b).c

报错场合

// 构造函数
new a?.()
new a?.b()
// 链判断运算符的右侧有模板字符串
a?.`{b}`
a?.b`{c}`
// 链判断运算符的左侧是 super
super?.()
super?.foo
// 链运算符用于赋值运算符左侧
a?.b = c

右侧不得为十进制数值

foo?.3:0会被解析成foo ? .3 : 0(三元运算符),因此规定?.不能紧跟一个十进制数字

NULL判断符

ES6引入一个新的NULL判断符“??”,它的行为类似“||”,但是只有运算符左侧的值为NULLundefined时,才会返回右侧的值

NULL判断符的作用

链判断运算符?>”配合使用,为nullundefined的值设置默认值

const animationDuration = response.settings?.animationDuration ?? 300;

NULL的问题

??”与“&&”或“||”不分优先级高低,两个或三个同时使用时,需要使用括号表明优先级,否则会报错

// 报错
lhs && middle ?? rhs
lhs ?? middle && rhs
lhs || middle ?? rhs
lhs ?? middle || rhs

//正确
(lhs && middle) ?? rhs;
lhs && (middle ?? rhs);
(lhs ?? middle) && rhs;
lhs ?? (middle && rhs);
(lhs || middle) ?? rhs;
lhs || (middle ?? rhs);
(lhs ?? middle) || rhs;
lhs ?? (middle || rhs);

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

是洋洋a

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值