charCodeAt() and codePointAt()

这篇文章主要介绍javascript里的charCodeAt()方法和ES6引进的codePointAt()方法.

在说这两个方法之前,必须要先补充一些关于Unicode编码的知识…

ASCII码是256(2^8)个(0-255)数字,每一个数字都是一个码点(code point)[1].用于代表256个字符.但是这256个字符只是常用字符,各国语言,包括中文,远远超过这个范围.所以Unicode就出现了,Unicode源于一个很简单的想法:将全世界所有的字符包含在一个集合里,计算机只要支持这一个字符集,就能显示所有的字符,再也不会有乱码了。

可以这么理解,Unicode码是ASCII码的一个超集(superset).它的前128个code point和ASCII是一致的.后面又增加了很多很多字符.而UTF-32,UTF-8,UTF-16,都是Unicode码的编码形式:


more >>

method definitions

从ECMAScript2015(ES6)开始,引入了一种在初始化对象的时候,给对象定义方法的简约语法.为原来给一个函数定义一个方法名的键值对语法提供了一种简写语法.

语法

var obj = {
  property( parameters… ) {},
  *generator( parameters… ) {},
// also with computed keys:
  [property]( parameters… ) {},
  *[generator]( parameters… ) {},
// compare ES5 getter/setter syntax:
  get property() {},
  set property(value) {}
};

more >>

getter

get语法把对象的某个属性绑定到一个函数上,当访问该属性的时候执行这个函数

语法

{get prop() { ... } }
{get [expression]() { ... } }

参数

prop

需要绑定到函数的属性名

表达式

从ECMAScript 6 开始,你可以使用一个表达式来得到一个计算后的属性名来绑定所给的函数.

描述

有时候,你会想要让属性值是一个动态计算出的值,或者映射一个外部变量的状态而不需要显式地调用一个方法.在JavaScript里,你可以通过getter来实现它. 同一个对象的同一个属性不能同时绑定getter函数并且指定拥有一个值,但可以通过结合使用getter和setter来创建一个伪属性.

使用getter的时候需要注意以下几点:

  • 它可以拥有一个id,id可以是数字也可以是字符串
  • 它不能拥有参数.一个也不能有.(查看更多)
  • 在对象字面量里,一个属性只能有一个getter,并且getter绑定函数的属性不能再指定它的值,反之亦然.({ get x() { }, get x() { } } and { x: …, get x() { } } 类似于这样的是不行的.)

getter可以通过 delete 方法删除

栗子

在对象初始化的时候给属性添加getter

这会给 ocj 对象创建一个名为 latest 的伪属性,在打印它的时候会返回数组的最后一个值.

var log = ['test'];
var obj = {
  get latest () {
    if (log.length == 0) return undefined;
    return log[log.length - 1]
  }
}
console.log (obj.latest); // Will return "test".

注意,重新给 latest 属性指定值不会生效:

var log = ['test'];
var obj = {
  get latest () {
    if (log.length == 0) return undefined;
    return log[log.length - 1]
  }
}
console.log (obj.latest); // Will return "test".
log.push('bunny');
console.log(obj.latest);  // Will return "bunny"
obj.latest = 3;
console.log(obj.latest);  // Will return "bunny" still

使用 delete 操作来删除getter

如果你想把getter删除,只需要使用 delete 就行了.

delete obj.latest;

使用 defineProperty 给一个既存的对象添加getter

想要在任何时间给一个既存的对象添加getter ,可以通过Object.defineProperty()

var o = { a:0 }

Object.defineProperty(o, "b", { get: function () { return this.a + 1; } });

console.log(o.b) // Runs the getter, which yields a + 1 (which is 1)

使用计算后的属性名

注意: 计算后的属性名属于试验中技术, ECMAScript 6 的目标的一部分, 还没有被浏览器广泛支持. 在不支持的环境下会触发语法错误.
(经过测试,在目前的chrome里是可以用的.)

var expr = "foo";

var obj = {
  get [expr]() { return "bar"; }
};

console.log(obj.foo); // "bar"

智能 / 重写自身 / 懒getter

getter提供了一种定义对象属性的方式,但是它的值要到获取属性值的时候才会被计算. 也就是说, getter会延迟计算属性值,直到需要用到这个值,所以如果这个值一直用不到,则永远不需要为计算它而付出开销.

另外一个对getter进行额外优化的技术方案是: 智能getters 或 制表getters. 它可以延迟计算属性值,并且把计算结果进行缓存,让之后的访问直接获取缓存结果. 属性值会在第一次访问时进行计算并缓存,然后之后的访问会直接读取缓存结果而不是再次计算.这在以下场景下是很实用的:

  • 如果计算一个属性值会花费很多代价(占取很多随机内容,消耗CPU时间,产生大量工作线程,检索远程文件,等)
  • 属性值目前暂时不会用到,而是之后才会用到,甚至一直都用不到.
  • 如果它要被多次使用到,但是这个值不会变化,每次都不需要重新计算,甚至不能重新计算.

也就是说,如果某个属性值是可能会变化的,你就不能使用懒getter,因为它不会重新计算值.

在下面的这个例子里,对象有一个getter作为它的notifier属性,在获取属性的时候,这个属性被删除后再次添加,但新增属性所拥有的就是普通的属性值.最后这个值被返回.

get notifier() {
  delete this.notifier;
  return this.notifier = document.getElementById("bookmarked-notification-anchor");
},

查看原文


end