es6笔记3^_^object
一、destructuring
ES6允许按照一定模式,从数组和对象中提取值,对变量进行赋值,这被称为解构Destructuring。
//es5
if(1){
let cat = 'ken';
let dog = 'lili';
let zoo = {cat: cat, dog: dog};
console.log(zoo) ; //Object {cat: "ken", dog: "lili"}
}
//用ES6完全可以像下面这么写:
if(1){
let cat = 'ken';
let dog = 'lili';
let zoo = {cat, dog};
console.log(zoo) ; //Object {cat: "ken", dog: "lili"}
}
//反过来可以这么写:
if(1){
let dog = {type: 'animal', many: 2};
let { type, many} = dog;
console.log(type, many) ; //animal 2
}
二、属性名表达式
用方法、表达式作为对象的属性名;表达式还可以用于定义方法名。
JavaScript语言定义对象的属性,有两种方法。
let obj1 = {};
// 方法一
obj1.foo = true;
// 方法二
obj1['a'+'bc'] = 123;
console.log(obj1);
上面代码的方法一是直接用标识符作为属性名,方法二是用表达式作为属性名,这时要将表达式放在方括号之内。
如果使用字面量方式定义对象(使用大括号),在ES5中只能使用方法一(标识符)定义属性。
var obj2 = {
foo: true,
abc: 123
}
ES6允许字面量定义对象时,用方法(表达式)作为对象的属性名,即把表达式放在方括号内。
let propKey = 'foo';
let obj3 = {
[propKey]: true,
['a'+'bc']: 123
};
console.log(obj3);
//表达式还可以用于定义方法名。
let ello='i';
let obj4 = {
['h'+ello]() {
return 'hi nick';
}
};
console.log(obj4.hi()); // hi nick
三、Object.is()
Object.is()用来比较两个值是否严格相等。它与严格比较运算符(===)的行为基本一致,不同之处只有两个:一是+0不等于-0,二是NaN等于自身。
console.log(+0 === -0);//true
console.log(NaN === NaN); // false
console.log(Object.is(+0, -0)); // false
console.log(Object.is(NaN, NaN)); // true
四、Object.assign()
Object.assign方法用来将源对象(source)的所有可枚举属性,复制到目标对象(target)。
它至少需要两个对象作为参数,第一个参数是目标对象,后面的参数都是源对象。只要有一个参数不是对象,就会抛出TypeError错误。
let target = { a: 1 };
let source1 = { b: 2 };
let source2 = { c: 3 };
Object.assign(target, source1, source2);
console.log(target); // {a:1, b:2, c:3}
注意:如果目标对象与源对象有同名属性,或多个源对象有同名属性,则后面的属性会覆盖前面的属性。
let target1 = { a: 1, b: 1 };
let source11 = { b: 2, c: 2 };
let source21 = { c: 3 }; Object.assign(target1, source11, source21);
console.log(target1); // {a:1, b:2, c:3}
console.log(Object.assign({'name':'张三'},{'name':'nick','age':26,'sex':'男','sex':{'gander':'handsome'}}));
Object.assign只拷贝自身属性,不可枚举的属性(enumerable为false)和继承的属性不会被拷贝。
let obj1=Object.assign({b: 'c'},
Object.defineProperty({}, 'invisible', {
enumerable: false,
value: 'hello'
})
);
console.log(obj1);// { b: 'c' } let obj2 =Object.assign({b: 'c'},
Object.defineProperty({}, 'invisible', {
enumerable: true,
value: 'hello'
})
);
console.log(obj2);// {b: "c", invisible: "hello"}
属性名为Symbol值的属性,也会被Object.assign拷贝。
let obj3=Object.assign({ a: 'b' }, { [Symbol('c')]: 'd' })
console.log(obj3);// { a: 'b', Symbol(c): 'd' }
注意:Object.assign可以用来处理数组,但是会把数组视为对象。
Object.assign([1, 2, 3], [4, 5]);// [4, 5, 3]
其中,4覆盖1,5覆盖2,因为它们在数组的同一位置,所以就对应位置覆盖了。
Object.assign还有很多用处,下面就看一下吧:
为对象添加属性
class Point {
constructor(x, y) {
Object.assign(this, {x, y});
}
}
这样就给Point类的对象实例添加了x、y属性。
为对象添加方法
let SomeClass={test:'nick'};
SomeClass.prototype={};
Object.assign(SomeClass.prototype, {
someMethod:function(arg1, arg2) { },
anotherMethod:function () { }
});
console.log(SomeClass);
等同于下面的写法
let SomeClass2={test:'nick2'};
SomeClass2.prototype={};
SomeClass2.prototype.someMethod = function (arg1, arg2) { };
SomeClass2.prototype.anotherMethod = function () { };
console.log(SomeClass2);
上面代码使用了对象属性的简洁表示法,直接将两个函数放在大括号中,再使用assign方法添加到SomeClass.prototype之中。
克隆对象
function clone1(origin) {
return Object.assign({}, origin);
}
上面代码将原始对象拷贝到一个空对象,就得到了原始对象的克隆。
不过,采用这种方法克隆,只能克隆原始对象自身的值,不能克隆它继承的值。如果想要保持继承链,可以采用下面的代码。
function clone2(origin) {
let originProto = Object.getPrototypeOf(origin);
return Object.assign(Object.create(originProto), origin);
}
在JS里子类利用Object.getPrototypeOf去调用父类方法,用来获取对象的原型。用它可以模仿Java的super。
多个对象合并到某个对象
const merge1 =(target, ...sources) => Object.assign(target, ...sources);
多个对象合并到一个新对象
const merge2 = (...sources) => Object.assign({},...sources);
为属性指定默认值
const DEFAULTS = {
logLevel: 0,
outputFormat: 'html'
}; function processContent(options) {
let options1 = Object.assign({}, DEFAULTS, options);
}
上面代码中,DEFAULTS对象是默认值,options对象是用户提供的参数。Object.assign方法将DEFAULTS和options合并成一个新对象,如果两者有同名属性,则option的属性值会覆盖DEFAULTS的属性值。
注: 由于存在深拷贝的问题,DEFAULTS对象和options对象的所有属性的值,都只能是简单类型,而不能指向另一个对象。否则,将导致DEFAULTS对象的该属性不起作用。
此篇全部代码:
<!DOCTYPE html>
<html >
<head>
<meta charset="UTF-8">
<title>es6-object</title>
<script>
/*object*/
//1.destructuring
//ES6允许按照一定模式,从数组和对象中提取值,对变量进行赋值,这被称为解构(Destructuring)。
//es5
if(1){
let cat = 'ken';
let dog = 'lili';
let zoo = {cat: cat, dog: dog};
console.log(zoo) ; //Object {cat: "ken", dog: "lili"}
}
//用ES6完全可以像下面这么写:
if(1){
let cat = 'ken';
let dog = 'lili';
let zoo = {cat, dog};
console.log(zoo) ; //Object {cat: "ken", dog: "lili"}
}
//反过来可以这么写:
if(1){
let dog = {type: 'animal', many: 2};
let { type, many} = dog;
console.log(type, many) ; //animal 2
} /*2.属性名表达式(用方法(表达式)作为对象的属性名;表达式还可以用于定义方法名。)
JavaScript语言定义对象的属性,有两种方法。*/
if(1){
let obj1 = {};
// 方法一
obj1.foo = true;
// 方法二
obj1['a'+'bc'] = 123;
console.log(obj1);
/*上面代码的方法一是直接用标识符作为属性名,方法二是用表达式作为属性名,这时要将表达式放在方括号之内。
如果使用字面量方式定义对象(使用大括号),在ES5中只能使用方法一(标识符)定义属性。
var obj2 = {
foo: true,
abc: 123
};*/
//ES6允许字面量定义对象时,用方法(表达式)作为对象的属性名,即把表达式放在方括号内。
let propKey = 'foo';
let obj3 = {
[propKey]: true,
['a'+'bc']: 123
};
console.log(obj3);
//表达式还可以用于定义方法名。
let ello='i';
let obj4 = {
['h'+ello]() {
return 'hi nick';
}
};
console.log(obj4.hi()); // hi nick
}
//3. Object.is()用来比较两个值是否严格相等。它与严格比较运算符(===)的行为基本一致,不同之处只有两个:一是+0不等于-0,二是NaN等于自身。
console.log(+0 === -0);//true
console.log(NaN === NaN); // false
console.log(Object.is(+0, -0)); // false
console.log(Object.is(NaN, NaN)); // true
/*
4.源对象的所有可枚举属性,复制到目标对象
Object.assign方法用来将源对象(source)的所有可枚举属性,复制到目标对象(target)。
它至少需要两个对象作为参数,第一个参数是目标对象,后面的参数都是源对象。只要有一个参数不是对象,就会抛出TypeError错误。
*/
if(1){
let target = { a: 1 };
let source1 = { b: 2 };
let source2 = { c: 3 };
Object.assign(target, source1, source2);
console.log(target); // {a:1, b:2, c:3}
//注意,如果目标对象与源对象有同名属性,或多个源对象有同名属性,则后面的属性会覆盖前面的属性。 let target1 = { a: 1, b: 1 };
let source11 = { b: 2, c: 2 };
let source21 = { c: 3 }; Object.assign(target1, source11, source21);
console.log(target1); // {a:1, b:2, c:3}
console.log(Object.assign({'name':'张三'},{'name':'nick','age':26,'sex':'男','sex':{'gander':'handsome'}})); // Object.assign只拷贝自身属性,不可枚举的属性(enumerable为false)和继承的属性不会被拷贝。 let obj1=Object.assign({b: 'c'},
Object.defineProperty({}, 'invisible', {
enumerable: false,
value: 'hello'
})
);
console.log(obj1);// { b: 'c' } let obj2 =Object.assign({b: 'c'},
Object.defineProperty({}, 'invisible', {
enumerable: true,
value: 'hello'
})
);
console.log(obj2);// {b: "c", invisible: "hello"} // 属性名为Symbol值的属性,也会被Object.assign拷贝。
let obj3=Object.assign({ a: 'b' }, { [Symbol('c')]: 'd' })
console.log(obj3);// { a: 'b', Symbol(c): 'd' } // 注意,Object.assign可以用来处理数组,但是会把数组视为对象。
Object.assign([1, 2, 3], [4, 5]);// [4, 5, 3] /* 其中,4覆盖1,5覆盖2,因为它们在数组的同一位置,所以就对应位置覆盖了。
Object.assign还有很多用处,下面就看一下吧:
为对象添加属性
*/
class Point {
constructor(x, y) {
Object.assign(this, {x, y});
}
} /*这样就给Point类的对象实例添加了x、y属性。
为对象添加方法*/
let SomeClass={test:'nick'};
SomeClass.prototype={};
Object.assign(SomeClass.prototype, {
someMethod:function(arg1, arg2) { },
anotherMethod:function () { }
});
console.log(SomeClass);
// 等同于下面的写法
let SomeClass2={test:'nick2'};
SomeClass2.prototype={};
SomeClass2.prototype.someMethod = function (arg1, arg2) { };
SomeClass2.prototype.anotherMethod = function () { };
console.log(SomeClass2); /*上面代码使用了对象属性的简洁表示法,直接将两个函数放在大括号中,再使用assign方法添加到SomeClass.prototype之中。
克隆对象*/ function clone1(origin) {
return Object.assign({}, origin);
}
/*
上面代码将原始对象拷贝到一个空对象,就得到了原始对象的克隆。
不过,采用这种方法克隆,只能克隆原始对象自身的值,不能克隆它继承的值。如果想要保持继承链,可以采用下面的代码。*/ function clone2(origin) {
let originProto = Object.getPrototypeOf(origin);
return Object.assign(Object.create(originProto), origin);
}
/* 在JS里子类利用Object.getPrototypeOf去调用父类方法,用来获取对象的原型。用它可以模仿Java的super。
将多个对象合并成一个对象
多个对象合并到某个对象*/ const merge1 =(target, ...sources) => Object.assign(target, ...sources); // 多个对象合并到一个新对象 const merge2 = (...sources) => Object.assign({},...sources); // 为属性指定默认值 const DEFAULTS = {
logLevel: 0,
outputFormat: 'html'
}; function processContent(options) {
let options1 = Object.assign({}, DEFAULTS, options);
}
/*
上面代码中,DEFAULTS对象是默认值,options对象是用户提供的参数。Object.assign方法将DEFAULTS和options合并成一个新对象,如果两者有同名属性,则option的属性值会覆盖DEFAULTS的属性值。
注: 由于存在深拷贝的问题,DEFAULTS对象和options对象的所有属性的值,都只能是简单类型,而不能指向另一个对象。否则,将导致DEFAULTS对象的该属性不起作用。*/
}
/*
5.proto属性
proto属性,用来读取或设置当前对象的prototype对象。该属性一度被正式写入ES6草案,但后来又被移除(尽量别用)。目前,所有浏览器(包括IE11)都部署了这个属性。
*/
if(1){
// es6的写法
let someOtherObj=function(){console.log('someOtherObj');};
let obj1 = {
__proto__: someOtherObj,
method: function() {console.log('method');}
};
// es5的写法
let obj2 = Object.create(someOtherObj);
obj2.method = function() {};
console.log(obj1);
console.log(obj2);
}
// 17.Symbol类型
//ES6引入了一种新的原始数据类型Symbol,表示独一无二的ID。凡是属性名属于Symbol类型,就都是独一无二的,可以保证不会与其他属性名产生冲突。
if(1){
let s = Symbol();
console.log(typeof s);// "symbol"
/*
typeof运算符的结果,表明变量s是Symbol数据类型,而不是字符串之类的其他类型。
注意,Symbol函数前不能使用new命令,否则会报错。这是因为生成的Symbol是一个原始类型的值,不是对象。
Symbol类型的值不能与其他类型的值进行运算,会报错。
*/ let sym = Symbol('My symbol');
// "your symbol is " + sym
// TypeError: can't convert symbol to string
// `your symbol is ${sym}`
// TypeError: can't convert symbol to string
//但是,Symbol类型的值可以转为字符串。
console.log(String(sym)); // 'Symbol(My symbol)'
console.log(sym.toString()); // 'Symbol(My symbol)'
}
/*
6.内置代理
Proxy 内置的一个代理工具,使用他可以在对象处理上加一层屏障: S6原生提供Proxy构造函数,用来生成Proxy实例。 var proxy = new Proxy(target, handler)
new Proxy()表示生成一个Proxy实例,它的target参数表示所要拦截的目标对象,handler参数也是一个对象,用来定制拦截行为。
*/
if(1){
let plain = {
name : "hubwiz"
};
let proxy = new Proxy(plain, {
get: function(target, property) {
console.log(target);//plain
console.log(property);//title
return property in target ? target[property] : "汇智网";
}
});
console.log(proxy.name);// "hubwiz"
console.log(proxy.title);// "汇智网"
}
/*
Proxy(target, handler), 这里的 handler有如下的方法:
get(target, propKey, receiver):拦截对象属性的读取,比如proxy.foo和proxy['foo'],返回类型不限。最后一个参数receiver可选,当target对象设置了propKey属性的get函数时,receiver对象会绑定get函数的this对象。
set(target, propKey, value, receiver):拦截对象属性的设置,比如proxy.foo = v或proxy['foo'] = v,返回一个布尔值。
has(target, propKey):拦截propKey in proxy的操作,返回一个布尔值。
deleteProperty(target, propKey) :拦截delete proxy[propKey]的操作,返回一个布尔值。
enumerate(target):拦截for (var x in proxy),返回一个遍历器。
hasOwn(target, propKey):拦截proxy.hasOwnProperty('foo'),返回一个布尔值。
ownKeys(target):拦截Object.getOwnPropertyNames(proxy)、Object.getOwnPropertySymbols(proxy)、Object.keys(proxy),返回一个数组。该方法返回对象所有自身的属性,而Object.keys()仅返回对象可遍历的属性。
getOwnPropertyDescriptor(target, propKey) :拦截Object.getOwnPropertyDescriptor(proxy, propKey),返回属性的描述对象。
defineProperty(target, propKey, propDesc):拦截Object.defineProperty(proxy, propKey, propDesc)、Object.defineProperties(proxy, propDescs),返回一个布尔值。
preventExtensions(target):拦截Object.preventExtensions(proxy),返回一个布尔值。
getPrototypeOf(target) :拦截Object.getPrototypeOf(proxy),返回一个对象。
isExtensible(target):拦截Object.isExtensible(proxy),返回一个布尔值。
setPrototypeOf(target, proto):拦截Object.setPrototypeOf(proxy, proto),返回一个布尔值。
如果目标对象是函数,那么还有两种额外操作可以拦截。
apply(target, object, args):拦截Proxy实例作为函数调用的操作,比如proxy(...args)、proxy.call(object, ...args)、proxy.apply(...)。
construct(target, args, proxy):拦截Proxy实例作为构造函数调用的操作,比如new proxy(...args)。
*/
</script>
</head>
<body> </body>
</html>
此篇终,待续……
es6笔记3^_^object的更多相关文章
- ES6笔记(5)-- Generator生成器函数
系列文章 -- ES6笔记系列 接触过Ajax请求的会遇到过异步调用的问题,为了保证调用顺序的正确性,一般我们会在回调函数中调用,也有用到一些新的解决方案如Promise相关的技术. 在异步编程中,还 ...
- ES6笔记系列
ES6,即ECMAScript 6.0,ES6的第一个版本是在2015年发布的,所以又称作ECMAScript 2015 如今距ES6发布已经一年多的时间,这时候才去学,作为一个JSer,羞愧羞愧,还 ...
- ES6笔记(1) -- 环境配置支持
系列文章 -- ES6笔记系列 虽然ES6已经发布一年多了,但在各大浏览器之中的支持度还不是很理想,在这查看ES6新特性支持度 Chrome的最新版本浏览器大部分已经支持,在Node.js环境上支持度 ...
- ES6笔记(2)-- let的块级作用域
系列文章 -- ES6笔记系列 一.函数级作用域 我们都知道,在ES6以前,JS只有函数级作用域,没有块级作用域这个概念 没有块级作用域,有利有弊,利于方便自由,弊于作用域内的变量容易被共享,例如这个 ...
- ES6笔记(3)-- 解构赋值
系列文章 -- ES6笔记系列 解构赋值,即对某种结构进行解析,然后将解析出来的值赋值给相关的变量,常见的有数组.对象.字符串的解构赋值等 一.数组的解构赋值 function ids() { ret ...
- ES6笔记(4)-- Symbol类型
系列文章 -- ES6笔记系列 Symbol是什么?中文意思是标志.记号,顾名思义,它可以用了做记号. 是的,它是一种标记的方法,被ES6引入作为一种新的数据类型,表示独一无二的值. 由此,JS的数据 ...
- ES6笔记(6)-- Set、Map结构和Iterator迭代器
系列文章 -- ES6笔记系列 搞ES6的人也是够无聊,把JS弄得越来越像Java.C++,连Iterator迭代器.Set集合.Map结构都出来了,不知道说什么好... 一.简单使用 1. iter ...
- ES6笔记(7)-- Promise异步编程
系列文章 -- ES6笔记系列 很久很久以前,在做Node.js聊天室,使用MongoDB数据服务的时候就遇到了多重回调嵌套导致代码混乱的问题. JS异步编程有利有弊,Promise的出现,改善了这一 ...
- ES6 笔记汇总
ES6 笔记汇总 二.ES6基础-let和const命令 三.变量的解构赋值 四.字符串的拓展 五.正则表达式的拓展 ...将会持续更新,敬请期待
- ES6笔记2
ES6笔记2 Promise Promise 是 ES6 引入的异步编程的新解决方案,语法上是一个构造函数 一共有3种状态,pending(进行中).fulfilled(已成功)和rejected(已 ...
随机推荐
- Query插件之ajaxFileUpload使用方法——input.change()事件的时候实现文件上传
点击下载 这是HTML <input id="uploadedfile" name="uploadedfile" type="file" ...
- Socket.io官方聊天室DEMO的学习笔记
照着Socket.io官方的聊天室代码敲了一遍,遇到了一个奇怪的问题: 每次点击SEND按钮的时候,都会重新刷新页面. 在点击页面的一瞬间,看到了正在加载jquery的提示, 然后以为是jquery用 ...
- web项目编译出错时,原因之一,可能是build path 中order and Export引起
build path中的order and Export,如果两个libarary中有相同功能的jar包,则编译器会选择顺序在前的jar包中相应的类作为编译所需. 所以,当项目jar包较多的时候,如果 ...
- [转]JavaScript通过参数动态调用函数——js中eval实现反射
以下文章出自 http://blog.rongzhiwang.com/king/archive/2012/08/13/javascriptjseval.aspx 今天碰到人问这样一个问题 ...
- javascript高级程序设计 重读系列
1.基本概念.数据类型.函数 1.1 数据类型 ECMAScript中有5种简单数据类型:Undefind,Null,Boolean,Number,String 问题:判断变量是否是空值的代码 解析: ...
- CodeForces 617A Elephant
C语言语法入门题 #include<cstdio> #include<cstring> #include<vector> #include<cmath> ...
- 控制流之if
if语句if语句用来检验一个条件, 如果 条件为真,我们运行一块语句(称为 if-块 ), 否则 我们处理另外一块语句(称为 else-块 ). else 从句是可选的. ~~~~~~~~~~~~~~ ...
- iOS 主动抛出异常
http://blog.csdn.net/jymn_chen/article/details/38096749 http://blog.sina.com.cn/s/blog_7270a06c0101b ...
- slf4j与logback对接是如何将日志写到控制台的
今天一个以前同事问了个RT的问题 我翻了下代码,简单跟了下 很简单 1. demo代码 package org.simonme.demo.log; import org.slf4j.Logger; i ...
- ios UIKit动力
UIkit动力学是UIkit框架中模拟真实世界的一些特性. UIDynamicAnimator 主要有UIDynamicAnimator类,通过这个类中的不同行为来实现一些动态特性. 它一般有两种初始 ...