From aa30945f1bc00a7d802847d62868792a969f3672 Mon Sep 17 00:00:00 2001 From: Ruan Yifeng Date: Thu, 5 Feb 2015 23:08:48 +0800 Subject: [PATCH] =?UTF-8?q?=E4=BF=AE=E6=94=B9object/proxy?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- docs/let.md | 13 +++++++++++++ docs/object.md | 35 ++++++++++++++++++++++++++++++++++- docs/reference.md | 4 +++- 3 files changed, 50 insertions(+), 2 deletions(-) diff --git a/docs/let.md b/docs/let.md index 7e68627..0f8064a 100644 --- a/docs/let.md +++ b/docs/let.md @@ -75,6 +75,19 @@ function do_something() { 上面代码在声明foo之前,就使用这个变量,结果会抛出一个错误。 +这也意味着typeof不再是一个百分之百安全的操作。 + +```javascript + +if (1) { + typeof x; // ReferenceError + let x; +} + +``` + +上面代码中,由于块级作用域内typeof运行时,x还没有声明,所以会抛出一个ReferenceError。 + 注意,let不允许在相同作用域内,重复声明同一个变量。 ```javascript diff --git a/docs/object.md b/docs/object.md index f6451fc..44ae792 100644 --- a/docs/object.md +++ b/docs/object.md @@ -590,7 +590,7 @@ obj.time // 35 上面代码中,proxy对象是obj对象的原型,obj对象本身并没有time属性,所有根据原型链,会在proxy对象上读取该属性,导致被拦截。 -对于没有设置拦截的操作,则直接落在目标函数上,按照原先的方式产生结果。 +对于没有设置拦截的操作,则直接落在目标对象上,按照原先的方式产生结果。 下面是另一个拦截读取操作的例子。 @@ -617,6 +617,39 @@ proxy.age // 抛出一个错误 上面代码表示,如果访问目标对象不存在的属性,会抛出一个错误。如果没有这个拦截函数,访问不存在的属性,只会返回undefined。 +利用proxy,可以将读取属性的操作(get),转变为执行某个函数。 + +```javascript + +var pipe = (function () { + var pipe; + return function (value) { + pipe = []; + return new Proxy({}, { + get: function (pipeObject, fnName) { + if (fnName == "get") { + return pipe.reduce(function (val, fn) { + return fn(val); + }, value); + } + pipe.push(window[fnName]); + return pipeObject; + } + }); + } +}()); + +var double = function (n) { return n*2 }; +var pow = function (n) { return n*n }; +var reverseInt = function (n) { return n.toString().split('').reverse().join('')|0 }; + +pipe(3) . double . pow . reverseInt . get +// 63 + +``` + +上面代码设置Proxy以后,达到了将函数名链式使用的效果。 + 除了取值函数get,Proxy还可以设置存值函数set,用来拦截某个属性的赋值行为。假定Person对象有一个age属性,该属性应该是一个不大于200的整数,那么可以使用Proxy对象保证age的属性值符合要求。 ```javascript diff --git a/docs/reference.md b/docs/reference.md index 81a3589..0bb3e72 100644 --- a/docs/reference.md +++ b/docs/reference.md @@ -24,7 +24,8 @@ ## 语法点 -- Kyle Simpson, [For and against `let`](http://davidwalsh.name/for-and-against-let): 讨论let命令的作用域 +- Kyle Simpson, [For and against `let`](http://davidwalsh.name/for-and-against-let): 讨论let命令的作用域 +- kangax, [Why `typeof` is no longer “safe”](http://es-discourse.com/t/why-typeof-is-no-longer-safe/15): 讨论在块级作用域内,let命令的变量声明和赋值的行为 - Nick Fitzgerald, [Destructuring Assignment in ECMAScript 6](http://fitzgeraldnick.com/weblog/50/): 详细介绍解构赋值的用法 - Nicholas C. Zakas, [Understanding ECMAScript 6 arrow functions](http://www.nczonline.net/blog/2013/09/10/understanding-ecmascript-6-arrow-functions/) - Jack Franklin, [Real Life ES6 - Arrow Functions](http://javascriptplayground.com/blog/2014/04/real-life-es6-arrow-fn/) @@ -48,6 +49,7 @@ - Sella Rafaeli, [Native JavaScript Data-Binding](http://www.sellarafaeli.com/blog/native_javascript_data_binding): 如何使用Object.observe方法,实现数据对象与DOM对象的双向绑定 - Axel Rauschmayer, [Symbols in ECMAScript 6](http://www.2ality.com/2014/12/es6-symbols.html): Symbol简介 - Axel Rauschmayer, [Meta programming with ECMAScript 6 proxies](http://www.2ality.com/2014/12/es6-proxies.html): Proxy详解 +- Daniel Zautner, [Meta-programming JavaScript Using Proxies](http://dzautner.com/meta-programming-javascript-using-proxies/):使用Proxy实现元编程 ## Iterator和Generator