[Javascript] Getter and Setter Abstractions
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的更多相关文章
- JavaScript getter and setter All In One
JavaScript getter and setter All In One getter & setter JavaScript Object Accessors JavaScript A ...
- JavaScript getter和setter
对象的属性是由属性名name,值key,和其他特性(可读写性 writable,可枚举性enumerable,可配置性configurable)组成的.从ES5开发,提供了getter和setter ...
- javascript的getter和setter(转)
显然这是一个无关IE(高级IE除外)的话题,尽管如此,有兴趣的同学还是一起来认识一下ECMAScript5标准中getter和setter的实现.在一个对象中,操作其中的属性或方法,通常运用最多的就是 ...
- JavaScript中闭包实现的私有属性的getter()和setter()方法
注意: 以下的输出都在浏览器的控制台中 <!DOCTYPE html> <html> <head> <meta charset="utf-8&quo ...
- javascript中的function命名空間與模擬getter、setter
function的命名空間 在javascript中,function也可以擁有自己的命名空間例如以下這段程式碼: 12345678 function () { return 'I am A';} A ...
- 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); ...
- javascript中的getter和setter
在ECMAScript 5中,属性值可以用一个或两个方法代替,这两个方法就是getter和setter var man = { name : 'lidg', weibo : '@lidg', get ...
- 基于 getter 和 setter 撸一个简易的MVVM
Angular 和 Vue 在对Angular的学习中,了解到AngularJS 的两个主要缺点: 对于每一次界面时间,Ajax 或者 timeout,都会进行一个脏检查,而每一次脏检查又会在内部循环 ...
- js中的访问器属性中的getter和setter函数实现数据双向绑定
嗯,之前在读js红宝书的时候,在对象那一章有介绍属性类型.第一种数据类型指的是数据属性,第二种是访问器属性.在初识vue的时候,其双向数据绑定也是基于访问器属性中的getter和setter函数原理来 ...
随机推荐
- css3 文本模型
我前期是一名前端开发者,经常会遇到关于文本模型的问题,很多地方我们会经常遇到这种问题.例如栏目的标题,在设计师给我们图的时候并不会考虑到标题的长度,所以我们自己开发的过程中自己注意这一点. 首先和大家 ...
- Android开发中的日期格式化
下面的转换符来自Java,但是在android中同样可用.(以下表格内容来自互联网.) 常见日期格式化转换符 转换符 说 明 示 例 %te 一个月中的某一天(1-31) 2 %tb 指定语言环 ...
- 微信图片不可显示java解决方法
先看知乎:https://www.zhihu.com/question/35044484 场景: 微信上传了图片素材,返回了图片url,然后不能在img标签中正常显示. 原因是微信做了图片防盗连接. ...
- Linux安装java jdk、mysql、tomcat
安装javajdk 1.8 检查是否安装 rpm -qa | grep jdk rpm方式安装 下载java1.8 jdk http://download.oracle.com/otn-pub/jav ...
- 关于ListView中item与子控件抢夺焦点的解决方法
1.在开发中,listview可以说是我们使用最频繁的控件之一了,但是关于listview的各种问题也是很多.当我们使用自定义布局的Listview的时候,如果在item的布局文件里面存在Button ...
- js-内置对象及相关语法
1:如图(视频截取的) this指的是当前标签的对象. var ary=new Array("mark","jay","leslie"); ...
- 手动触发dom节点事件代码
在爬代码过程中,碰到一个稀奇古怪的问题.需要手工修改select的值,然后手动触发select的change事件,但使用网络上查到的通过trigger.onchange()事件触发都不执行,没办法,只 ...
- Sql语句优化-查询两表不同行NOT IN、NOT EXISTS、连接查询Left Join
在实际开发中,我们往往需要比较两个或多个表数据的差别,比较那些数据相同那些数据不相同,这时我们有一下三种方法可以使用:1. IN或NOT IN,2. EXIST或NOTEXIST,3.使用连接查询(i ...
- 【Oracle】删除手工创建的数据库
众所周知,DBCA创建的数据库可以通过DBCA命令删除,但是手工创建的数据库却不能用此方式删除,下面给出删除方式: SQL> startup mount exclusive SQL> al ...
- 【Oracle】redo与undo
一 .redo(重做信息) 是Oracle在线(或归档)重做日志文件中记录的信息,万一出现失败时可以利用这些数据来“重放”(或重做)事务.Oracle中记录这些信息的文件叫做redo log file ...