javascript
JavaScriptのメモ
Table of Contents |
Bookmarklet
Examples of bookmarklets modifying URLs.
javascript:(function(){location=location.href.replace('http://ieeexplore.ieee.org','http://ieeexplore.ieee.org.proxy-um.researchport.umd.edu');})()
javascript:(function(){var c='edit';var f=location.href.split('?');if(!f[1].match('=')){location=f[0]+'?cmd='+c+'&page='+f[1];}else{location=f[0]+'?cmd='+c+'&'+f[1].match('page=[^&]+');}})()
Greasemonkey
A template of greasemonkey script modifying a links.
// ==UserScript== // @name UMDResearchPort // @namespace http://note.sonots.com // @description Access Papers via UMD Research Port // @include http://scholar.google.com/* // @include http://www.cfar.umd.edu/~aswch/enee731.2006/* // @include http://www.google.*/* // ==/UserScript== var links; links = document.getElementsByTagName('a'); for (var i = 0; i < links.length; i++) { links[i].href = links[i].href.replace('http://ieeexplore.ieee.org', 'http://ieeexplore.ieee.org.proxy-um.researchport.umd.edu'); links[i].href = links[i].href.replace('http://www.jstor.org', 'http://www.jstor.org.proxy-um.researchport.umd.edu'); }
Introduction to Object for other language experts
(Almost) Everything is Associative array
The structure concept is definable by using an associative array not only in javascript but also in other languages. For example, think PHP's way $person->name (class object) and $person['name'] (associative array). Just how to write is different. Therefore(?), javascript does not have Struct definition, but uses associative array.
Futhermore, if we set a lambda function to a key of an associative array, it works as a member function of a class. For example, think PHP's way $person->eat() and $person['eat']() (used create_function). Just how to write is different. Therefore(?), javascript does not have Class definition, but uses associative array.
var person = {"name":"hoge"}; alert(person["name"]); alert(person.name);
javascript has a syntax sugar to use associative array like object
javascript has a syntax sugar to define a key like a member variable name
var person = {name:"hoge"}; alert(person.name); alert(person["name"]);
Define a member function. Lambda function is set to a key.
var person = { name : "hoge", eat : function(){alert("Delicious!");}, }; person.eat(); person["eat"]();
Associative Array is not enough for Class
But, simply using associative array to express object is not so good. If we want to define other objects of the same class, we have to copy the object entirely and initialize values. We want only prototype, and want to "new" it. Javascript has such supports that other languages do not (Therefore(?), we do not use associative array to define class in other languages.)
var Person = function(){}; // or function Person(); // it's same Person.prototype = { name : "", eat : function(){alert("Delicious!");}, whoami : function(){alert(this.name);}, }; // Person.prototype.eat = function(){alert("Delicious!");}; is also okay for now var person = new Person(); person.name = "hoge"; alert(person.name); // "hoge" person.eat(); // we can easily create an instance of the same class var person2 = new Person(); alert(person.name); // "" person2.eat();
Javascript chose to use function objects to define class probably because we can define a constructor concurrently (If I were the designer of javascript language, I might've defined another syntax like "class". In fact, prototype.js does.) See the next.
var Person = function(name){this.name = name;}; // constructor // name is already defined in the constructor. Person.prototype.eat = function(){alert("Delicious!");}; Person.prototype.whoami = function(){alert(this.name);}; var person = new Person("hoge"); alert(person.name); person.eat();
"this." in the constructor may look same with "prototype." Thus, you may want to use only "this." to define member methods and variables so that you can define everything in one place. It would look similar with class definitions in the other languages.
function Person(name) { this.name = name; this.eat = function(){ alert("Delicious!"); }; this.whoami = function(){ alert(this.name); }; } var person = new Person("hoge"); alert(person.name); person.eat();
However, "this." and "prototype." are different. "this." allocate memory spaces for each object. Therefore, eat() and whoami() functions are recreated in each object although they are same.
If we define them in prototype, object shares the definition (reference). What "new" does is that person.__proto__ = Person.prototype, and call the constructor. Javascript passes objects by reference, so person.__proto__ refers Person.prototype and person2.__proto__ also refers Person.prototype.
We can override member methods and variables in each object.
var Person = function(name){this.name = name;}; Person.prototype = { eat : function(){alert("Delicious!");}, whoami : function(){alert(this.name);}, }; var person = new Person("hoge"); person.eat = function(){alert("Bad Taste!");} person.eat(); // Bad Taste! var person2 = new Person("hoge"); person2.eat(); // Delicious!
Think javascript chains searching as object.varname -> object.__proto__.varname -> object.__proto__.__proto__.varname-> ... up to root (Object prototype). This is like "extends" in the other languages (override).
I personally want to define everything in one place including a constructor. Fortunately, prototype.js has a trick for us.
var Person = Class.create(); Person.prototype = { name : "", height : null, initialize : function(name){this.name = name;}, eat : function(){alert("Delicious!");}, whoami : function(){alert(this.name);}, } var person = new Person("foo"); var person2 = new Person("bar");
"initialize" work as a constructor.