2018年10月30日 星期二

about js Generator

判斷一個function 是否是generator 的方法

var x  = function * (){yield undefined;}
console.log(x.constructor.name === 'GeneratorFunction')
-------------------------------------------------------------------
The function* declaration (function keyword followed by an asterisk) defines a generator function, which returns a Generator object.
You can also define generator functions using the GeneratorFunction constructor, or the function expression syntax.

Syntax

Section

function* name([param[, param[, ... param]]]) {
   statements
}
name
The function name.
param
The name of a formal parameter for the function.
statements
The statements comprising the body of the function.

Description

Section

Generators are functions which can be exited and later re-entered. Their context (variable bindings) will be saved across re-entrances.

Generators in JavaScript -- especially when combined with Promises -- are a very powerful tool for asynchronous programming as they mitigate -- if not entirely eliminate -- the problems with callbacks, such as Callback Hell and Inversion of Control.
This pattern is what async functions are built on top of.
Calling a generator function does not execute its body immediately; an iterator object for the function is returned instead. When the iterator's next() method is called, the generator function's body is executed until the first yield expression, which specifies the value to be returned from the iterator or, with yield*, delegates to another generator function. The next() method returns an object with a value property containing the yielded value and a done property which indicates whether the generator has yielded its last value as a boolean. Calling the next() method with an argument will resume the generator function execution, replacing the yield expression where execution was paused with the argument from next().
A return statement in a generator, when executed, will make the generator finished (i.e the done property of the object returned by it will be set to true). If a value is returned, it will be set as the value property of the object returned by the generator.
Much like a return statement, an error thrown inside the generator will make the generator finished -- unless caught within the generator's body.
When a generator is finished, subsequent next calls will not execute any  of that generator's code, they will just return an object of this form: {value: undefined, done: true}.

Examples

Section

Simple example

Section

function* idMaker() {
  var index = 0;
  while (index < index+1)
    yield index++;
}

var gen = idMaker();

console.log(gen.next().value); // 0
console.log(gen.next().value); // 1
console.log(gen.next().value); // 2
console.log(gen.next().value); // 3
// ...

Example with yield*

Section

function* anotherGenerator(i) {
  yield i + 1;
  yield i + 2;
  yield i + 3;
}

function* generator(i) {
  yield i;
  yield* anotherGenerator(i);
  yield i + 10;
}

var gen = generator(10);

console.log(gen.next().value); // 10
console.log(gen.next().value); // 11
console.log(gen.next().value); // 12
console.log(gen.next().value); // 13
console.log(gen.next().value); // 20

Passing arguments into Generators

Section

function* logGenerator() {
  console.log(0);
  console.log(1, yield);
  console.log(2, yield);
  console.log(3, yield);
}

var gen = logGenerator();

// the first call of next executes from the start of the function
// until the first yield statement
gen.next();             // 0
gen.next('pretzel');    // 1 pretzel
gen.next('california'); // 2 california
gen.next('mayonnaise'); // 3 mayonnaise

Return statement in a generator

Section

function* yieldAndReturn() {
  yield "Y";
  return "R";
  yield "unreachable";
}

var gen = yieldAndReturn()
console.log(gen.next()); // { value: "Y", done: false }
console.log(gen.next()); // { value: "R", done: true }
console.log(gen.next()); // { value: undefined, done: true }

Generators are not constructable

Section

function* f() {}
var obj = new f; // throws "TypeError: f is not a constructor

Generator defined in an expression

Section

const foo = function* () {
  yield 10;
  yield 20;
};

const bar = foo();
console.log(bar.next()); // {value: 10, done: false}
 
-------------------------------------------
 
The Generator object is returned by a generator function and it conforms to both the iterable protocol and the iterator protocol.

Syntax

區段

function* gen() { yield 1; yield 2; yield 3; } var g = gen(); // "Generator { }"

Methods

區段

Generator.prototype.next()
Returns a value yielded by the yield expression.
Generator.prototype.return()
Returns the given value and finishes the generator.
Generator.prototype.throw()
Throws an error to a generator (also finishes the generator, unless caught from within that generator).

Example

區段

An infinite iterator

區段

function* idMaker() {  
    var index = 0;  
    while(true) yield index++; 
}  

var gen = idMaker(); // "Generator { }" console.log(gen.next().value); // 0 

console.log(gen.next().value); // 1 console.log(gen.next().value); // 2 // ...

Legacy generator objects

區段

Firefox (SpiderMonkey) also implemented an earlier version of generators in JavaScript 1.7, where the star (*) in the function declaration was not necessary (you just use the yield keyword in the function body). However, legacy generators support has been removed since Firefox 58 (released on January 23, 2018) (bug 1083482).

Legacy generator methods

區段

Generator.prototype.next()
Returns a value yielded by the yield expression. This corresponds to next() in the ES2015 generator object.
Generator.prototype.close()
Closes the generator, so that when calling next() an StopIteration error will be thrown. This corresponds to the return() method in the ES2015 generator object.
Generator.prototype.send()
Used to send a value to a generator. The value is returned from the yield expression, and returns a value yielded by the next yield expression. send(x) corresponds to next(x) in the ES2015 generator object.
Generator.prototype.throw()
Throws an error to a generator. This corresponds to the throw() method in the ES2015 generator object.

Legacy generator example

區段

function* fibonacci() { var a = yield 1; yield a * 2; }  

var it = fibonacci(); 

console.log(it); // "Generator { }" console.log(it.next()); // 1 

console.log(it.send(10)); // 20 console.log(it.close()); // undefined 
console.log(it.next()); // throws StopIteration (as the generator is now closed)
 



2018年10月25日 星期四

java String, char 間的轉換

String str = "abc";
char[] bm;

// String 轉 char[]
bm = str.toCharArray();

// char[] 轉 String
str = String.valueOf(bm);

簡化 java System.out.print.*

import static java.lang.System.out;
//////////////////////////////////////////////////////
package com.xyz.util;

import java.io.*;

/**
 *
 * @author xman
 */
public class Out {

    public static void println(Object obj) {
        System.out.println(obj);
    }
    //--------------------------------------------------------------------------
    // 换行输出
    public static void println() {
        System.out.println();
    }
    //--------------------------------------------------------------------------
    // 不换行输出,
    public static void print(Object obj) {
        System.out.print(obj);
    }
    //--------------------------------------------------------------------------
    public static void printf(String format, Object... args) {
        System.out.printf(format, args);
    }
}

2018年10月17日 星期三

visual studio code debbuger

{
    // 使用 IntelliSense 以得知可用的屬性。
    // 暫留以檢視現有屬性的描述。
    // 如需詳細資訊,請瀏覽: https://go.microsoft.com/fwlink/?linkid=830387
    "version": "0.2.0",
    "configurations": [
        {
            "type": "java",
            "name": "java Debug (Launch)",
            "request": "launch",
            "cwd": "${workspaceFolder}",
            "console": "internalConsole",
            "stopOnEntry": false,
            "mainClass": "",
            "args": ""
        },
        {
            "name": "nodejs Launch Program",
            "type": "node",
            "request": "launch",
            "program": "${workspaceFolder}/app.js"
        },
        {
            "name": "nodejs: Current File",
            "type": "node",
            "request": "launch",
            "program": "${file}"
        },
        {
            "name": "Python: Current File (Integrated Terminal)",
            "type": "python",
            "request": "launch",
            "program": "${file}",
            "console": "integratedTerminal"
        },
        {
            "name": "Python: Attach",
            "type": "python",
            "request": "attach",
            "port": 5678,
            "host": "localhost"
        },
        {
            "name": "Python: Django",
            "type": "python",
            "request": "launch",
            "program": "${workspaceFolder}/manage.py",
            "console": "integratedTerminal",
            "args": [
                "runserver",
                "--noreload",
                "--nothreading"
            ],
            "django": true
        },
        {
            "name": "Python: Flask",
            "type": "python",
            "request": "launch",
            "module": "flask",
            "env": {
                "FLASK_APP": "app.py"
            },
            "args": [
                "run",
                "--no-debugger",
                "--no-reload"
            ],
            "jinja": true
        },
        {
            "name": "Python: Current File (External Terminal)",
            "type": "python",
            "request": "launch",
            "program": "${file}",
            "console": "externalTerminal"
        }
    ]
}

2018年10月11日 星期四

underscore, lodash 間的差異

https://github.com/lodash/lodash/wiki/Migrating

let fixList = [
        "collect",
        "inject",
        "foldl",
        "foldr",
        "detect",
        "select",
        "all",
        "any",
        "include",
        "contains",
        "pluck",
        "where",
        'findWhere',
        "indexBy",
        "unique",
        "object",
        "compose",
        "restArguments",
        "allKeys",
        "mapObject",
        "pairs",
        "methods",
        "extendOwn",
        "matcher"
    ]
  • Underscore _.any is Lodash _.some
  • Underscore _.all is Lodash _.every
  • Underscore _.compose is Lodash _.flowRight
  • Underscore _.contains is Lodash _.includes
  • Underscore _.each doesn’t allow exiting by returning false
  • Underscore _.findWhere is Lodash _.find
  • Underscore _.flatten is deep by default while Lodash is shallow
  • Underscore _.indexOf with 3rd parameter undefined is Lodash _.indexOf
  • Underscore _.indexOf with 3rd parameter true is Lodash _.sortedIndexOf
  • Underscore _.indexBy is Lodash _.keyBy
  • Underscore _.invoke is Lodash _.invokeMap
  • Underscore _.mapObject is Lodash _.mapValues
  • Underscore _.max combines Lodash _.max & _.maxBy
  • Underscore _.min combines Lodash _.min & _.minBy
  • Underscore _.sample combines Lodash _.sample & _.sampleSize
  • Underscore _.object combines Lodash _.fromPairs and _.zipObject
  • Underscore _.omit by a predicate is Lodash _.omitBy
  • Underscore _.pairs is Lodash _.toPairs
  • Underscore _.pick by a predicate is Lodash _.pickBy
  • Underscore _.pluck is Lodash _.map
  • Underscore _.uniq by an iteratee is Lodash _.uniqBy
  • Underscore _.where is Lodash _.filter
  • Underscore _.isFinite doesn’t align with Number.isFinite
    (e.g. _.isFinite('1') returns true in Underscore but false in Lodash)
  • Underscore _.matches shorthand doesn’t support deep comparisons
    (e.g. _.filter(objects, { 'a': { 'b': 'c' } }))
  • Underscore ≥ 1.7 & Lodash _.template syntax is
    _.template(string, option)(data)
  • Lodash _.memoize caches are Map like objects
  • Lodash doesn’t support a context argument for many methods in favor of _.bind
  • Lodash supports implicit chaining, lazy chaining, & shortcut fusion
  • Lodash split its overloaded _.head, _.last, _.rest, & _.initial out into
    _.take, _.takeRight, _.drop, & _.dropRight
    (i.e. _.head(array, 2) in Underscore is _.take(array, 2) in Lodash)

2018年10月8日 星期一

javascript Object.create() 原意

if (typeof Object.create !== "function") {
    Object.create = function (proto, propertiesObject) {
        if (!(proto === null || typeof proto === "object" || typeof proto === "function")) {
            throw TypeError('Argument must be an object, or null');
        }
        var temp = new Object();
        temp.__proto__ = proto;
        if(typeof propertiesObject === "object")
            Object.defineProperties(temp, propertiesObject);
        return temp;
    };
}
-----------------------------------------------------------------
o = {};
// 等同於:
o = Object.create(Object.prototype);


// Example where we create an object with a couple of sample properties.
// (Note that the second parameter maps keys to *property descriptors*.)
o = Object.create(Object.prototype, {
  // foo 為數值屬性
  foo: { writable: true, configurable: true, value: 'hello' },
  // bar 為 getter-and-setter 訪問屬性
  bar: {
    configurable: false,
    get: function() { return 10; },
    set: function(value) { console.log('Setting `o.bar` to', value); }
/* with ES5 Accessors our code can look like this
    get function() { return 10; },
    set function(value) { console.log('setting `o.bar` to', value); } */
  }
});


function Constructor() {}
o = new Constructor();
// 等同於:
o = Object.create(Constructor.prototype);
// Of course, if there is actual initialization code in the
// Constructor function, the Object.create() cannot reflect it


// 創建一個新物件,指定原型是全新的空物件,並加入值為 42 的屬性'p'
o = Object.create({}, { p: { value: 42 } }); 

2018年10月6日 星期六

js library

https://github.com/tweenjs/tween.js

https://github.com/brehaut/color-js

https://github.com/dankogai/js-base64


// lodash, underscore
http://eng.rightscale.com/2015/01/22/lodash-extensions.html
https://www.npmjs.com/package/lodash-extensions
https://www.npmjs.com/package/underscore-extensions
https://github.com/gmmorris/underscorepp

// router
Page.js [https://github.com/visionmedia/page.js]
Director [https://github.com/flatiron/director]

// 動畫對列
https://aerotwist.com/blog/flip-your-animations/ 
https://github.com/googlearchive/flipjs 

https://github.com/wilsonpage/fastdom 

http://adrai.github.io/flowchart.js

https://github.com/evanw 

https://piconion.com/
 http://www.csie.ntnu.edu.tw/~u91029/Curve.html
 


http://baidufe.github.io/BaiduTemplate/
https://github.com/wangxiao/BaiduTemplate 

http://chutsu.github.io/ditto/#docs/how_do_i_use_ditto 

https://github.com/BorisMoore/jquery-tmpl 

https://github.com/yahoo/serialize-javascript 

https://johnresig.com/blog/javascript-micro-templating/ 

https://www.puritys.me/docs-blog/article-142-%E7%AC%AC%E4%B8%80%E7%AF%87-Node.js-%E6%90%AD%E9%85%8D-Apache-CGI.html

https://www.puritys.me/docs-blog/article-144-%E7%AC%AC%E4%BA%8C%E7%AF%87-Node.js-%E6%90%AD%E9%85%8D-Apache---Header-%E8%99%95%E7%90%86.html

https://www.puritys.me/docs-blog/article-201-Node.js-%E4%BD%BF%E7%94%A8-php-function.html 

https://www.npmjs.com/package/workerpool
https://www.npmjs.com/package/node-workers-pool
https://www.slideshare.net/mgornstein/minion-pool-a-worker-pool-for-nodejs 

2018年10月2日 星期二

jquery 靜態工具

camelCase: 把 style key 化為駝峰

cleanData: 清除  $.data() 資料

cssHooks:  css 設定提取所需要的特殊處理

cssNumber:  哪些 css 是數值類

attrHooks:  處理頑疾 attr

support:  檢測瀏覽器的支援

valHooks:  針對 table value

contains(context, elem):  context 是否包含 elem

easing:  動畫用的運動函式

$.css:

$.style:

parseHTML(內文, context, option): context 通常指 document, option 若內文含 script 是否要執行