Showing posts with label global. Show all posts
Showing posts with label global. Show all posts

Friday, October 03, 2008

JavaScript函数调用时的作用域链和调用对象是如何形成的及与闭包的关系

1、javascript解析器启动时就会初始化建立一个全局对象global object,这个全局对象就拥有了一些预定义的全局变量和全局方法,如Infinity, parseInt, Math,所有程序中定义的全局变量都是这个全局对象的属性。在客户端javascript中,Window就是这个javascript的全局对象
2、当javascript调用一个function时,会生成一个对象,称之为call object(调用对象),function中的局部变量和function的参数都成为这个call object的属性,以免覆写同名的全局变量。
调用对象: ECMAScript规范术语称之为activation object(活动对象)。
3、javascript解析器每次执行function时,都会为此function创建一个execution context执行环境,在此function执行环境中最重要的一点就是function的作用域链scope chain,这是一个对象链,由全局对象调用对象构成,对象链具体构成过程见下面说明。
4、当javascript查询变量x的值时,就会检查此作用域链中第一个对象,可能是调用对象或者是全局对象,如果对象中有定义此x属性,则返回值,不然检查作用域链中的下一个对象是否定义x属性,在作用域链中没有找到,最后返回undefined。
5、当javascript调用一个function时,它会先将此function定义时的作用域作为其作用域链,然后创建一个调用对象,置于作用域链的顶部,function的参数及内部var声明的所有局部变量都会成为此调用对象的属性。
6、this关键词指向方法的调用者,而不是以调用对象的属性存在,同一个方法中的this在不同的function调用中,可能指向不同的对象。
7、The Call Object as a Namespace
(function() {
// 在方法体内用var声明的所有局部变量,都是以方法调用时创建的调用对象的属性形式存在。
// 这样就避免与全局变量发生命名冲突。
})();
8、javascript中所有的function都是一个闭包,但只有当一个嵌套函数被导出到它所定义的作用域外时,这种闭包才强大。如果理解了闭包,就会理解function调用时的作用域链和调用对象,才能真正掌握javascript。
9、当一个嵌套函数的引用被保存到一个全局变量或者另外一个对象的属性时,在这种情况下,此嵌套函数有一个外部引用,并且在其外围调用函数的调用对象中有一个属性指向此嵌套函数。因为有其他对象引用此嵌套函数,所以在外围函数被调用一次后,其创建的调用对象会继续存在,并不会被垃圾回收器回收,其函数参数和局部变量都会在这个调用对象中得以维持,javascript代码任何形式都不能直接访问此对象,但是此调用对象是嵌套函数被调用时创建的作用域链中的一部分,可以被嵌套函数访问并修改。

Tuesday, February 12, 2008

Using parseFloat() or "+" instead of parseInt()

parseInt() 在解析字符串为数字的时候,有时候会有点问题,如
parseInt("010") 可以被解析成10,也可能被解析成8,字符串以"0"开头可以被做为8进制解析也可以被做为十进制解析,所以parseInt('08')得到的结果是0,而parseInt('07')得到的结果却是7,如果parseInt('08', 10)的第二个参数明确说明解析为十进制数字时就会得到结果8。
一般解析字符串为数字时可以用parseFloat()这个全局函数或者是"+"运算符。
['2008', '02', '11', '06', '21', '03'].map(function(v) { return + v });
# [2008, 2, 11, 6, 21, 3]

Sunday, March 25, 2007

References with global and static variables

The Zend Engine 1, driving PHP 4, implements the static and global modifier for variables in terms of references. For example, a true global variable imported inside a function scope with the global statement actually creates a reference to the global variable. This can lead to unexpected behaviour which the following example address.


<?php
function global_ref()
{
//在function中用global,static引入的变量其实是对此变量建立了一个引用reference,
//在function执行完之后会对应变量的值不会丢失。
global $obj;
var_dump($obj);
echo "<br/>";
$obj = &new stdclass;
}
global_ref();
global_ref();
?>

<br/>

<?php
function global_noref()
{
global $obj;
var_dump($obj);
echo "<br/>";
if(!isset($obj))
{
$obj = new stdclass;
}
else
{
echo "has set variable: \$obj. <br/>";
}
}
global_noref();
global_noref();
?>
A similar behaviour applies to the static statement. References are not stored statically:

<?php
function static_ref()
{
static $sta;
var_dump($sta);
if(!isset($sta))
{
$sta = &new stdclass;
}
$sta->num++;
}
static_ref();
static_ref();
static_ref();
?>

<?php
function static_noref()
{
static $sta;
var_dump($sta);
echo "<br>";
if(!isset($sta))
{
$sta = new stdclass;
}
$sta->num++;
}
static_noref();
static_noref();
static_noref();
?>

Using the global keyword inside a function to define a variable is essentially the same as passing the variable by reference as a parameter:

somefunction(){
global $var;
}

is the same as:

somefunction(& $a) {

}

The advantage to using the keyword is if you have a long list of variables needed by the function - you dont have to pass them every time you call the function.

Saturday, March 24, 2007

The global keyword


<?php
$a = 1;
$b = 2;
$GLOBALS['c'] = 3;
echo $c, "<br>";
$d = 4;

function Sum()
{
global $a, $b;

$b = $a + $b + $GLOBALS['c'] + $GLOBALS['d'];
}

Sum();
echo $b;
?>

The above script will output "3", "10". By declaring $a and $b global within the function, all references to either variable will refer to the global version. There is no limit to the number of global variables that can be manipulated by a function.

A second way to access variables from the global scope is to use the special PHP-defined $GLOBALS array.

The $GLOBALS array is an associative array with the name of the global variable being the key and the contents of that variable being the value of the array element. Notice how $GLOBALS exists in any scope, this is because $GLOBALS is a superglobal.