2010年09月30日

メモ化

JavaScript: The Good Partsのメモ化。


var fibonacci = function (n) {
return n < 2 ? n : fibonacci(n - 1) + fibonacci(n - 2);
};

for (var i = 0; i <= 10; i += 1) {
document.writeln('// ' + i + ': ' + fibonacci(i));
}


これだとfibonaccが453回実行される。一度計算したのは覚えておこう。

var fibonacci = function(){
var memo = [0, 1];
var fib = function (n) {
var result = memo[n];
if (typeof result !== 'number') {
result = fib(n - 1) + fib(n - 2);
memo[n] = result;
}
return result;
};
return fib;
}();
for (var i = 0; i <= 10; i += 1) {
document.writeln('// ' + i + ': ' + fibonacci(i));
}


これだとfibonacciは11回にfibが29回

var memoizer = function (memo, fundamental) {
var shell = function (n) {
var result = memo[n];
if (typeof result !== 'number') {
result = fundamental(shell, n);
memo[n] = result;
}
return result;
};
return shell;
};
var fibonacci = memoizer([0, 1], function (shell, n) {
return shell(n - 1) + shell(n - 2);
});
for (var i = 0; i <= 10; i += 1) {
document.writeln('// ' + i + ': ' + fibonacci(i));
}


これだとモット少なくできる。


難解すぎる。。。
タグ:メモ化
posted by ねこまんま at 03:17 | Comment(0) | TrackBack(0) | テクニック | 更新情報をチェックする

2010年09月29日

JavaScriptでカリー化

JavaScript: The Good Partsを読んでいるとカリー化で躓いた。

この本内容は良いんだけどどこぞのページで作成した関数やメソッドを次ページ以降で当たり前に使ってくるので結構捜すのがめんどくさい。addとかいうオブジェクトが登場したからネイティブのaddかとおもったらずっと前のページで作詞した関数だった。一言補足が欲しい。(P.○○で作成したaddみたいに)


var add = function (a, b) {
if (typeof a !== 'number' || typeof b !== 'number') {
throw {
name: 'TypeError',
message: 'add needs numbers'
}
}
return a + b;
}
Function.prototype.method = function(name , func){
this.prototype[name] = func;
return this;
}
Function.method('curry',function(){
//var args = arguments , that = this;
//return function(){
// return that.apply(null,args.concat(arguments));
//}
var slice = Array.prototype.slice,
args = slice.apply(arguments),
that = this;
return function(){
return that.apply(null, args.concat(slice.apply(arguments)))
}
})
var add1 = add.curry(1);
document.writeln(add1(6));//7


こういうことらしい。

で、カリー化とは関数に引数を固定して新しい関数を作成する。とのこと。

add(A,B)// return A+B


Aを固定化してadd1を生み出すとこのような感じ。

add1(C)// return A+C



カリー化は理解したが次のコードが難解。

Function.method('curry',function(){
var slice = Array.prototype.slice,
args = slice.apply(arguments),
that = this;
return function(){
return that.apply(null, args.concat(slice.apply(arguments)))
}
})


オブジェクトを配列に変換が利用されているのはわかる。

argsとthisをクロージャーで包む。ここでthisはadd関数となる。そこでapplyを利用してadd関数を実行する。引数にはargsつまり「add.curry(1)」の引数とslice.apply(arguments)つまり「add1(6)」を結合した配列[1,6]となる。ということかな?
posted by ねこまんま at 16:59 | Comment(0) | TrackBack(0) | テクニック | 更新情報をチェックする

プロトタイプと継承

第14回 プロトタイプと継承

よい記事。

var Point = function(x, y){
this.x = x;
this.y = y;
}
Point.prototype.length = function(){
return Math.sqrt(this.x * this.x + this.y * this.y);
};
var point1 = new Point(3, 4);
console.log(point1.length()); // 5
console.log(point1);


基本的なプロトタイプだけども、new演算子を用いることで,関数がコンストラクタとして働き,そのコンストラクタが持つプロトタイプオブジェクトのメソッド(プロパティ)を継承した新しいオブジェクトを作ることができるらしい。インスタンスと思ってたけど継承したオブジェクトなのか。でどのようなオブジェクトかというと次のような感じ。

{
x:3,
y:4,
__proto__: {
consutructor : function(x,y){
(中略)
} ,
length : function(){
(中略)
} ,
__proto__: {
(中略)
}
}
}
}


xとyと隠しプロパティの__proto__を持つ。__proto__にはconstructorプロパティ(function Point)と,lengthメソッドが定義されています。

これらは実体を共有しているの、new演算子で生成後にprototypeに追加したメソッドも共有される。

var Point = function(x, y){
this.x = x;
this.y = y;
}
Point.prototype.length = function(){
return Math.sqrt(this.x * this.x + this.y * this.y);
};
var point1 = new Point(3, 4);
console.log(point1.length());//5
Point.prototype.distance = function(z){
return this.x*z;
};
console.log(point1.distance(2));//10



__proto__はほぼすべてのオブジェクトに存在しprototypeを拡張することでメソッドを使いできるのがわかる。変数型の拡張

var array1 = [1, 2];
console.log(array1.__proto__ === Array.prototype);//true
Array.prototype.insert = function(v, i){
this.splice(i, 0, v);
return this;
};
console.log(array1.insert(6, 1));


でも、ネイティブのプロトタイプを拡張するとfor inなど様々な箇所で弊害が発生する。for in ではオブジェクト自身のプロパティか,__proto__のプロパティか区別がつかない。これはhasOwnPropertyで確認することが出来る。

var array1 = [1, 2];
for (var p in array1) {
console.log(p, ':', array1[p]);
//0 : 1
//1 : 2
}
Array.prototype.insert = function(v, i){
this.splice(i, 0, v);
return this;
};
for (var p in array1) {
console.log(p, ':', array1[p]);
//0 : 1
//1 : 2
//insert : function (v, i){
// this.splice(i, 0, v);
// return this;
//}
}
for (var p in array1) {
if (array1.hasOwnProperty(p)) {
console.log(p, ':', array1[p]);
//0 : 1
//1 : 2
}
}
posted by ねこまんま at 03:25 | Comment(0) | TrackBack(0) | テクニック | 更新情報をチェックする

2010年09月28日

変数型の拡張

オブジェクトの拡張ではすべてのオブジェクトで利用できるメソッドを追加したが

関数や文字列などでもFunction.prototypeを拡張することですべての関数で利用できるメソッドを追加できる。

Function.prototype.method = function(name , func){
this.prototype[name] = func;
return this;
}
String.method("hoge",function(){
return this.replace("a","b");
});
alert("abc".hoge());//bbc
posted by ねこまんま at 19:09 | Comment(0) | TrackBack(0) | テクニック | 更新情報をチェックする

オブジェクトの拡張

Object.prototypeに新たなメソッドを定義することですべてのオブジェクトで利用できるメソッドが追加できる

Object.prototype.hoge = function(){
return this.replace("a","b");
}
alert("abc".hoge());//bbc
タグ:Prototype object
posted by ねこまんま at 19:04 | Comment(0) | TrackBack(0) | テクニック | 更新情報をチェックする

2010年09月24日

オブジェクトの参照渡し

今まで気にしなかったんだけどオブジェクトの参照渡しで値が渡される。参照渡しとは共通の領域を別々のオブジェクト名で同じメモリが参照されている。

obj2に変更を加えるとobjも変更される

var obj = new Object;
obj.nickname='bar';
var obj2 = obj;
obj2.nickname = 'foo';
alert(obj.nickname);//foo


配列も同様

var arr = new Array;
arr[0] = 'bar';
var arr2 = arr;
arr2[0] = 'foo';
alert(arr[0]);//foo


文字列は参照渡しではない

var str = 'bar';
var str2 = str;
str2 = 'foo';
alert(str);//bar
タグ:Objec
posted by ねこまんま at 01:12 | Comment(0) | TrackBack(0) | テクニック | 更新情報をチェックする

2010年09月13日

YUI Compressorでjavascriptを圧縮

YUI CompressorはYahooが提供するJavaScriptやCSSの圧縮ツールです。

ダウンロードしたらコマンドラインから実行する

java -jar yuicompressor-2.2.4.jar js/script.js -o js/script.min.js


タグ:YUI Compressor
posted by ねこまんま at 07:08 | Comment(0) | TrackBack(0) | テクニック | 更新情報をチェックする

2010年09月09日

JavaScriptと指数

JavaScriptと指数について調べてみた。

次の2つの条件式はtrueを返す。

alert(3000===3e3);//true
alert(3000===3e+3);//true


指数はeで桁を表した数値の形。

次のコードでは20桁を超えた段階で表示できなくなる。

alert(100000000000000000000);//100000000000000000000
alert(1000000000000000000000);//1e+21


そんな感じ。
タグ:指数
posted by ねこまんま at 00:51 | Comment(0) | TrackBack(0) | テクニック | 更新情報をチェックする

2010年09月05日

要素がサポートしてる属性を確認

次のような関数を実行すると要素が属性をサポートしているどうか確認できる。

var supportsElementAttribute = function (ele,attr) {
var input = document.createElement(ele);
return attr in input;
};
alert(supportsElementAttribute("input","value"))//true
alert(supportsElementAttribute("input","type"))//true
alert(supportsElementAttribute("input","hoge"))//false
alert(supportsElementAttribute("div","id"))//true
alert(supportsElementAttribute("img","src"))//true


ちなみに in はプロパティが存在するかどうか確認する演算子

参考:HTML5 の placeholder 属性を jQuery でクロスブラウザに
タグ:in
posted by ねこまんま at 06:08 | Comment(0) | TrackBack(0) | テクニック | 更新情報をチェックする

2010年08月10日

URLからファイル名を取得する正規表現

正規表現は毎回手こずるので作った正規表現を覚書

特定のURLからファイル名のみを取得する正規表現

"url".match(".+/(.+?)$")[1]


更に、拡張子を取り除いたファイル名を取得する正規表現

"url".match(".+/(.+?)\.[a-z]+$")[1]
posted by ねこまんま at 15:30 | Comment(0) | TrackBack(0) | テクニック | 更新情報をチェックする

2010年07月29日

webkitTransitionEndでCSS3の-webkit-transitionにコールバック関数を設定

CSS3のアニメーションメソッド「-webkit-transition」のアニメーション終了時のイベントは「webkitTransitionEnd」で設定が出来る。

$(this).bind('webkitTransitionEnd', function() {
//コールバック関数
})


便利ですわ。
posted by ねこまんま at 05:39 | Comment(0) | TrackBack(0) | テクニック | 更新情報をチェックする

2010年05月29日

Adobe AIRのパッケージング

Adobe AIRではパッケージする際に自己署名入り証明書を作成する必要があります。

コマンドラインから次のように実行すると証明書「hoge.pfx」が作成されます。

adt -certificate -cn hogecysign 1024-RSA hoge.pfx hogeword


hogecysignは証明書の名前、hogewordは証明書です。

次はパッケージ化

adt -package -storetype pkcs12 -keystore hoge.pfx -storepass hogeword HellowWorld.air HellowWorld.xml HellowWorld.html


みたいにするとパッケージ化できる。
posted by ねこまんま at 02:26 | Comment(0) | TrackBack(0) | テクニック | 更新情報をチェックする

2010年05月18日

はじめてのAdobe AIR

まずはAIR SDK をインストール。
ダウンロードして解凍した「AdobeAIRSDK」をC直下に移動します。

次に環境変数pathに、AdobeのAIRの実行コマンドを追記します!

環境変数pathはWindows VISTAの場合、「コマンドプロンプト」から「システムとメンテナンス」を選択、「システム」から「システムの詳細設定」を選択します。ユーザーアカウント制御が出る場合は、続行をクリックします。「環境変数」から「PATH」を選択して「編集」をクリック。行末に「;C:\AdobeAIRSDK\bin」を追加します。

次に作業フォルダの作成。

C直下にC:\AIR\helloというフォルダを作成します。

中に用意するのは設定用のXMLファイルと土台のHTMLファイル

HelloWorld.xml

<?xml version="1.0" encoding="UTF-8"?>
<application xmlns="http://ns.adobe.com/air/application/1.5">
<id>javascript.HelloWorld</id>
<filename>HelloWorld</filename>
<initialWindow>
<content>HelloWorld.html</content>
<visible>true</visible>
<width>400</width>
<height>300</height>
</initialWindow>
</application>


HelloWorld.html

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
"http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="ja" lang="ja">
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8" />
<meta http-equiv="Content-Style-Type" content="text/css" />
<meta http-equiv="Content-Script-Type" content="text/javascript" />
</head>
<body>
<h1>hello world!</h1>
</body>
</html>



コマンドプロンプトで作業フォルダに移動

cd \AIR\hello


adl HelloWorld.xml


これでAIRが実行できます。めでたしめでたし
posted by ねこまんま at 00:58 | Comment(0) | TrackBack(0) | テクニック | 更新情報をチェックする

2010年05月12日

Amazonの商品をランダムに表示するスクリプト

配列にセットしておいたAmazonの商品をランダムで表示するスクリプトです。

var books = [
{
title :"PHP 逆引きレシピ" ,
asin : "4798119865"
},
(中略)
{
title :"基礎から学べる PHP 標準コースウェア" ,
asin : "4774138002"
}
]
var list='', n=4 , l = books.length;
while (n-- > 0) {
var i = Math.random() * l | 0;
list += '<a href="http://amazon.co.jp/o/ASIN/'+books[i].asin+'/○○-22/ref=nosim"><img src="http://images.amazon.com/images/P/'+books[i].asin+'.09._OU09_SCTZZZZZZZ_.jpg" alt="'+books[i].title+'" /></a><br /><a href="http://amazon.co.jp/o/ASIN/+books[i].asin+/○○-22/ref=nosim">'+books[i].title+'</a><br /><br />';
books.splice(i, 1);
--l;
}
document.write(list)


document.writeとか手を抜き感満載ですが自由に改造して利用してください。
タグ:Amazon
posted by ねこまんま at 14:55 | Comment(0) | TrackBack(0) | テクニック | 更新情報をチェックする

overrideMimeTypeを利用してAjaxの文字化けに対応する

AjaxのXMLHttpRequestでSJISなどのファイルを読み込もうとした場合、文字化けすることがある。

これはoverrideMimeTypeを設定することで解消が可能だ。

var xhr = new XMLHttpRequest();
xhr.overrideMimeType("text/plain; charset=shift_jis");


ただしIEではoverrideMimeTypeが実装されていないので、この方法では対応ができない。
posted by ねこまんま at 14:31 | Comment(0) | TrackBack(0) | テクニック | 更新情報をチェックする

2010年05月11日

配列から任意の数の値をランダムに取得する方法

配列から任意の数のの値をランダムに取得する関数です。

function random(array, num) {
var a = array;
var t = [];
var r = [];
var l = a.length;
var n = num < l ? num : l;
while (n-- > 0) {
var i = Math.random() * l | 0;
r[n] = t[i] || a[i];
--l;
t[i] = t[l] || a[l];
}
return r;
}
var arr = ["hoge1","hoge2","hoge3","hoge4"];
random(arr, 3)


これは頭いい!

参考:配列からn個の要素を重複無しでランダムに取り出す - m2
タグ:random
posted by ねこまんま at 18:02 | Comment(0) | TrackBack(0) | テクニック | 更新情報をチェックする

乱数などの少数を整数に変換

普通は次のように書く

Math.floor(Math.random()*10);


floorメソッドを利用して小数点以下の数値を切り捨てます。

こういう風に書くことも出来ます。

~~(Math.random()*10)


こういう風に書くことも出来ます。

Math.random()*10|0


参考:Math.floor を使わずに小数を整数にする - IT戦記
タグ:Floor
posted by ねこまんま at 17:47 | Comment(0) | TrackBack(0) | テクニック | 更新情報をチェックする

2010年05月03日

クロージャー入門

次のようなプログラミングの場合li要素をクリックするたびに4を返す。(li要素は4つ)

window.onload = function(){
var lis = document.getElementsByTagName("li");
for(var i = 0 ; i<lis.length; i++){
lis[i].onclick = function(){
console.log(i)
}
}
}


次のようにclickイベントの設定を無名関数で包むと0,1,2,3のようにクリックした要素の番号を返す。

window.onload = function(){
var lis = document.getElementsByTagName("li");
for(var i = 0 ; i<lis.length; i++){
(function(n){
lis[i].onclick = function(){
console.log(n)
}
})(i);
}
}


これがクロージャー、イベントのスコープを利用して限定的な変数を動的に作り上げる

window.onload = function(){
var lis = document.getElementsByTagName("li");
var click = function(i,n){
n.onclick = function(){
console.log(i)
}
}
for(var i = 0 ; i<lis.length; i++){
click(i, lis[i]);
}
}


当然このように関数リテラルとして取り扱ってもよい
posted by ねこまんま at 08:06 | Comment(0) | TrackBack(0) | テクニック | 更新情報をチェックする

2010年04月29日

オブジェクトを配列に変換

配列かどうか調べる関数を使いながら調べると「Array.prototype.slice.apply」でオブジェクトを配列に変換出来るらしいです。

var func = function() {
  console.log(IsArray(arguments))//false
  var args = Array.prototype.slice.apply(arguments);
  console.log(IsArray(args))//true
};
function IsArray(array) {
  return(array.constructor===Array);
}
func(1,2,3)


参考:404 Blog Not Found:javascript - Array.prototype.slice.apply(arguments) // 引数一発配列化
タグ:apply slice
posted by ねこまんま at 04:22 | Comment(0) | TrackBack(0) | テクニック | 更新情報をチェックする

配列かどうか調べる関数

JavaScriptで配列かどうか調べる関数

function IsArray(array) {
  return(array.constructor===Array);
}
console.log(IsArray("hoge"))//false
console.log(IsArray({}))//false
console.log(IsArray(["aa","bb"]))//true


参考:javascriptのオブジェクトが配列かどうかを調べる関数 | りょーちの駄文と書評(コメント欄まで参照)

constructorではオブジェクトの初期化で使用されたコンストラクタ関数を参照することが出来るのでobjectなのかArrayなのかを判別できる。

参考:constructorとprototype.constructorがわからなくなった - 宇宙野武士は元気にしているか
タグ:Constructor array
posted by ねこまんま at 04:13 | Comment(0) | TrackBack(0) | テクニック | 更新情報をチェックする