frontendmemo

このサイトは、「html、css、js、ツールなどについて、自分が覚えたこと、またはいつも忘れて調べることを書き溜め、それが結果といて勉強したての初心者の方や自分と同じような技術レベルの人の助けになることを目的とするWebログ」、略してブログです。挨拶→http://frontendmemo.hatenablog.com/entry/2016/06/25/115845

2017年カレンダーをJavascriptで生成

卓上カレンダーを買うお金がないのでカレンダーをJsで作ってみました。
こちらを参考に作りました。
イヌでもわかるJavaScript講座 - カレンダー
感謝です。

ソースはカレンダーの下に載せています。







html

<div id="calendar">
</div>

css

#calendar:after {
	clear: both;
	display: block;
	content: "";
}
#calendar table {
	border-collapse: collapse;
	text-align: left;
	line-height: 1.5;
	float: left;
	margin: 10px 10px 0 0;
}
#calendar thead {
	border-right: 1px solid #ccc;
	border-left: 1px solid #ccc;
	background: #04162e;
}
#calendar thead th {
	padding: 10px;
	font-weight: bold;
	vertical-align: top;
	color: #fff;
}
#calendar tbody th {
	width: 150px;
	padding: 10px;
	font-weight: bold;
	vertical-align: top;
	border-bottom: 1px solid #ccc;
	background: #efefef;
}
#calendar td {
	padding: 10px;
	vertical-align: top;
	border-bottom: 1px solid #ccc;
	text-align: center;
}
#calendar .today {
	background: #ccc;
}
#calendar .sat {
	color: blue;
}
#calendar .sun {
	color: red;
}

javascript

<script src="https://code.jquery.com/jquery-2.2.4.js"></script>
<script>
$(function(){
'use strict';
var $calendar = $('#calendar');
var myWeekTbl = new Array('月','火','水','木','金','土','日');	// 曜日テーブル定義
var myMonthTbl= new Array(31,28,31,30,31,30,31,31,30,31,30,31);	// 月テーブル定義
var myDate = new Date();
var myToday = myDate.getDate();	// 今日の'日'を退避
var todayMyMonth = myDate.getMonth();	// 月を取得(0月~11月)

function setCalender(l){
myDate = new Date(2017,l);	// 今日の日付データ取得
var myYear = myDate.getFullYear();	// 年を取得
((myYear % 4)===0 && (myYear % 100) !==0) || (myYear % 400)===0 ? myMonthTbl[1] = 29: 28;	// うるう年だったら...
	// 2月を29日とする
var myMonth = myDate.getMonth();	// 月を取得(0月~11月)
myDate.setDate(1);	// 日付を'1日'に変えて、
var myWeek = myDate.getDay() - 1;	// '1日'の曜日を取得
var myTblLine = Math.ceil((myWeek+myMonthTbl[myMonth])/7);	// カレンダーの行数
var myTable = new Array(7*myTblLine);	// 表のセル数を用意
for(var i=0; i<7*myTblLine; i++){
	myTable[i]=' ';	// セルを全て空にする
}
for(i=0; i<myMonthTbl[myMonth]; i++){
myTable[i+myWeek]=i+1;	// 日付を埋め込む
}

var source = '';
var td = '<td>';
var tdC = '</td>';
var tr = '<tr>';
var trC = '</tr>';

for(i=0; i<myTblLine; i++){	// 表の「行」のループ
	source += tr;
	for (var j = 0; j < 7; j++) {
		var mydat = myTable[j+(i*7)];
		if(todayMyMonth === myMonth && mydat === myToday){
			source += '<td class="today">' + mydat + tdC;
		}else if(j === 5){
			source += '<td class="sat">' + mydat + tdC;
		}else if(j === 6){
			source += '<td class="sun">' + mydat + tdC;
		}else{
			source += td + mydat + tdC;
		}
	}
	source += trC;
}
var week = '';
for(var k=0; k<7; k++){	// 曜日
	if(k === 5){
		week += '<td class="sat">' + myWeekTbl[k] + tdC;
	}else if(k === 6){
		week += '<td class="sun">' + myWeekTbl[k] + tdC;
	}else{
		week += td + myWeekTbl[k] + tdC;
	}
}
var weekTr = tr + week + trC;
var tableSource = '<table>' +
	'<tr><td colspan="7">' +
	 myYear + '年' + (myMonth+1) + '月' +
	 '</td></tr>' + weekTr + source + '</table>';

	$calendar.append(tableSource);	// 表の作成開始
}
for(var l=0; l<12; l++){
	setCalender(l);
}

});
</script>

配列から空文字を削除する方法など

falseと判定されるvalueまとめ

  • null
  • 0
  • undefind
  • ''(空文字)
  • NaN
  • false

文字列や数値を真偽値に変換する方法

Boolean

var str = 'aaa';
console.log(Boolean(str)); // true

!!エクスクラメーションマーク2つ

console.log(!!str); // true

配列から空文字を削除する

var arr = ["1", "", "2", "", "3", ""];
arr.filter(Boolean); // 偽とみなされる値にfalseを返す

尚、filterメソッドのサポートはIE9からになります。

JavaScript urlのファイル名のみ取得する方法(拡張子あり/なし)

urlのファイル名のみ取得したい場合があります。

たとえば
http://○○○.com/○○○/index.htmlのindexを抽出したいときですね。
以下のようにします。

var l = window.location.pathname.split('/');
l = l[l.length-1];
l = l.split('.')[0];
console.log(l); // index
<||

JavaScript 問題③

問題

1~100までの数字の中で、3の倍数と3が含まれている数字をconsoleで表示させてください。

答え

See the Pen ygaygv by funclur (@funclur) on CodePen.


vvar result = 0;
var count = 0;
var array = [];
var re = /3/;
for(var i = 1;i <= 100;i++){
  if(!!re.test(i) || i % '3' === 0){
    array.push(i);
  }
}
console.log(array);
for(var j = 0; j < array.length; j++){
  count += array[j]
}
console.log(count);

その他回答例

toStringメソッドで文字列化

See the Pen WRGbpO by funclur (@funclur) on CodePen.


関数内で繰り返し

See the Pen wgzaLO by funclur (@funclur) on CodePen.

オブジェクト指向 JavaScriptの原則 プリミティブ型と参照型、関数、コンストラクタ、プロトタイプ

オブジェクト指向 JavaScriptの原則を読んで学んだことを書きます。
全てを網羅してないことと本書と例文に多少違いがありますことご了承ください。

オブジェクト指向JavaScriptの原則

オブジェクト指向JavaScriptの原則

プリミティブ型とは

trueや25のように、そのままの形で格納される単純なデータ型です。

  • 真偽値 true false
  • 数値 整数または浮動小数点型の数値
  • 文字列 
  • null
  • undefined 初期化されていない変数に割り当てられる値

プリミティブ型のメソッド

  • .toLowerCase();
  • .chartAt();
  • .substring();
  • .toFixed();
  • .toString();

参照型とは

オブジェクトを表します。
オブジェクトは下記のように複数参照できる

var object1 = new Object();
var object2 = object1;
console.log(typeof object2); // object
object2 = null;
console.log(typeof object2); // object

大規模アプリケーションではnullを割り当て参照を解除します。
ところがjavascriptのバグで型はobjectとして吐き出されます。

プロパティの追加

var object1 = new Object();
var object2 = object1;
object2.property = 'プロパティを追加';
console.log(object2.property); // プロパティを追加

関数

関数宣言

関数宣言は宣言より前に実行できる巻き上げが可能

var result = add(5, 5);
console.log(result); // 10
function add(num1, num2){
  return num1 + num2;
}

関数式

巻き上げは巻き上げ不可

var result = add(5, 5);
console.log(result); // undefined
var add = function(num1, num2){
  return num1 + num2;
};

第1級関数とは

オブジェクトのように変数を割り当てること、オブジェクトのプロパティとして追加すること、関数の戻り値として関数を返すこともできます。

function sayHi(){
  console.log('Hi');
}
sayHi(); // Hi
var sayHi2 = sayHi;
sayHi2(); // Hi

引数(パラメータ)

function sum(){
  var i = 0;
  var len = arguments.length;
  var result = 0;
  for(i;i<len;i++){
    result += arguments[i];
  }
  return result;
}
console.log(sum(1,2)); // 3
console.log(sum(1,2,3,4)); // 10

オーバーロード

一つの関数が複数のパラメータの型、組み合わせを持つことが可能です。

function sayMessage(message){
  if(arguments.length === 0){
    message = 'メッセージ';
  }
  console.log(message);
}
sayMessage('hello'); // hello
sayMessage(); // メッセージ

callメソッド

thisの値を変更します。

function sayNameForAll(label){
  console.log(label + ':' + this.name);
}

var person1 = {
  name : 'Nicholas'
};

var person2 = {
  name : 'greg'
};

var name = 'Michael';

sayNameForAll(this); // [object Window]:Michael
sayNameForAll.call(this); // undefined:Michael
sayNameForAll.call(this, 'global'); // global:Michael
sayNameForAll.call(person1, 'person1'); // person1:Nicholas person1がthis 'person1'が第一引数になる 
sayNameForAll.call(person2, 'person2'); // person2:greg person2がthis 'person1'が第一引数になる 

applyメソッド

すでにデータが配列に格納されてる場合はapply()を使用します。

function sayNameForAll(label){
  console.log(label + ':' + this.name);
}

var person1 = {
  name : 'Nicholas'
};

var person2 = {
  name : 'greg'
};

var name = 'Michael';

sayNameForAll(this); // [object Window]:Michael
sayNameForAll.apply(this); // undefined:Michael
sayNameForAll.apply(this, ['global']); // global:Michael
sayNameForAll.apply(person1, ['person1']); // person1:Nicholas person1がthis 'person1'が第一引数になる 
sayNameForAll.apply(person2, ['person2']); // person2:greg person2がthis 'person1'が第一引数になる 

bindメソッド

thisの値を固定した新しい関数を生成します。

function sayNameForAll(label){
  console.log(label + ':' + this.name);
}

var person1 = {
  name : 'Nicholas'
};

var person2 = {
  name : 'greg'
};

// person1オブジェクト専用の関数を生成
var sayNameForPerson1 = sayNameForAll.bind(person1); // thisがperson1
sayNameForPerson1('person1'); // person1:Nicholas 'person1'は引数

// person2オブジェクト専用の関数を生成
var sayNameForPerson2 = sayNameForAll.bind(person2); // thisがperson2
sayNameForPerson2('person2'); // person2:greg 'person2'は引数

// bind()で生成された関数をオブジェクトにメソッドとして与えてもthisの値は変わらない
person2.sayName = sayNameForPerson1;
person2.sayName('person2'); // person2:Nicholas

コンストラクタ

new演算子を伴って使用されることでオブジェクトを生成する関数である。
コンストラクタの長所は、コンストラクタによって生成されたオブジェクトは全て同じプロパティやメソッドを持ってるということ
コンストラクタ通常の関数と区別するため先頭の文字は大文字にする

// コンストラクタを生成

function Person(){
  console.log(1);
}
// インスタンスを生成
var person1 = new Person();
// 以下のように型を判定できる
console.log(person1.constructor === Person) // Person1のコンストラクタはPersonである
console.log(person1 instanceof Person) // Personのインスタンスはperson1である

コンストラクタの存在意義は同じプロパティやメソッドを持ったオブジェクトを簡単に生成できるということ

function Person(name){
  this.name = name;
  this.say = function(){
    return console.log(this.name);
  };
}
var person1 = new Person('abc');
var person2 = new Person('cde');
console.log(person1.name); // abc
console.log(person2.name); // cde
person1.say(); // abc
person2.say(); // cde

プロトタイプ

function Person(name){
  this.name = name;
}
Person.prototype = {
  sayName: function(){
    console.log(this.name);
  },
  toStoring: function(){
    return '[Person' + this.name + ']';
  }
};

オブジェクト指向JavaScriptの原則

オブジェクト指向JavaScriptの原則

JavaScript 問題②

問題

文字列hatenabloghatanosiinaaに含まれてるaの数をconsole.logで出力してください。

答え

See the Pen ggOMbo by funclur (@funclur) on CodePen.


var str = 'hatenabloghatanosiinaa';
var count = 0;

for(var i = 0; str.length>i; i++){
  var strParts = str.substring(i,i+1);
  if(strParts === 'a'){
    count++;
  }
}

console.log(count);

考察

文字列を切り離す方法は何個かあります。

charAtメソッド
var str = 'hatenabloghatanosiinaa';
str.charAt(0) //h

String.prototype.charAt() - JavaScript | MDN

sliceとindexOfメソッド
str.slice(i).indexOf('a')

Array.prototype.slice() - JavaScript | MDN

正規表現
str.match(/a/g).length

JavaScript 問題①

問題:下記のようにconsole.logで出力してください。

記事の投稿数が96になりました。
記事の投稿数が97になりました。
記事の投稿数が98になりました。
記事の投稿数が99になりました。
記事の投稿数が記念すべき100になりました。

1つ目

(function(){
  var i = 96;
  var length = 100;
  for(i; i <= length; i++){
    if(i === 100){
      console.log("記事の投稿数が記念すべき" + i + "になりました。");
    }else{
      console.log("記事の投稿数が" + i + "になりました。");
    }
  }
})();

2つ目

 var i = 96;
  var length = 100;

  function message(){
    this.times = function(i){
      if(i === 100){
        console.log("記事の投稿数が記念すべき" + i + "になりました。");
      }else{
        console.log("記事の投稿数が" + i + "になりました。");
      }
    }
  }
  message.prototype = {
    say: function(i){
      return this.times(i);
    }
  };
  newMessage = new message();
  for(i; i <= length; i++){  
    newMessage.say(i);
  }