ES6学习笔记(8)----对象的扩展
参考书《ECMAScript 6入门》
http://es6.ruanyifeng.com/
对象的扩展
1.属性名的简洁表示法 : ES6允许在代码中直接写变量,变量名是属性名,变量值是属性值。
let key = "value";
let obj = {key};//obj {key : "value"}
2.方法的简写表示法
let obj = {
method : function(x,y){
return {x,y};//{x:x,y:y} 属性简写法在方法中的使用
}
}
同
let obj = {
method(x,y){
return {x,y};
}
}
3.属性表达式: obj[表达式]="value"
a.用{}定义对象时定义属性的两种方式
var obj = {
length : 3,
name : "test"
}//ES5的方式
let obj = {
["leng" + "th"] : 3,
["na"+"me"] : "test"
}//ES6的方式
function test2(){
return true;
}
function ["test" + 2](){
return true;
}报错
let ["test" + 4] = function(){}//报错
let ["test" + 4] = new Function(){}//报错
let obj = {
["test" + 4](){
return true;
}
}正确
obj //{test4: ƒ}
b.读取对象中属性的方式
obj.name
obj['name']
c.使用表达式定义属性的方式不可以与属性简写法混用
let a = 1;
let obj = {
["name"+1] : {[a]}//报错
}
let a = 1;
let obj = {
["name"+1] : {a}//正确
}
d.当表达式定义的属性名是一个对象时,表达式运行结果是[Object object],不是对象对应的属性名
let size = 3;
let clothes = {size};
let obj2 = {
["test" + obj] : "testagain"
}
obj2//{test[object Object]: "testagain"}
4.对象的name属性:对象里的方法的name属性返回方法所对应的方法名
a.如果是对象里的get方法或者set方法,则对象方法的name属性返回get/set + 函数名
let cat = {
age:1,
set mini(a){
this.age = age;
}
get mini(){
return this.age;
}
}
cat.mini.name //undefined
Object.getOwnPropertyDescriptor(cat,'mini').get.name //'get mini'
Object.getOwnPropertyDescriptor(cat,'mini').set.name//'set mini'
b.bind方法创造的对象的函数,name属性返回的是"bound" + 方法名
let obj = {
test(){}
}
obj.test.bind().name //"bound test"
c.使用new Function方法创建的函数,name属性返回的是"anonymous" + 方法名
(new Function()).name //"anonymous"
(new Function()).bind().name // "bound anonymous"
5.Object.is() //严格相等判断
相等判断
"==" //ES5
1 == '1' //true 即使1与'1'类型并不相同还是会判断它们相等,这是因为==引起了数据转换
"==="//ES5
1 === '1' //false 类型不同判断为false,比==规则更严格
undefined === undefined //true
null === null //true
NaN === NaN //false ===漏洞
+0 === -0 //true ===漏洞
Object.is(a,b) //ES6 判断a,b是否相等
Object.is(1,2) //false
Object.is(1,2) //false
Object.is(1,'1') //false
Object.is(undefined,undefined)//true
Object.is(null,null)//true
在NaN与+0,-0的判断上比===更准确,其他与 === 一致
Object.is(NaN,NaN) //true
Object.is(+0,-0) //false
6.Object.assign() : 用于将源对象的所有可枚举属性复制到目标对象上
a.此方法可以有多个参数,首参数一定是目标对象,不可以为null或者undefined,会报错;其余参数是源对象,当其余参数不是对象时,只有字符串类型会生效,其他数值,布尔类型都不会生效,遇到不能转化成对象的null或者undefined,则会跳过,不出错。
Object.assign(null,{name : "test"}) //报错 Cannot convert undefined or null to object
Object.assign(null,{name : "test"})//报错 Cannot convert undefined or null to object
Object.assign(1,{name : "test"}); //Number {1, name: "test"} 首参数不是对象时,会先转成对象
Object.assign({},undefined); //{}
Object.assign({},null);//{}
b.当其余参数不是对象时,只有字符串类型会以数组形式生效,其他数值,函数以及布尔类型都不会生效,
Object.assign({},'abc');//{0: "a", 1: "b", 2: "c"}
Object.assign({},100);// {}
Object.assign({},true);//{}
let f = function(){}
Object.assign({},f);//{}
d.用途
(1)可以用来复制对象(浅拷贝)
let target = {name: "target"}
let source = {size: 13}
let newobj = Object.assign(target,source);//得到新的target {name: "target", size: 13}
newobj //{name: "target", size: 13}
target //{name: "target", size: 13}
target.size = 0;
newobj.size // {name: "target", size: 0}
newobj.size = 1;
target //{name: "target", size: 1} newobj与target是一个对象,任何一方的改动都会影响到另一方
//浅拷贝
let target = {name:"target"}
let source = {cat:{name: "nn",age: "3"}}
Object.assign(target,source); //{name:"target",cat:{name: "nn",age: "3"}}
source.cat.name = "big";
target.cat.name;// "big"
(2)如果源对象中有和目标对象同名的属性,则源对象中的此属性会全部覆盖目标对象中的此属性
let target = {
cat:{
name: "nn",
age: "3",
color: "black"
}
}
let source = {
cat: {
name:"bigdeck"
}
}
Object.assign(target,source);//{cat: cat: {name: "bigdeck"}} /source覆盖target的整个cat属性值,并不会只覆盖cat.name
(3)如果目标对象和源对象都是数组,则会将数组当做对象来处理
Object.assign(['a','b','c'],[1,3]); //[1,3,'c']
这是因为处理时视为对象处理Object.assign({1:'a',2:'b',3:'c'},{1:1,2:3});
(4)如果要复制的值是一个取值就、函数,则会先执行取值函数后赋值
let obj = {
cat : "nn",
get cat(){
return "cat";
},
set cat(a){
this.cat = "a";
}
}
Object.assign({},obj);//{cat: "cat"}
(5)可以为对象添加属性
Object.assign({},{name:"test"});//{name:"test"}
class Cat{
constructor(age,color){
return Object.assign(this,{age,color});
}
}
var c1 = new Cat(13,"white")
c1 //cat {age: 13, color: "white"}
(6)可以为对象添加函数
Object.assign(c1,{run(){return "run fast";}});
c1//Cat {age: 13, color: "white", run: ƒ}
Object.assign(c1.__proto__,{run2(){return "run fast";}});
c1.__proto__ //{run2: ƒ, constructor: ƒ}
c1 //Cat {age: 13, color: "white", run: ƒ}
(7)克隆对象
Object.assign({},c1);//Cat {age: 13, color: "white", run: ƒ}
Object.assign(Object.create(Object.getPrototypeOf(c1)),c1);//Cat {age: 13, color: "white", run: ƒ}
(8)合并多个对象
Object.assign({},{name:"test"},{age:13},{size:10});//{name: "test", age: 13, size: 10}
let merge = (target,...sources) => Object.assign(target,sources);
merge({},{name:"test"},{age:13},{size:10});//{name: "test", age: 13, size: 10}
merge({},[{name:"test"},{age:13},{size:10}]);//{0: {name: "test"}, 1: {age: 13}, 2: {size: 10}}
(9)为属性指定默认值
const DEFAULT = {
name : "test"
}
function init(){
var c = Object.assign({},DEFAULT,options);
return c;
}
init({name:"test2"});//利用了Object.assign同名属性后面的会全覆盖前面的同名属性的特点实现了給属性指定默认值(如果后面的对象没有与默认对象同名的属性,则使用默认对象中的属性)
7.属性的可枚举性与遍历
(1)可枚举性
Object.getOwnPropertyDescriptor()可以拿到对象的某个属性的描述对象
Object.getOwnPropertyDescriptor(c1,'age')
{
configurable:true,
enumerable:true,//此属性为true,表示被此对象描述的的属性是可枚举属性;false则为不可枚举属性
value:13,
writable:true
}
有四个操作会忽略enumerable为false的属性
for...in循环:只遍历对象自身的和继承的可枚举属性
Object.keys():返回对象自身的所有可枚举属性的键名
JSON.stringify():只串行化对象自身的可枚举的属性
Object.assign():忽略enumerable为false的属性,只拷贝对象自身的可枚举的属性
//父类
function Animal(){
this.name = 'Animal';
this.age = 13;
this.size = 100;
}
Object.defineProperties(Animal,{'gender':{value:"boy",enumerable:false},'color':{value:"red",enumerable:true}});
//原型链继承
function Cat(){
}
Cat.prototype = new Animal();
Cat.prototype.constructor = Cat;
Cat.prototype.name = 'cat';
Cat.ownSize = 10;
//new一个实例
var cat = new Cat();
Object.defineProperties(cat,{'sizecat':{value:1,enumerable:false},'colorcat':{value:"black",enumerable:true}});
for(var i in cat){
console.log(i+" : "+cat[i]);
}
//colorcat : black自身的可枚举属性
//name : 继承自Cat的可枚举属性
//age : 13 继承字Animal的可枚举的属性
//size : 100继承自Animal的可枚举的属性
//constructor : function Cat(){}构造器
Object.keys(cat)//['colorcat'] cat自身可枚举的属性
JSON.stringify(cat)//'{"colorcat":"black"}' cat自身可枚举的属性
Object.assign({},cat);//{colorcat: "black"} cat自身可枚举的属性
(2)属性的遍历
for...in:只遍历对象自身的和继承的可枚举属性
Object.keys(obj):返回对象自身的所有可枚举属性的键名
Object.getOwnPropertyNames(obj):返回一个数组,包含对象自身的所有属性的键名,这个所有属性包含不可枚举属性但是不包含symbol属性的键名
Object.getOwnPropertyNames(cat);
// ["sizecat", "colorcat"] 'sizecat'对象自身的不可枚举属性,'colorcat'对象自身的可枚举属性
Object.getOwnPropertySymbols(obj):返回一个数组,包含对象自身的所有Symbol属性的键名
Object.getOwnPropertySymbols(cat);
//[] cat没有Symbol属性
Reflect.ownKeys(obj):返回一个数组,包含对象自身的所有属性的键名,不管这个属性是Symbol还是字符串,也不管是否可枚举
Reflect.ownKeys(cat);
//["sizecat", "colorcat"] 'sizecat'对象自身的不可枚举属性,'colorcat'对象自身的可枚举属性
属性的遍历顺序
首先遍历所有数值键,按照数值升序排列
其次遍历所有的字符串键,按照时间加入顺序升序排列
最后遍历所有的Symbol键,按照时间加入顺序升序排列
var obj = {1:2,"test":"again","a":"testing",2:3}
obj["objSymbol"] = Symbol()
Reflect.ownKeys(obj);//["1", "2", "test", "a", "objSymbol"]
8.Object.getOwnPropertyDescriptor()与Object.getOwnPropertyDescriptors()
Object.getOwnPropertyDescriptor()返回某个对象属性的描述对象(此属性非继承属性)
Object.getOwnPropertyDescriptor(cat,'name')//undefined 因为name是继承属性
Object.getOwnPropertyDescriptor(cat,'colorcat')// {value: "black", writable: false, enumerable: true, configurable: false} 因为colorcat是自身属性
Object.getOwnPropertyDescriptors() 返回指定对象所有的自身属性(非继承属性)的描述对象。
Object.getOwnPropertyDescriptors(cat);
//
{
catSymbol:{value: Symbol(), writable: true, enumerable: true, configurable: true}
colorcat:{value: "black", writable: false, enumerable: true, configurable: false}
sizecat:{value: 1, writable: false, enumerable: false, configurable: false}
}
9._proto_属性,getPrototypeOf()与setPrototypeOf()
(1)_proto_属性:用于读取或设置当前对象的prototype对象
var d = {name:"test"}
//读取对象的__proto__
d.__proto__ //{constructor: ƒ Object(), __defineGetter__: ƒ, __defineSetter__: ƒ, hasOwnProperty: ƒ, __lookupGetter__: ƒ, …}
//设置对象的__proto__
var c = {1:0};
d.__proto__ = c //返回的是c {1: 0}
(2)Object.getPrototypeOf(param):用于读取一个对象的原型对象。如果参数不是对象,则转化成对象;如果不能转化成对象,如undefined或者null,则会报错。
Object.getPrototypeOf(d) //{1: 0}
Object.getPrototypeOf(1)//Number {0, constructor: ƒ, toExponential: ƒ, toFixed: ƒ, toPrecision: ƒ, toString: ƒ, …}
Object.getPrototypeof(undefined)//报错 Uncaught TypeError: Object.getPrototypeof is not a function
(3)Object.setPrototypeOf(obj1,obj2):用来设置当前对象的prototype对象,返回参数对象本身。
//将obj2设置为obj1的原型对象。如果第一个参数不是对象,则转化为对象,但因为返回的是第一个参数,所以没有变化;如果第一个参数不能转化成对象,如undefined或者null,则会报错。
Object.setPrototypeOf(d,Number); //Function {name: "test"}
Object.getPrototypeOf(d);//ƒ Number() { [native code] }
10.super关键字:指向当前对象的原型对象
//super关键字在表示对象的原型时,只能用在对象的方法中,用在其他方法中都会报错。
let obj = {
name:super.name//报错 super用在属性中
}
let obj = {
method:function(){
return super.name;//报错 super用在方法中,然后赋值给属性
}
}
let obj = {
method = ()=> super.name;//报错 super用在方法中,然后赋值给属性
}
let obj1 = {
name:"obj1"
}
let obj2 = {
name:"obj2",
method(){
return super.name;//正确 obj1
}
}
Object.setPrototypeOf(obj2, obj1);
obj2.method //"obj1"
11.Object.keys(),Object.values()与Object.entries()
Object.keys():返回一个数组,数组成员是对象自身(不包含可继承)所有可遍历属性的键名
Object.values():返回一个数组,数组成员是对象自身所有可遍历属性的键值
Object.entries():返回一个数组,数组成员是对象自身所有可遍历的键值对
12.对象的扩展运算符
对象的扩展运算符...可以用于对象的解构赋值
(1)扩展运算符
可用于赋值对象
let obj = {name : "test",age : 13}
let obj3 = {...obj}
obj3 // {name: "test", age: 13}
如果参数是null或者undefined,将会忽略不报错
{...null}//{}
{...undefined}//{}
(2)解构赋值:解构赋值时,使用扩展运算符的参数必须是最后一个参数
let {x,y,...z} = {x : "test",y : 13,size:23,color:"black"}
x = "test"
y = 13
z = {size:23,color:"black"}
let {...x,y,z} = {x : "test",y : 13,size:23,color:"black"} //报错
ES6学习笔记(8)----对象的扩展的更多相关文章
- ES6 学习笔记之四 对象的扩展
ES6 为对象字面量添加了几个实用的功能,虽然这几个新功能基本上都是语法糖,但确实方便. 一.属性的简洁表示法 当定义一个对象时,允许直接写入一个变量,作为对象的属性,变量名就是属性名. 例1: , ...
- ES6学习笔记(三)——数值的扩展
看到这条条目录有没有感觉很枯燥,觉得自己的工作中还用不到它所以实在没有耐心看下去,我也是最近得闲,逼自己静下心来去学习去总结,只有在别人浮躁的时候你能静下心来去学去看去总结,你才能进步.毕竟作为前端不 ...
- es6学习笔记9--函数的扩展
函数参数的默认值 基本用法 在ES6之前,不能直接为函数的参数指定默认值,为了避免这个问题,通常需要先判断一下参数y是否被赋值,如果没有,再等于默认值. ES6允许为函数的参数设置默认值,即直接写在参 ...
- ES6学习笔记二:各种扩展
转载请注明原文地址:http://www.cnblogs.com/ygj0930/p/7242967.html 一:字符串扩展 1:字符串遍历器 for (let char of str) { // ...
- ES6学习笔记(对象)
1.属性的简洁表示法 const foo = 'bar'; const baz = {foo}; baz // {foo: "bar"} // 等同于 const baz = {f ...
- ES6学习笔记(5)----数值的扩展
参考书<ECMAScript 6入门>http://es6.ruanyifeng.com/ 数值的扩展 1.Number对象的扩展(1)javascript的全局函数isNaN,isFin ...
- es6学习笔记-proxy对象
前提摘要 尤大大的vue3.0即将到来,虽然学不动了,但是还要学的啊,据说vue3.0是基于proxy来进行对值进行拦截并操作,所以es6的proxy也是要学习一下的. 一 什么是proxy Prox ...
- ES6学习笔记(一)——扩展运算符和解构赋值
前言 随着前端工程化的快速推进,在项目中使用ES6甚至更高的ES7等最近特性早已不是什么新鲜事.之前还觉得既然浏览器支持有限,那了解一下能看懂就好,然而仅仅了解还是不够的,现在放眼望去,那些成熟框架的 ...
- es6学习笔记--promise对象
Promise对象是为了简化异步编程.解决回调地狱情况 Promise,简单说就是一个容器,里面保存着某个未来才会结束的事件(通常是一个异步操作)的结果.从语法上说,Promise 是一个对象,从它可 ...
随机推荐
- React在Render中使用bind可能导致的问题
因为bind在render的时候会重现生成,这样会导致props每次都不同, puremixin的插件也会失效. 所以需要将bind的结果缓存下来,或者直接在constructor里做这个事情 con ...
- java 简单贪吃蛇
1. [代码]java 简单程序 跳至 [1] [全屏预览]package com.snake;import java.awt.*;import javax.swing.*;import ja ...
- 一步一步学Silverlight 2系列(25):综合实例之Live Search
概述 Silverlight 2 Beta 1版本发布了,无论从Runtime还是Tools都给我们带来了很多的惊喜,如支持框架语言Visual Basic, Visual C#, IronRuby, ...
- Oracle:ORA-01790: expression must have same datatype as corresponding expression
今天有现场报sql错误,错误sql语句 类似 select * from tableA where (exists 条件A or exists 条件B), 单独执行 select * f ...
- 屏幕适配-使用autoLayout
当遇见xib中无法删除的控件时. 将这个错误的控件拖离本xib(第一个元素.xib文件是有许多元素组成的集合),确保这个xib是正确的.重新创建一个xib文件,将这个正确的xib元素整个复制过去. 在 ...
- [SoapUI] Common XPath expressions
选取节点 表达式 描述 nodename 选取此节点的所有子节点. / 从根节点选取. // 从匹配选择的当前节点选择文档中的节点,而不考虑它们的位置. . 选取当前节点. .. 选取当前节点的父节点 ...
- 「BZOJ3438」小M的作物(最小割
3438: 小M的作物 Time Limit: 10 Sec Memory Limit: 256 MBSubmit: 1891 Solved: 801[Submit][Status][Discus ...
- MYSQL数据库学习----MYSQL数据类型
一切数据在计算中都是以二进制形式存储,而8位二进制数就表示1个字节. 通常我们说一种数据类型占多少字节,就是说这种数据类型可以表示多少位的二进制数,同时二进制数可以转换为十进制数,进而得到这种数据类型 ...
- Linux Shell高级技巧(目录)
为了方便我们每个人的学习,这里将给出Linux Shell高级技巧五篇系列博客的目录以供大家在需要时参阅和查找. Linux Shell高级技巧(一) http://www.cnblogs.com/s ...
- jQuery中排除指定元素,同时选择剩下的所有元素
场景:某页面用了js延时加载技术处理所有图片,以改善用户体验,但是有几个图片不想延时加载,要求把它们单独挑出来. 研究了一下jQuery的API文档,搞掂了,jQuery真的很方便,贴在这里备份: 1 ...