JavaScript provides primitive types and means of processing those. However, those are not enough. Real data must somehow come into the program and data must somehow leave the program, for it to become useful to us. In this talk, we will see how two abstractions are essential for data flow and to build up other abstractions, such as Iterator, Iterable, Observable, Scheduling, and others. Talk

Getter as abstractions:

const ten = ;

// Abstractions
// Laziness
const getTen = () => { console.log("hi"); // hook for side effects // Implementation flexibility
return + ;
// return 2 * 5;
// return 10
}

Benefits:

  • First of all: 'getTen' if you don't call the function, the calcuation inside the fucntion never run.
  • You can do any side effects inside function.
  • Implmentation flexibility, you can do different ways to aecieve the same effects.

Think about this code:

function add(getX, getY) {
const x = getX();
const y = getY();
return x + y;
}

'getX' and 'getY' are abstract. What we are doing now is adding two abstract number in concrete world. What if we add in abstract world?

function add(getX, getY) {
return () => { // put code into a get getter function
const x = getX();
const y = getY();
return x + y;
}
}

Now the function are complete lazy, lazyniess is a good thing, when you have some lzay you use getter can make things concrete.

function add(getX, getY) {
return () => {
const x = getX();
const y = getY();
return x + y;
}
} const getTen = () => ;
const getY = Math.random; const getSum = add(getTen, getY); // so far no calcuation happens

Lazy initialization and lazy iteration:

let i = ;
const array = [,,,];
function getArrayItem() {
// lazy iteration
return array[i++];
} console.log(getArrayItem());
console.log(getArrayItem());
console.log(getArrayItem());
console.log(getArrayItem());
console.log(getArrayItem()); // undefined

This is a concrete example, we call the fucntion mutiplue time and loop though the array.

And we also see that after call result as 'undefined', if we want to loop the array again from zero idnex, we have to do:

let i = ;
const array = [,,,];
function getArrayItem() {
// lazy iteration
return array[i++];
} console.log(getArrayItem());
console.log(getArrayItem());
console.log(getArrayItem());
console.log(getArrayItem()); i = ;
console.log(getArrayItem());
console.log(getArrayItem());
console.log(getArrayItem());
console.log(getArrayItem());

We call

i = ;

Of course this is not good at all, we leak the information.

The way to improve it is by using getter & lazyniess:

function getGetArrayItem() {
// lazy initialization
let i = ;
const array = [,,,];
return function() {
// lazy iteration
return array[i++];
}
} let getArrayItem = getGetArrayItem(); console.log(getArrayItem());
console.log(getArrayItem());
console.log(getArrayItem());
console.log(getArrayItem()); getArrayItem = getGetArrayItem(); console.log(getArrayItem());
console.log(getArrayItem());
console.log(getArrayItem());
console.log(getArrayItem());

getter-getter: Abstract List:

Think about the following example:

function range(left, right) {

  return () => {
// lazy initialization
let x = left;
return () => {
// lazy iteration
if (x > right) {
return undefined;
}
return x++;
}
}
} const getGet = range( , );
const get = getGet(); console.log(get()); //
console.log(get());
console.log(get());
console.log(get());
console.log(get()); //
console.log(get()); // undefined
console.log(get());
console.log(get());

It prints out the range of nuber, which we defined, we can notice after the right limit of the number, it just print out undefined.

One way to solve the undefined problem is using for loop:

function range(left, right) {

  return () => {
// lazy initialization
let x = left;
return () => {
// lazy iteration
if (x > right) {
return undefined;
}
return x++;
}
}
} const getGet = range( , ); for(let get = getGet(), x = get(); x !== undefined; x = get()) {
console.log(x) // 10 ... 14
}

The good thing about this code is that no matter how large the range it is, the menory size is always 1. Every time you call the fucntion, it pull one value from the abstract getter function every time. It makes CPU and memory efficient.


Completion markers:

function range(left, right) {

  return () => {
// lazy initialization
let x = left;
return () => {
// lazy iteration
if (x > right) {
return {done: true};
}
return {done: false, value: x++};
}
}
} const getGet = range(, ); for(let get = getGet(), res = get(); !res.done; res = get()) {
console.log(res.value) // 10 ... 14
}

We added {done: true | false} as a complete marker.


Convert to Symbol.iterator:

function range(left, right) {

  return {
[Symbol.iterator]: () => {
// lazy initialization
let x = left;
return {
next: () => {
// lazy iteration
if (x > right) {
return {done: true};
}
return {done: false, value: x++};
}
}
}
}
}

Javascript notice that when you are using [Symbol.iterator] and have  'next' inside, then it provides you a nice syntax to loop over the iterator and get the value of out it.

for(let x of range(, )) {
console.log(x) // 10 ... 14
}

We might have done this:

function range(left, right) {

  return {
[Symbol.iterator]: () => {
// lazy initialization
let x = left;
return {
next: () => {
// lazy iteration
if (x > right) {
return {done: true};
}
return {done: false, value: x++};
}
}
}
}
} for(let x of range(,)) {
if(x % === ) {
console.log(x)
}
}

We using 'if' inside 'for' loop, well it is nothing wrong, but we can do better. Because range() is abstract function, we don't need to pull all the value done to the concrete world to do the filtering, we can also do the filtering in abstract function.

const filter = pred => iterations => {
let z = [];
for (let x of iterations) {
if(pred(x)) z.push(x);
}
return z;
}; function range(left, right) { return {
[Symbol.iterator]: () => {
// lazy initialization
let x = left;
return {
next: () => {
// lazy iteration
if (x > right) {
return {done: true};
}
return {done: false, value: x++};
}
}
}
}
} for(let x of filter(x => x % === )(range(,))) {
console.log(x)
}

Setter-setter abstraction:

You can think of "setter-setter" is callback:

const setSetTen = (setTen) => {
setTen()
} setSetTen(console.log) //

The benifits of doing setter-setter is

  • Async
  • Inversion of control
const setSetTen = (setTen) => {
setTimeout(() => {
//Async
setTen()
}, ) } setSetTen(console.log) //

Setter-setter to Observable:

[Javascript] Getter and Setter Abstractions的更多相关文章

  1. JavaScript getter and setter All In One

    JavaScript getter and setter All In One getter & setter JavaScript Object Accessors JavaScript A ...

  2. JavaScript getter和setter

    对象的属性是由属性名name,值key,和其他特性(可读写性 writable,可枚举性enumerable,可配置性configurable)组成的.从ES5开发,提供了getter和setter ...

  3. javascript的getter和setter(转)

    显然这是一个无关IE(高级IE除外)的话题,尽管如此,有兴趣的同学还是一起来认识一下ECMAScript5标准中getter和setter的实现.在一个对象中,操作其中的属性或方法,通常运用最多的就是 ...

  4. JavaScript中闭包实现的私有属性的getter()和setter()方法

    注意: 以下的输出都在浏览器的控制台中 <!DOCTYPE html> <html> <head> <meta charset="utf-8&quo ...

  5. javascript中的function命名空間與模擬getter、setter

    function的命名空間 在javascript中,function也可以擁有自己的命名空間例如以下這段程式碼: 12345678 function () { return 'I am A';} A ...

  6. javascript权威指南笔记--javascript语言核心(五)--getter和setter属性

    getter和setter属性: var p = { x:1.0, y:1.0, get r(){ return Math.sqrt(this.x*this.x + this.y * this.y); ...

  7. javascript中的getter和setter

    在ECMAScript 5中,属性值可以用一个或两个方法代替,这两个方法就是getter和setter var man = { name : 'lidg', weibo : '@lidg', get ...

  8. 基于 getter 和 setter 撸一个简易的MVVM

    Angular 和 Vue 在对Angular的学习中,了解到AngularJS 的两个主要缺点: 对于每一次界面时间,Ajax 或者 timeout,都会进行一个脏检查,而每一次脏检查又会在内部循环 ...

  9. js中的访问器属性中的getter和setter函数实现数据双向绑定

    嗯,之前在读js红宝书的时候,在对象那一章有介绍属性类型.第一种数据类型指的是数据属性,第二种是访问器属性.在初识vue的时候,其双向数据绑定也是基于访问器属性中的getter和setter函数原理来 ...

随机推荐

  1. JDK5.0新特性(静态导入、自动装箱/拆箱、增强for循环、可变参数、枚举、泛形)

    JDK5中新增了很多新的java特性,利用这些新语法可以帮助开发人员编写出更加高效.清晰,安全的代码. 这些新特性主要有:1.静态导入2.自动装箱/拆箱3.增强for循环4.可变参数5.枚举6.泛型7 ...

  2. hdu3507Print Article(斜率优化dp)

    Print Article Time Limit: 9000/3000 MS (Java/Others)    Memory Limit: 131072/65536 K (Java/Others)To ...

  3. python 线程池和锁

    一.死锁现象与递归锁 锁:Lock线程安全,多线程操作时,内部会让所有线程排队处理.如:list/dict/Queue        线程不安全 + 人 => 排队处理. import thre ...

  4. HTML <!DOCTYPE>标签

    一般一个基本html页面的结构,如下代码所示: <html> <head> <title>我是基本的页面结构</title> </head> ...

  5. angularJS之ng-bind与{{}}取值的区别

    1:{{ }} 是等页面加载完后,再取值. 2:ng-bind 它是在页面加载的时候,是不会显示{{name}}这种变量出来. 3:ng-bind 可以解决 ng 页面闪烁加载问题. 4:ng-bin ...

  6. mysql数据库之存储过程入门

    引用:百度百科 存储过程 存储过程(Stored Procedure)是在大型数据库系统中,一组为了完成特定功能的SQL 语句集,存储在数据库中,经过第一次编译后再次调用不需要再次编译,用户通过指定存 ...

  7. 【Oracle】进入sqlplus 删除键backspace时出现^H

    当oracle进入sqlplus后,输入命令时候出现错误,我们按平时的习惯使用backspace键删除错误信息,此时会出现^H 解决办法:进入sqlplus之前,使用stty erase '^H'命令 ...

  8. linux 清空文件的几种方案

    之前要清理文件,都是简单粗暴的rm -rf log文件,最近,发现在某些环境下,是不能删除文件本省的,又必须要清理文件的内容信息,经过亲自实验,目测以下的几种方案是可行的,方案如下: 1.采用vi命令 ...

  9. 作业08之《MVC实现用户权限》

    1. 赋给用户一个userid,在用户角色表将用户和角色关联起来,在角色权限表中将角色和权限对应起来,权限表中存储的是左边菜单栏的名称. 2. 在判断权限时,通过用户的userid,获取其角色id,然 ...

  10. (转)基于openlayers实现聚类统计展示

    http://blog.csdn.net/gisshixisheng/article/details/46137015 概述: 在前面的博文中讲述过基于Arcgis for js如何实现聚类统计展示, ...