javascriptのconsole.logについてメモ

質問して教えてもらったのでメモ。

JavaScriptの基本の「image changer を追加する」にあるコードを動かした。

var myImg = document.querySelector('img')

myImg.onclick = function () {
  var mySrc = myImg.getAttribute('src')

  if (mySrc === 'images/firefox-icon.png') {
    console.log(myImg) // firefox-icon2.png ...①
    console.log(mySrc) // firefox-icon.png ...②
    myImg.setAttribute('src', 'images/firefox2.png') // ...③
  } else {
    myImg.setAttribute('src', 'images/firefox-icon.png')
  }
}

③を実行する前に①と②の中身をconsole.logで確認したところ、予想では①②の両方ともfirefox-icon.pngが表示されると思ったのが、①だけfirefox-icon2.pngが表示された。

console.logはコンソールを確認した時点での値を表示する

console.logする対象がオブジェクトのとき、コンソールに表示される値はコンソールを開いて確認した時点での値になる。typeofで確認すると、①はオブジェクトで②は文字列だった。

例①

var obj={"bool":true}

console.log(obj);

setTimeout(function(){
    obj.bool=false;
}, 5000);

このコードを実行してから「5秒以内にコンソールを確認」するとtrueが表示され、「5秒後にコンソールを確認」するとfalseが表示される。これは5秒以内の時点だとconsole.logしているobjの中身がまだtrueだからで、5秒後にコンソールを開いて確認したときにはsetTimeoutが実行されてobjのboolがfalseに変更されているからコンソールの表示内容も変わる。

※正確には「5秒後にsetTimeoutの処理が実行される」のではなく「5秒後にsetTimeoutが実行キューに登録されてそのあとに処理が実行される」
参考:JavaScript を学ぶ際に一番重要なのに、誤解されがちな setTimeout 系の概念

例②

var a = new Array(100, 300, 200)

a.push(500)
console.log(a) // [100, 300, 200, 500] ...①
a.splice(1, 2, 800, 1000)
console.log(a) //  [100, 800, 1000, 500] ...②

このコードを「コンソールを最初から表示した状態で実行」したとき、①②の結果はコメントの通りになる。「console.logを実行してからコンソールを開いて確認」した場合は①②の結果は両方とも[100, 800, 1000, 500]になる。これはコードの処理が全て終わった時点でのaの値を表示しているからこの結果になる。

console.logより下に値を書き換えたり代入するコードがあったとしても、コンソールを確認するまでにその変更が実行された場合は、コンソールに表示される値は変更後の値になる。これはオブジェクトに対して起こる現象で、プリミティブな値(文字列・数値 etc)では起こらない(たぶん)。一番最初のコードの②の結果がfirefox-icon.pngだったのは、②の型がプリミティブな値(文字列)だったから。

react-router-domとMaterial-UIを一緒に使うメモ

react-router@v4からパッケージが分離されたので、これからはreact-router-domを使おうとかで、react-routerからreact-router-domを使うことにした。

参考にしたサイト

React Router: Declarative Routing for React.js

React Router v4(next) が alphaからbetaになってぼちぼち変わってたので追従する - Qiita

Material-UI

react-routerでページ遷移にちょっとしたアニメーションを付ける | WebDesign Dackel

コードと結果

import React, { Component } from 'react'
import ReactDOM from'react-dom'
import { BrowserRouter as Router, Route, Link } from 'react-router-dom'
import FlatButton from 'material-ui/FlatButton'
import { Home } from './home.js'
import { About } from './about.js'

class Action extends Component {
  render () {
    return (
      <Router>
        <div>
          <FlatButton label="home" containerElement={<Link to="/" />} />
          <FlatButton label="about" containerElement={<Link to="/about" />} />

          <Route exact path="/" component={Home} />
          <Route path="/about" component={About} />
        </div>
      </Router>
    )
  }
}

export { Action }

f:id:unecocc:20170607010457p:plain

解説

homeとaboutページをimportで読み込み。< Route/>でurlと表示するページのコンポーネントを設定。< FlatButton/>内に< Link/>を設定することでMaterial-UIの装飾が可能。

aboutページでリロードするとエラーになる。未解決。

// エラー内容
Refused to apply a stylesheet because its hash, its nonce, or 'unsafe-inline' appears in neither the style-src directive nor the default-src directive of the Content Security Policy.

UITableViewのCellの高さを可変にするメモ

Twitterのような、ツイート(文章)ごとに高さが変わるセルを作る。
UITableViewの使い方と高さを可変にする方法は下記の記事参照。

yuu.1000quu.com

www.swift-study.com

環境

Swift3
Xcode 8.3.1

コード

// ViewController.swift


import UIKit

class ViewController: UIViewController, UITableViewDelegate, UITableViewDataSource {
    
    @IBOutlet weak var tableView: UITableView!
    
    var rows = [
        "責任者に問いただす必要がある。責任者はどこか。",
        "我々の大方の苦悩は、あり得べき別の人生を夢想することから始まる。自分の可能性という当てにならないものに望みを託すことが諸悪の根元だ。今ここにある君以外、ほかの何者にもなれない自分を認めなくてはいけない。",
        "「僕なりの愛ですわい」",
        "大きなカステラを一人で切り分けて食べるというのは孤独の極地ですからね、人恋しさをしみじみ味わってほしくて",
        "「だって寂しいんだもの。それに夕風が冷たいの」",
        "「我々は運命の黒い糸で結ばれているというわけです」",
        "慰めるわけじゃないけど、あなたはどんな道を選んでも僕に会っていたと思う。直感的に分かります。いずれにしても、僕は全力を尽くしてあなたを駄目にする。運命に抗ってもしょうがないですよ",
        "猫ラーメンは、猫から出汁を取っているという噂の屋台ラーメンであり、真偽はともかくとして、その味は無類である。",
        "不毛に過ぎた二年の遅れをがつがつとみっともなく取り返そうとしているような気分になってきた。そんないじましい己の姿は私の美学に反する。したがって私は潔く勉強をあきらめた。こういった潔さには自信がある。つまりは紳士だということだ。",
        "成就した恋ほど語るに値しないものはない。",
    ]
    
    
    override func viewDidLoad() {
        super.viewDidLoad()
        
        //見積もり高さ
        tableView.estimatedRowHeight = 20
        
        //自動設定
        tableView.rowHeight = UITableViewAutomaticDimension
    }
    
    
    override func didReceiveMemoryWarning() {
        super.didReceiveMemoryWarning()
    }
    
    
    // セルの個数を指定するデリゲートメソッド(必須)
    func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
        return rows.count
    }
    
    
    // セルに値を設定するデータソースメソッド(必須)
    func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
        
        // セルを取得する(セルをオブジェクト化)
        let cell = tableView.dequeueReusableCell(withIdentifier: "myCell", for: indexPath as IndexPath)
        
        // セルに表示する値を設定する
        cell.textLabel!.text = rows[indexPath.row]
        
        // 0に設定
        cell.textLabel!.numberOfLines = 0
        
        // 折り返しアリに設定
        cell.textLabel!.lineBreakMode = NSLineBreakMode.byWordWrapping
        
        return cell
    }
    
    // セルが選択された時に呼ばれるデリゲートメソッド
    func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) {
        print("セル番号:\(indexPath.row) セルの内容:\(rows[indexPath.row])")
    }
}

Storyboard

f:id:unecocc:20170424150852p:plain

結果

f:id:unecocc:20170424150723p:plain