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> //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"} } (1){ let cat = 'ken'; let dog = 'lili'; let zoo = {cat, dog}; console.log(zoo) ; //Object {cat: "ken", dog: "lili"} } (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 };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);let obj3=Object.assign({ a: 'b' }, { [Symbol('c')]: 'd' }) console.log(obj3);Object.assign([1, 2, 3], [4, 5]); 其中,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数据类型,而不是字符串之类的其他类型。 注意,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);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>
View Code此篇终,待续……