diff --git a/docs/generator.md b/docs/generator.md index 184f6d1..3ca20ab 100644 --- a/docs/generator.md +++ b/docs/generator.md @@ -1173,7 +1173,7 @@ Generator函数的暂停执行的效果,意味着可以把异步操作写在yi function* loadUI() { showLoadingScreen(); yield loadUIDataAsynchronously(); - hideLoadingScreen(); + hideLoadingScreen(); } var loader = loadUI(); // 加载UI diff --git a/docs/proxy.md b/docs/proxy.md index 6095d2a..b188510 100644 --- a/docs/proxy.md +++ b/docs/proxy.md @@ -137,45 +137,41 @@ fproxy.foo; // 'Hello, foo' 拦截`for (var x in proxy)`,返回一个遍历器。 -**(6)has(target, propKey)** - -拦截`in`运算符,返回一个布尔值。 - -**(7)ownKeys(target)** +**(6)ownKeys(target)** 拦截`Object.getOwnPropertyNames(proxy)`、`Object.getOwnPropertySymbols(proxy)`、`Object.keys(proxy)`,返回一个数组。该方法返回对象所有自身的属性,而`Object.keys()`仅返回对象可遍历的属性。 -**(8)getOwnPropertyDescriptor(target, propKey)** +**(7)getOwnPropertyDescriptor(target, propKey)** 拦截`Object.getOwnPropertyDescriptor(proxy, propKey)`,返回属性的描述对象。 -**(9)defineProperty(target, propKey, propDesc)** +**(8)defineProperty(target, propKey, propDesc)** 拦截`Object.defineProperty(proxy, propKey, propDesc)`、`Object.defineProperties(proxy, propDescs)`,返回一个布尔值。 -**(10)preventExtensions(target)** +**(9)preventExtensions(target)** 拦截`Object.preventExtensions(proxy)`,返回一个布尔值。 -**(11)getPrototypeOf(target)** +**(10)getPrototypeOf(target)** 拦截`Object.getPrototypeOf(proxy)`,返回一个对象。 -**(12)isExtensible(target)** +**(11)isExtensible(target)** 拦截`Object.isExtensible(proxy)`,返回一个布尔值。 -**(13)setPrototypeOf(target, proto)** +**(12)setPrototypeOf(target, proto)** 拦截`Object.setPrototypeOf(proxy, proto)`,返回一个布尔值。 如果目标对象是函数,那么还有两种额外操作可以拦截。 -**(14)apply(target, object, args)** +**(13)apply(target, object, args)** 拦截Proxy实例作为函数调用的操作,比如`proxy(...args)`、`proxy.call(object, ...args)`、`proxy.apply(...)`。 -**(15)construct(target, args, proxy)** +**(14)construct(target, args, proxy)** 拦截Proxy实例作为构造函数调用的操作,比如`new proxy(...args)`。 diff --git a/docs/set-map.md b/docs/set-map.md index 0169068..64d43e8 100644 --- a/docs/set-map.md +++ b/docs/set-map.md @@ -13,7 +13,7 @@ var s = new Set(); [2,3,5,4,5,2,2].map(x => s.add(x)) -for (i of s) {console.log(i)} +for (let i of s) {console.log(i)} // 2 3 5 4 ``` @@ -358,7 +358,7 @@ class Foo { } ``` -上面代码保证了`Foo`的实例方法,只能在`Foo`的实例上调用。这里使用WeakSet的好处是,数组`foos`对实例的引用,不会被计入内存回收机制,所以删除实例的时候,不用考虑`foos`,也不会出现内存泄漏。 +上面代码保证了`Foo`的实例方法,只能在`Foo`的实例上调用。这里使用WeakSet的好处是,`foos`对实例的引用,不会被计入内存回收机制,所以删除实例的时候,不用考虑`foos`,也不会出现内存泄漏。 ## Map diff --git a/docs/simd.md b/docs/simd.md new file mode 100644 index 0000000..e36e23f --- /dev/null +++ b/docs/simd.md @@ -0,0 +1,33 @@ +# SIMD 的用法 + +SIMD是“Single Instruction/Multiple Data”的缩写,意为“单指令,多数据”。它是JavaScript操作CPU对应指令的接口,你可以看做这是一种不同的运算执行模式。与它相对的是SISD(“Single Instruction/Single Data”),即“单指令,单数据”。 + +SIMD的含义是使用一个指令,完成多个数据的运算;SISD的含义是使用一个指令,完成单个数据的运算,这是JavaScript的默认运算模式。显而易见,SIMD的执行效率要高于SISD,所以被广泛用于3D图形运算、物理模拟等运算量超大的项目之中。 + +为了理解SIMD,请看下面的例子。 + +```javascript +var a = [1, 2, 3, 4]; +var b = [5, 6, 7, 8]; +var c = []; + +c[0] = a[0] + b[0]; +c[1] = a[1] + b[1]; +c[2] = a[2] + b[2]; +c[3] = a[3] + b[3]; +c; // Array[6, 8, 10, 12] +``` + +上面代码中,数组`a`和`b`的对应成员相加,结果放入数组`c`。它的运算模式是依次处理每个数组成员,一共有四个数组成员,所以需要运算4次。 + +如果采用SIMD模式,只要运算一次就够了。 + +```javascript +var a = SIMD.Float32x4(1, 2, 3, 4); +var b = SIMD.Float32x4(5, 6, 7, 8); +var c = SIMD.Float32x4.add(a,b); // Float32x4[6, 8, 10, 12] +``` + +上面代码之中,数组`a`和`b`的四个成员的各自相加,只用一条指令就完成了。因此,速度比上一种写法提高了4倍。 + +一次SIMD运算,可以处理多个数据,这些数据被称为“通道”(lane)。上面代码中,一次运算了四个数据,因此就是四个通道。