unhurried

コンピュータ関連ネタがほとんど、ときどき趣味も…

Mission Peak 春と夏の景色

ベイエリアでは11月頃~3月頃が雨季でこの期間はよく雨が降るのですが、それ以外の時期にはほとんど全くと言って良いほど雨が降りません。
サンノゼから少し北に行ったところにMission Peakという人気のハイキングトレイルがあり、この山は雨季に青々と成長した草が、夏には一気に枯れて茶色に変化します。
このわずか2、3ヵ月の間の変化を記録してみるとおもしろいのではと思い、春(4月)と夏(7月)に同じ場所から写真を撮って比較してみました。

f:id:unhurried:20170721153121j:plain:w500

f:id:unhurried:20170721153432j:plain:w500

f:id:unhurried:20170721153458j:plain:w500

参考

Load modules in Node.js

When we create modules in Node.js, we can use "module.exports" or "exports" objects. However, I didn't understand the difference of them. In this article I have sorted out when to use each object. Note: I don't mention the detailed difference of the two in this article, you can find it in the link described below.

Which to use, "module.exports" or "exports"?

Use "module.exports" to export single class function or object.

class MyClass {
    ...
}
module.exports = MyClass;

Use "exports" to export multiple functions or objects.

function myFunc1 {
    ...
}
function myFunc2 {
    ...
}
exports.myFunc1 = myFunc1;
exports.myFunc2 = myFunc2;

* "module.exports" can also be used, but using "exports" is simpler.

module.exports = {
    myFunc1: myFunc1,
    myFunc2: myFunc1
}

The behaivior when executing "require" mutilple times.

The script loaded by "require" is evaluatted only the first time and "require" returns cached object from the second time.

  • module.js
var _var = Math.random();
function func() {
    console.log(`module.js - func : _var=${_var}`)
}
exports.func = func;
  • main.js
const module1 = require('./module.js')
const module2 = require('./module.js')
module1.func()
module2.func()
  • Result
module.js - func : _var=0.7381836391077983
module.js - func : _var=0.7381836391077983

Reference

React Quick Start Cheat Sheet

I came up with a new web application idea, and I tried to use React in the development this time. Although React has a rich document for developers, I don't have good memory. Therefore I always take a note when I study a new library to remember the usage. I guess this note may be also useful for others, and like to share it in this article.

This time I made a sample program wrapping up React Quick Start. Also I have registered it sample code to CodePen: React Cheat Sheet.

// React Element

// Tag syntax like "<p> ... </p>" is called JSX, and JSX produces a React element.
// React elements are the descriptions of what you want to see on the screen.
// React elements are imuutable and they can't be changed once they are defined.
// (See following React components for how you can update the DOM.)
const singleLineElement = <p>Hello World.</p>;

// When you split JSX over multiple lines, 
// it is recommended to wrap it in parentheses to avoid automatic semicolon insertion by editors.
// Expressions can be embedded in JSX. (JSX itself is also an expression.)
// React escapes any values embedded in JSX before rendering them to prevent injection attacks.
const href = "https://www.time.gov/";
const multipleLinesElement = (
    <p>
        <a href={href} >Current Time: {new Date().toLocaleTimeString()}</a>
    </p>
);

// React Component
// React components accept inputs (props) and return React elements.
// They can be defined with "function" or "class", and used in JSX format like "<MyComponents />".

// React component in the "class" style
// React component extends React.Component class.
// Component name (= class name) must be started with a capital letter.
class ClassComponent extends React.Component {

    // Constructor recieves JSX attributes as a single props object.
    // React component must not modify its own props.  
    constructor(props) {

        // Constructor should always call the base constructor with props.
        super(props);

        // this.state is a special object used to store the state of the component.
        // this.state can be initialized only in the constructor.
        this.state = {value: 1};

        // Assign "this" to methods to handle events.
        this.handleChange = this.handleChange.bind(this);
    }

    // Define a method to handle an event.
    // React passes SyntheticEvent according to the W3C spec.
    handleChange(event) {

    // Use setState() method to modify the state.
    // setState() merges the object you provide into the current state.
    this.setState({value: event.target.value});
    // Use callback when you modify the state based on previous state.
    // (The update of the state may be asynchronous.)
    //     this.setState((prevState, props) => ({
    //         counter: prevState.counter + props.increment
    //     }));
    }
    
    // render() returns a single root React element which will be shown in the DOM. 
    // If render() returns null, the component will not be rendered.
    render() {
        return (
            <div>
                <form>
                    <input type="number" value={this.state.value} onChange={this.handleChange} />
                </form>
                <FunctionComponent number={this.state.value} />
            </div>
        );
    }

    // componentDidMount() is called after the component output has been rendered to the DOM.
    componentDidMount() {
        console.log("componentDidMount()");
    }

    // componentWillUnmount() is called when the component is being removed from the DOM.
    componentWillUnmount() {
        console.log("componentWillMount()");
    }
}

// React component in the "function" style
function FunctionComponent(props) {

    const number = props.number;
  console.log(number);
    var listItems = [];
    // When you define a list, a "key" attribute needs to be specifined in every element of the list.
    // (Keys help React identify which items have changed, are added, or are removed.)
    // Keys used within arrays should be unique among their siblings.
    for(var i=0; i<number; i++) {
// for(var i=0; i<number; i++) {
        listItems.push(
            <li key={i.toString()}>{i+1}</li>
        );
    }

    return (
        <ul>{listItems}</ul>
    );
}

// ReactDOM.render() renders React components (or elements).
// Pass a component or an elemment to render and root DOM where you want to show it.
// React DOM updates only necessary parts of the DOM.
ReactDOM.render(
    <ClassComponent />,
    document.getElementById('root')
);

React Quick Startを簡単に復習できるサンプルコード

Webアプリのアイデアがふと思い浮かんだので、開発するときにこれまで使ったことのないライブラリを導入してみようと、Reactに挑戦しています。
Reactはドキュメントが充実していて大変素晴らしいのですが、私は物覚えが悪いので一度読んでもすぐに忘れてしまうことが多いです。ですのでいつも後でさっと見返せるように自分用に簡単なメモを作るのですが、このメモがもしかするとどなたかの役に立つかもしれないと思いましたので、ご紹介します。

今回はReact Quick Startをポイントをまとめたサンプルコードです。
(CodePenにも登録しています:React Cheat Sheet

// React Element

// Tag syntax like "<p> ... </p>" is called JSX, and JSX produces a React element.
// React elements are the descriptions of what you want to see on the screen.
// React elements are imuutable and they can't be changed once they are defined.
// (See following React components for how you can update the DOM.)
const singleLineElement = <p>Hello World.</p>;

// When you split JSX over multiple lines, 
// it is recommended to wrap it in parentheses to avoid automatic semicolon insertion by editors.
// Expressions can be embedded in JSX. (JSX itself is also an expression.)
// React escapes any values embedded in JSX before rendering them to prevent injection attacks.
const href = "https://www.time.gov/";
const multipleLinesElement = (
    <p>
        <a href={href} >Current Time: {new Date().toLocaleTimeString()}</a>
    </p>
);

// React Component
// React components accept inputs (props) and return React elements.
// They can be defined with "function" or "class", and used in JSX format like "<MyComponents />".

// React component in the "class" style
// React component extends React.Component class.
// Component name (= class name) must be started with a capital letter.
class ClassComponent extends React.Component {

    // Constructor recieves JSX attributes as a single props object.
    // React component must not modify its own props.  
    constructor(props) {

        // Constructor should always call the base constructor with props.
        super(props);

        // this.state is a special object used to store the state of the component.
        // this.state can be initialized only in the constructor.
        this.state = {value: 1};

        // Assign "this" to methods to handle events.
        this.handleChange = this.handleChange.bind(this);
    }

    // Define a method to handle an event.
    // React passes SyntheticEvent according to the W3C spec.
    handleChange(event) {

    // Use setState() method to modify the state.
    // setState() merges the object you provide into the current state.
    this.setState({value: event.target.value});
    // Use callback when you modify the state based on previous state.
    // (The update of the state may be asynchronous.)
    //     this.setState((prevState, props) => ({
    //         counter: prevState.counter + props.increment
    //     }));
    }
    
    // render() returns a single root React element which will be shown in the DOM. 
    // If render() returns null, the component will not be rendered.
    render() {
        return (
            <div>
                <form>
                    <input type="number" value={this.state.value} onChange={this.handleChange} />
                </form>
                <FunctionComponent number={this.state.value} />
            </div>
        );
    }

    // componentDidMount() is called after the component output has been rendered to the DOM.
    componentDidMount() {
        console.log("componentDidMount()");
    }

    // componentWillUnmount() is called when the component is being removed from the DOM.
    componentWillUnmount() {
        console.log("componentWillMount()");
    }
}

// React component in the "function" style
function FunctionComponent(props) {

    const number = props.number;
  console.log(number);
    var listItems = [];
    // When you define a list, a "key" attribute needs to be specifined in every element of the list.
    // (Keys help React identify which items have changed, are added, or are removed.)
    // Keys used within arrays should be unique among their siblings.
    for(var i=0; i<number; i++) {
// for(var i=0; i<number; i++) {
        listItems.push(
            <li key={i.toString()}>{i+1}</li>
        );
    }

    return (
        <ul>{listItems}</ul>
    );
}

// ReactDOM.render() renders React components (or elements).
// Pass a component or an elemment to render and root DOM where you want to show it.
// React DOM updates only necessary parts of the DOM.
ReactDOM.render(
    <ClassComponent />,
    document.getElementById('root')
);

Object Oriented Programming in JavaScript

Although I'm familiar with Object Oriented Programming (OOP) as I has been using Java for a long time, I've never tried to use it in JavaScript. When I researched OOP in JavaScript, I found it a little complicated because there exist a few ways to implemnt. In this article, I sorted out and simplified them.

  • Use function as class cannot be used in JavaScript before ES5.
var ES5Class = (function() {

    // constructor
    var ES5Class = function(member) {
        // Cope with the following usage which doesn't use new operator.
        // var instance = ES5Class();
        if(!(this instanceof ES5Class)) {
            return new ES5Class(member);
        }

        // members
        // Conventionally prefix an under score to the name of private variables.
        // (Although it can be accessed from outside the class.)
        this._member = member;
    };

    // Declare a method with prototype.
    // Methods can be declared in following way, but it's not efficient
    // because functions will be created every time an instance is generated.
    //   this.printMethod = function... 
    var p = ES5Class.prototype;
    
    // methods
    p.printMember = function () {
        console.log(this._member);
    }

    return ES5Class;
})();

module.exports = ES5Class;
  • With JavaScript later than ES6, class syntax can be used to declare classes.
class ES6Class {

    // constructor
    constructor(member) {
        // memners
        // Conventionally prefix an under score to the name of private variables.
        // (Although it can be accessed from outside the class.)
        this._member = member;
    }

    printMember() {
        console.log(this._member);
    }
}

module.exports = ES6Class
  • class syntax can also define static methods but cannot define static members.
// As there is no way to declare static members in class syntax,
// define global-scope variables instead.
var _member = 0;

class ES6StaticClass {

    // static methods
    static printMember() {
        _member++;
        console.log(_member);
    }
}

module.exports = ES6StaticClass

Error Handling in JavaScript

When we handle exceptions in Java, it is common to declare classes which extend Exception class and make conditional branches with instanceof operator. As far as I researched about how to do in JavaScript, there are mainly two ways.

  1. Extend Error object
    • Declare classes which extend Error object (For before ES5: prototype of Error object) and make conditional branches with instanceof operator.
    • Using instanceof operator makes the comparison reliable, but Error classes have to be imported in the file where conditional branches exist.
  2. Change the name property of Error object.
    • Create an Error object and change the name property, then make conditional branches by strings set as the name property.
    • This method is simple, but thereis a possibility that the names of the errors may be the same as the ones defined in the dependent modules.

Sample Code

error.js

var ERROR = {};

// As the original value of the name priperty of Error object is "Error",
// change it to a name of the custom Error class.
ERROR.Error1 = class extends Error {}
ERROR.Error1.prototype.name = "Error1";

// For before ES5, implement the inheritance using prototype.
ERROR.Error2 = function (message) {
    this.message = message;
}
ERROR.Error2.prototype = new Error;
ERROR.Error2.prototype.name = "Error2";

module.exports = ERROR;

module.js

const ERROR = require('./error.js');

class MyClass {
    static myMethod(arg) {
        if (arg === 1) {
            throw new ERROR.Error1("Error1 occured.")
        } else if (arg === 2) { 
            throw new ERROR.Error2("Error2 occured.")
        } else if (arg === 3) { 
            const e = new Error("Error3 occured.")
            e.name = "Error3";
            throw e;
        }
    }
}

module.exports = MyClass;

main.js

const MyClass = require('./module.js');
const ERROR = require('./error.js');

try {
    MyClass.myMethod(1);
} catch(e) {
    if (e instanceof ERROR.Error1) {
        console.log(e.name);
        console.log(e.message);
    }
}

try {
    MyClass.myMethod(2);
} catch(e) {
    if (e instanceof ERROR.Error2) {
        console.log(e.name);
        console.log(e.message);
    }
}

try {
    MyClass.myMethod(3);
} catch(e) {
    if (e.name === "Error3") {
        console.log(e.name);
        console.log(e.message);
    }
}

Result

$ node main.js
Error1
Error1 occured.
Error2
Error2 occured.
Error3
Error3 occured.

Reference

JavaScript エラー処理(独自エラー・条件分岐)

Javaで例外処理と言えば、Exceptionクラスを継承したクラスを定義して、instanceof演算子で条件分岐するのが定番です。JavaScriptの定番について調べてみたところ、大きくは下記の2パターンがあるようです。

  1. Errorオブジェクトを継承する

    • Errorオブジェクトを継承したクラス(ES5以前の場合はprototypeを継承したオブジェクト)を定義して、instanceof演算子で条件分岐します。
    • instanceof演算子で比較するため、文字列比較と異なり確実に比較ができますが、条件分岐をするコードでも独自Errorクラス(オブジェクト)をロードする必要があります。
  2. Errorオブジェクトのnameプロパティを変更する

    • Errorオブジェクトを生成して、nameプロパティを変更して、nameプロパティに設定した文字列一致で条件分岐します。
    • 手軽に記述できる一方、文字列一致のため予期せず依存するモジュールに定義されているエラーとnameプロパティが重なってしまう可能性があります。

サンプルコード

error.js

var ERROR = {};

// Errorを継承したままではnameプロパティは「Error」のままであるため、
// nameプロパティを独自のエラークラスの名称に変更する。
ERROR.Error1 = class extends Error {}
ERROR.Error1.prototype.name = "Error1";

// ES5以前の場合はprototypeを使って継承する。
ERROR.Error2 = function (message) {
    this.message = message;
}
ERROR.Error2.prototype = new Error;
ERROR.Error2.prototype.name = "Error2";

module.exports = ERROR;

module.js

const ERROR = require('./error.js');

class MyClass {
    static myMethod(arg) {
        if (arg === 1) {
            throw new ERROR.Error1("Error1 occured.")
        } else if (arg === 2) { 
            throw new ERROR.Error2("Error2 occured.")
        } else if (arg === 3) { 
            const e = new Error("Error3 occured.")
            e.name = "Error3";
            throw e;
        }
    }
}

module.exports = MyClass;

main.js

const MyClass = require('./module.js');
const ERROR = require('./error.js');

try {
    MyClass.myMethod(1);
} catch(e) {
    if (e instanceof ERROR.Error1) {
        console.log(e.name);
        console.log(e.message);
    }
}

try {
    MyClass.myMethod(2);
} catch(e) {
    if (e instanceof ERROR.Error2) {
        console.log(e.name);
        console.log(e.message);
    }
}

try {
    MyClass.myMethod(3);
} catch(e) {
    if (e.name === "Error3") {
        console.log(e.name);
        console.log(e.message);
    }
}

実行結果

$ node main.js
Error1
Error1 occured.
Error2
Error2 occured.
Error3
Error3 occured.

参考