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 是一个对象,从它可 ...
随机推荐
- design.js
//模块式开发 var myNamespace = (function () { var myPrivateVar = 0; var myPrivateMethod = function (foo) ...
- POJ2516 Minimum Cost —— 最小费用最大流
题目链接:https://vjudge.net/problem/POJ-2516 Minimum Cost Time Limit: 4000MS Memory Limit: 65536K Tota ...
- 织梦dedecms内页分类频道友情链接实现方法
本文介绍了织梦dedecms中内页分类频道加友情链接的三种方法,有需要的朋友参考下. 织梦dedecms中内页分类频道加友情链接,方法有三种: 先讲方法,后讲原理: 方法:先找到首页模版index.h ...
- hadoop异常:Be Replicated to 0 nodes, instead of 1
Hadoop 坑爹的Be Replicated to 0 nodes, instead of 1 异常 博客分类: Java 编程 HadoopITeyeJSP算法Apache 有段时间不写博客了, ...
- [Selenium] 如何绕过 IE 的安全模式
自从 IE7 引入 Protected Mode 以来, IE 浏览器的安全性的确得到了一定程度的提高.其原理从本质来讲,在浏览某些需要启用保护模式的页面时,会开启一个新的浏览器会话以完成任务,而此时 ...
- Luogu网校听课笔记(自用
TG助学课——noilinux 8.2 深夜 Noi Linux的使用——darkflames的博客 #include<bits/stdc++.h> using namespace std ...
- Struts2访问Servlet API的几种方式
struts2提供了三种方式访问servlet API:大致分为两类 1. ActionContext: public static ActionContext getContext() :获得当前 ...
- 使用GAC加速 解决CSP问题 Kakuro - Cross Sums
Kakuro - Cross Sums 问题如下 一个简单的例子 可以看出限制条件是某行或某列的某几个空白格子求和等于某个值,且每一个限制中的格子所填的数必须为1-9且互异. 直接暴力搜索,空白格子太 ...
- py-day15_css+js_初
css+js_初 一.鼠标移动变色 <!DOCTYPE html> <html lang="en"> <head> <meta chars ...
- Cmake生成Makefile
cmake 相比automake 最大的区别是: 步骤没有automake那么多 main.cpp #include<iostream> #include"student.h&q ...