ES6总结--(3)

1.Symbol

       ES5 的对象属性名都是字符串,这容易造成属性名的冲突。⽐如,你使⽤了⼀个他⼈提供的对象,但⼜想为这个对象添加新的⽅法(mixin 模式),新⽅法的名字就有可能与现有⽅法产⽣冲突。如果有⼀种机制,保证每个属性的名字都是独⼀⽆⼆的就好了,这样就从根本上防⽌属性名的冲突。ES6 引⼊了⼀种新的原始数据类型 Symbol ,表示独⼀⽆⼆的值。

     1.1 生成Symbol值

        通过调⽤Symbol函数⽣成⼀个Symbol值,这个值是独⼀⽆⼆的。注意,Symbol的值不是对象,不要给其添加属性,Symbol就是⼀个类似于字符串的值
let s = Symbol(); 
typeof s //symbol

    1.2 生成具有标识的Symbol值

      Symbol 函数可以接受⼀个字符串作为参数,表示对 Symbol 实例的描述,主要是为了在控制台显示,或者转为字符串时,⽐较容易区分。 通过Symbol.prototype.description可以获取该描述信息。
let s1 = Symbol('foo'); 
let s2 = Symbol('bar');

    1.3 消除魔术字符串

       魔术字符串指的是,在代码之中多次出现、与代码形成强耦合的某⼀个具体的字符串或者数 值。⻛格良好的代码,应该尽量消除魔术字符串,改由含义清晰的变量代替。
function getArea(shape, options) { 
 let area = 0; 
 switch (shape) { 
  case 'Triangle': // 魔术字符串
  area = .5 * options.width * options.height; 
  break; 
  /* ... more code ... */ 
  } 
 return area;
}
getArea('Triangle', { width: 100, height: 100 }); // 魔术字符串

    1.4 获取⼀个对象中Symbol属性名

      Symbol 作为属性名,该属性不会出现在for...in、for...of循环中,也不会被Object.keys()、 Object.getOwnPropertyNames()、JSON.stringify()返回。但是,它也不是私有属性,有⼀个 Object.getOwnPropertySymbols⽅法,可以获取指定对象的所有 Symbol 属性名。或者,使⽤ Reflflect.ownKeys⽅法可以返回所有类型的键名,包括常规键名和 Symbol 键名。
let s1 = Symbol('foo'); 
let s2 = Symbol('bar'); 
let obj = { 
 [s1]:'hello', 
 [s2]:'world', 
 name:'terry', 
 age:12 
} 
Object.getOwnPropertySymbols(obj) //[ Symbol(foo), Symbol(bar) ]
Reflect.ownKeys(obj) //[ 'name', 'age', Symbol(foo), Symbol(bar) ]

     1.5 Symbol值重复利用

    Symbol.for() ⽅法可以做到使⽤同⼀个 Symbol 值。它接受⼀个字符串作为参数,然后搜索有没有以该参数作为名称的 Symbol 值。如果有,就返回这个 Symbol 值,否则就新建⼀个以该字符串为名称的 Symbol 值,并将其注册到全局。
let s1 = Symbol.for('foo'); 
let s2 = Symbol.for('foo'); 
s1 === s2 // true
    Symbol.keyFor() ⽅法返回⼀个已登记的 Symbol 类型值的 key
let s1 = Symbol.for("foo"); 
Symbol.keyFor(s1) // "foo" 
let s2 = Symbol("foo"); 
Symbol.keyFor(s2) // undefined

    1.6 内置Symbol

      除了定义⾃⼰使⽤的 Symbol 值以外,ES6 还提供了 11 个内置的 Symbol 值,指向语⾔内部使⽤的⽅法。
      Symbol.hasInstance
        对象的 Symbol.hasInstance 属性,指向⼀个内部⽅法。当其他对象使⽤ instanceof 运算符,判断是否为该对象的实例时,会调⽤这个⽅法。⽐如, foo instanceof Foo 在语⾔内 部,实际调⽤的是 Foo[Symbol.hasInstance](foo)
class MyClass { 
 [Symbol.hasInstance](foo) { 
  return foo instanceof Array; 
  } 
 } 
[1, 2, 3] instanceof new MyClass() // true
      Symbol.iterator
        对象的 Symbol.iterator 属性,指向该对象的默认遍历器⽅法。
const myIterable = {}; 
myIterable[Symbol.iterator] = function* () { 
 yield 1; 
 yield 2; 
 yield 3; 
}; 
[...myIterable] // [1, 2, 3]

2.集合

    2.1 Set

      Set允许存储任何类型的唯⼀值,Set是ES6提供了新的数据结构。它类似于数组,但是成员的值都是唯⼀的,没有重复的值。
      构造函数
      Set 函数可以接受⼀个数组(或者具有 iterable 接⼝的其他数据结构)作为参数,⽤来初始化。
const set = new Set([1, 2, 3, 4, 4]); 
[...set] 
// [1, 2, 3, 4]
      Set.prototype.size
        获取容器中元素个数
      Set.prototype.add(value)
        向集合加⼊⼀个元素,不允许相同元素存在
      Set.prototype.delete(value)
        从集合中删除⼀个元素
      Set.prototype.has(value)
        判断集合中是否包含value
      Set.prototype.clear()
         清空set集合
      Set.prototype.keys()
        获取set集合key值的迭代器,由于set集合没有key所有与values⽅法返回结果⼀致
      Set.prototype.values()
        获取set集合的value值的迭代器
      Set.prototype.entries()
        获取set集合的entries迭代器
 
      Set.prototype.forEach()
        与数组类似的迭代⽅法

    2.2 Map

       Map 数据结构。它类似于对象,也是键值对的集合,但是“键”的范围不限于字符串,各种类型的值(包括对象)都可以当作键。也就是说,Object 结构提供了“字符串—值”的对应,Map 结构提供了“值—值”的对应,是⼀种更完善的 Hash 结构实现。如果你需要“键值对”的数据结构,Map ⽐ Object 更合适。
const items = [ 
['name', '张三'], 
['title', 'Author']
]; 
const map = new Map(); 
items.forEach( 
 ([key, value]) => map.set(key, value) 
);
      Map.prototype.size
        获取集合键值对个数
      Map.prototype.set(key, value)
        向集合中设置⼀个键值对
      Map.prototype.get(key)
        从集合中通过key获取value
      Map.prototype.has(key)
        判断集合中是否包含key指定的键
      Map.prototype.delete(key)
        通过key删除⼀个键值对
      Map.prototype.clear()
        清空map集合
      Map.prototype.keys()
        获取map集合key值的迭代器
      Map.prototype.values()
        获取map集合value值的迭代器
      Map.prototype.entries()
        获取map集合entry的迭代器
      Map.prototype.forEach()
        迭代

3.代理

      Proxy 可以理解成,在⽬标对象之前架设⼀层“拦截”,外界对该对象的访问,都必须先通过这层拦截,因此提供了⼀种机制,可以对外界的访问进⾏过滤和改写。
      ES6 原⽣提供 Proxy 构造函数,⽤来⽣成 Proxy 实例。

    3.1 set/get

      设置、获取属性值劫持
let obj = { 
 name:'terry',
 age:12 
} 
let proxy = new Proxy(obj, { 
 get:function(target,key){ 
 return target[key] 
 }, 
set:function(target,key,value){
 target[key] = value;
 }
})
proxy.age = 13; // 将会触发set操作
console.log(proxy.name); // 将会触发get操作

    3.2 apply

       函数调⽤劫持,当通过代理执⾏函数的时候会触发apply函数的执⾏
function foo(name){ 
 console.log('hello',name); 
}
let proxy = new Proxy(foo,{ 
 apply(target,that,args){ 
  target.apply(that,args) 
 } 
}) 
proxy('terry');
proxy.call({},'terry')
proxy.apply({},['terry'])

    3.3 constructor

      构造函数劫持,当通过new来调⽤代理的时候会触发contructor函数的执⾏
function Foo(name){ 
 this.name = name; 
} 
let pp = new Proxy(Foo,{ 
 construct(target,args){ 
  return new target(...args) 
 } 
}) 
console.log(new pp('terry').name);

4.反射

      Reflect 是⼀个内置的对象,它提供拦截 JavaScript 操作的⽅法。这些⽅法与 proxy 的⽅法相同。 Reflect 不是⼀个函数对象,因此它是不可构造的。

     4.1 Reflect.apply(target, thisArg, args)

        和 Function.prototype.apply() 功能类似
function foo(name){ 
 console.log('hello',name); 
} 
let proxy = new Proxy(foo,{ 
 apply(target,that,args){ 
  Reflect.apply(target,that,args) 
 } 
})
proxy('terry');
proxy.call({},'terry')
proxy.apply({},['terry'])

     4.2 Reflect.construct(target, args)

        对构造函数进⾏ new 操作,相当于执⾏ new target(...args)
function Foo(name){ 
 this.name = name; 
} 
let proxy = new Proxy(Foo,{ 
 construct(target,args){ 
  return Reflect.construct(target,args) 
 } 
})
console.log(new proxy('terry').name);

    4.3 Reflect.get(target, name, receiver)

        获取对象身上某个属性的值,类似于 target[name]

    4.4 Reflect.set(target, name, value, receiver)

        将值分配给属性的函数。返回⼀个 Boolean ,如果更新成功,则返回 true

let obj = { 
 name:'terry', 
 age:12 
} 
let proxy = new Proxy(obj, { 
 get:function(target,key){ 
  return Reflect.get(target,key) 
 },
 set:function(target,key,value){
  return Reflect.set(target,key,value)
 }
})
proxy.age = 13; // 将会触发set操作
console.log(proxy.name); // 将会触发get操作
console.log(proxy.age); // 将会触发get操作

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值