占位以后写

主要是理解

1. 任何对象都可以用来作为hastable使用.

2. hashtable的key接受任何类型.

3. 但不意味着任何类型都可以作为key,事实上 hashtable的key的类型只有string型, 接受的其他类型最终会被转换为string. 

 

 

No Comments 2008-09-25 04:41:30 by Homyu.Shinn

以前很少写window间通讯的脚本,一直以为Global 变量的访问范围和var的一样。今天在写Triglav作弊工具的时候突然发现了个奇怪的问题,让我重新思考了Global变量的作用域,顺便复习一下var和this。

This的作用域:作用与当前实例,并且只能使用this关键字访问。比如 a = new Object,这时候a就是一个实例。那么当a下有一个方法,无论这个方法是实例化前就写好的,还是实例化后用a.foo= function(){}添加上去的,在这个方法里,this关键字都指向a。

Sample:

FooClass = function()
{
    this.Variable = "This is a public variable.";
    this.Say = function()
    {
        alert(this.Variable);
    }
}

foo = new FooClass();
foo.Say();
foo.Say2 = function()
{
    alert(this.Variable);
}
foo.Say2();

注:
1) 上面这个例子中可以把this.Variable替换一下试试看。

2) 另外,方法中的this指向(俗称“上下文”)是可以通过call, apply等方法改变,这点与下面的var不同。

Var的作用域:Var变量(下称私有变量)只作用于变量申明时的所在函数(updated 9/19/08) 的花括号 "{   }"以内。也就是说,它的作用域是依附与代码本身的,你的代码写在哪,作用域就在哪,而且在运行时是不可以改变的。

FooClass = function()
{
    var Var = "This is a variable which defined by var.";
    this.ThisVar = "This is a variable which defined by this.";
    var self = this;
    this.Say = function()
    {
        setTimeout(function()
        {
            alert(Var);
            alert(typeof this.ThisVar);
            alert(self.ThisVar);
        },  1000);
    }
}

foo = new FooClass;
foo.Say();

大家可以在上面的例子中看到,无论有几层{}的嵌套var声明的变量始终可以穿越他们,并且被scope内的变量访问到。
同时,在这个例子里,我们可以看到setTimeout中function的this并不是foo,typeof this.ThisVar返回的是undefined,但是我们在这里利用了var的特性,耍了个花招(var self = this),让不同上下文的方法能够访问到同一个实例。

Global变量:global变量javascript中可以直接用“variable_name = variable_value”来声明,也可以用"this.variable_name=xx“或者"var variable_name=xx“来声明,后两者要求声明表达式必须在最外最顶层,而且第一种声明可以在代码中的任意位置。要理解Global的作用域,首先要知道javascript中,任何一个window其实都是一个实例,而所有的global变量,都是属于window这个实例的。


而我们当前代码的上下文,如果没有特殊指定,都是在window实例下。换句话说,你可以直接使用this.variable_name来访问一个global变量----但是,这又与我们平时的使用习惯不一样,我相信大多数的jser在书写代码的习惯都是直接使用variable_name。而这种不使用this关键字访问global变量的方法和访问var声明的变量很相似--确实,在javascript中global变量其实是有双重特性的,它既可以使用this访问,也可以不使用this。当你使用this访问时,会先确定当前的上下文,再找到上下文中的指定变量。而如果没有this,那么毫无疑问会访问到代码文本所属的window下的某个global变量。

现在来看这种情况:假设我们有两个页面,分别为win1和win2。win2是由win1打开的,所以我们可以拿到win2的window对象,而且他们是在同一个域名下,不存在跨域访问的问题。
这时候做这样一件事:在win1下想做一个小小的hack,把win2下的CallLocalVar函数修改一下,让win2的代码在调用CallLocalVar函数时,先调用帽子函数(这时帽子函数其实算在win2的实例下),再由帽子函数调用回win2下原来的CallLocalVar。
这时候会有很有趣的事情发生,因为帽子函数是用win2.CallLocalVar = function(){}定义的,所以他的上下文应当是win2,但是又由于代码本身是在win1下写的,那么当帽子函数中global变量的访问方法是用“通常习惯的方式(无this)”方式访问的, 那么帽子函数最后会访问回win1下的global变量。

请看下面的例子:

win1.htm里的内容:
<script>
local = "this is win1 global variable";

win2 = window.open("win2.htm","win2");

setTimeout(function()
{
    local.test = win2.CallLocal;
    win2.CallLocal = function()
    {
        this.alert(local);
        if (local.test)
        {
            //local.test();
        }
    }

}, 4000);

</script>

win2.htm的内容:
<body>
<script>
local = "this is win2 global variable";

function CallLocal()
{
    alert(local);
}

</script>

<button onclick="CallLocal()">Wait 4 sec and then click</button>
</body>



好了,最后有个终级问题:
如果将win2.htm中的<button onclick="Call....</button>替换成setTimeout(CallLocal, 10000)会怎么样?

 

大牛们的相关讨论:http://bbs.51js.com/viewthread.php?tid=79018

http://www.jibbering.com/faq/faq_notes/closures.html

Tags: scope, javascript

No Comments 2008-06-30 00:19:50 by Homyu.Shinn

运行以下代码,会发现每次hello()出来的值都增加了&mdash;&mdash;虽然他们是属于不同实例,


ProtoBase = function()
{
 var i = 0;
 this.Get = function()
 {
  alert(i.toString());
  i++;
 }
}

ProtoDerived = function()
{
 this.Hello = function()
 {
  this.Get();
 }
}

ProtoDerived.prototype = new ProtoBase();

pd1 = new ProtoDerived();
pd2 = new ProtoDerived();

pd1.Hello();
pd2.Hello();

这是为什么呢?其实很简单,var申明的变量的可访问域是在其所属的“{ }”以内的所有代码块。因此,当Get被调用时,他所访问的i就是离他最近用 var 申明的私有i&mdash;&mdash;他们是相同的。

Tags: javascript, oop

No Comments 2008-06-27 21:48:09 by Homyu.Shinn

Here is rough sample of json request which was written while i was writting a tool for getting to do items from todoist, the requester in this sample can do a ordered request, block the 2nd request before 1st requst complete.

 

var bIdle = true;

function RequestAPI(sAPIUrl, iProjectID, sToken, sCallbackName, sAddtionalParameter)
{
 var argus = arguments;
 if (bIdle)
 {
  bIdle = false;
  var script = document.createElement('script');
  script.type = 'text/javascript';
  script.src = sAPIUrl + '?project_id=' + iProjectID.toString() + '&token=' + sToken + '&callback=' + sCallbackName + ((sAddtionalParameter!=null)?"&" + sAddtionalParameter:"");
  console.innerHTML +=script.src + "<br />";
  script.onreadystatechange = ReleaseAPIScript;
  document.getElementsByTagName('head')[0].appendChild(script);
 }
 else
 {
  setTimeout(function ()
  {
   RequestAPI.apply(window, argus);
  }, 1000);
 }
  
}

function ReleaseAPIScript()
{
 if (this.readyState.toLowerCase() == "loaded")
 {
  var elmtScript = this;
  // Release script after 1 min
  setTimeout(function(){
   document.getElementsByTagName('head')[0].removeChild(elmtScript);
  }, 1000);
  bIdle = true;
 }
}

Tags: json, javascript

No Comments 2008-06-24 11:11:48 by Homyu.Shinn