Javascript 随记
1. 闭包的例子
uniqueID = function () {
if (!arguments.callee.id) arguments.callee.id = 0;
return arguments.callee.id++;
}
// uniqueID = (function () {
// var id = 0;
// return function () { return id++; };
// })();
alert(uniqueID());
alert(uniqueID());
alert(uniqueID());
alert(uniqueID());
前一种方法的问题在于,任何人都可以把 uniqueID.id设置回0,并且违反函数所保证的它不会两次返回相同的值的约定。可以通过在只有该函数能够访问的闭包中存储持久性值的方法在防止这样的问题。。
Function() 构造函数
var f = new Function("x", "y", "return x*y");
function f(x, y) { return x*y };
上面两种语法等价,Function最后一个参数是函数的函数体, Function()构造函数的几个重要特点
1. Function() 构造函数允许 Javascript代码动态地创建并且在运行时编译。 例如,全局eval();
2. Function() 构造函数解析函数体,并且每次被调用的时候都创建一个新的函数对象。如果构造函数的调用出现在一个循环中,或者出现在一个经常被调用的函数中,那么这个过程的效率就很低了。相反,出现在一个循环或者函数中的函数直接量或者嵌套的函数,并不会每次遇到的时候都编译。每次遇到一个函数直接量也不会创建不同的函数对象。
3. 最后,关于Function()函数非常重要的一点是, 它所创建的函数并不实用词法作用域,相反,它们总是当作顶层的函数一样编译。
var f = new Function("x", "y", "return x*y");
var y = "global";
function constructFunction() {
var y = "local";
return new Function("return y");
}
alert(constructFunction()());
2. 变量
Javascript和Java这样的语言之间存在一个重要的差别,那就是Javascript是非类型(untype)的。这就意味着Javascript的变量可以存放任何类型的值。有一个特性是与Javascript缺少类型规则相关,即在必要时JavaScript可以快速、自动的将一种类型转换成另一种类型。例如,如果想把一个数值连接到一个字符串上。那么Javascript会自动把这个数值转换成相应的字符串。
变量的声明, 由var声明的变量是永久性的,也就是说,用delete运算符来删除这些变量将会引发错误。
如果在全局作用域中编写代码时可以不使用var 语句,但是在声明局部变量时,一定要使用var语句。。不然是全局变量
scope = "global";
function checkscope() {
scope = "local";
document.write(scope);
var privateScope="private"
myscope = "myscope";
document.write(myscope);
}
checkscope();
document.write(scope);
// document.write(privateScope);
document.write(myscope);
javascript 没有块级作用域, 和 C, C++以及Java不同。Javascript没有块级作用域。函数中声明的所用变量,无论在哪里声明的,在整个函数中它们都是定义的。
基本类型和引用类型
数据类型氛围两组,即基本类型和引用类型
数值、布尔值、null和undefined属于基本类型。 对象、数组和函数属于引用类型。。
基本类型在内存中具有固定的大小,,可以直接存放任何类型的值。引用类型变量存储的是对这个值的引用。通常引用的形式是指针或者内存地址。
var a = 3.14;
var b = a;
a = 4;
alert(b)
var a = [1, 2, 3];
var b = a;
a[0] = 99;
alert(b);
var a = "jacky";
var b = a;
a = "shuang";
alert(b);
垃圾收集
var s = "hello"; //allocate memory for a string
var u = s.toUpperCase() // Create a new string
s = u; /// Overwrite reference to original string
运行了这些代码之后,就不能再获得原始的字符串“hello” ,因为程序中没有变量再引用它了。系统检测到这一事实后,就会释放该字符串的存储空间以便这些空间可以再利用
全局对象
当javascript的解释器开始运行时,它首先要做的事情之一就是在执行任何javascript代码之前,创建一个全局对象(global object)这个对象的属性就是javascript程序中的全局变量。当声明一个javascript的全局变量时,实际上所做的是定义了那个全局对象的一个属性。
此外,javascript解释器还会用预定义的值和函数来初始化全局对象的许多属性。例如: 属性Infinity parseInt 和Math分别引用了数值infinity、预定义函数parseInt()和预定义对象Math。
在客户端javascript中,window对象代表浏览器窗口,它是包含在该窗口中的所有javascript代码的全局对象。这个全局window对象具有自我引用的window属性,它代替了this属性,可以用来引用这个全局对象。window对象定义了全局的核心属性,如parseInt 和Math, 此外它还定义了全局的客户端属性,如navigator 和screen。
如果全局变量是特殊的全局对象的属性,那么局部变量是一个对象的属性,这个对象被成为调用对象(call object)。虽然调用对象的生命周期比全局对象的短,但是他们的用途是相同的。在之星一个函数时,函数的参数和局部变量是作为调用对象的属性而存储的。用一个完全独立的对象来存储局部变量是javascript可以防止局部变量覆盖同名的全局变量的值
在javascript中,变量基本上和对象的属性是一样的。
Javascript并不像java c++ 语言那样支持真正的类。 但是。在javascript中可以定义伪类。做到这一点工具就是构造函数和原型对象。
构造函数
用对象直接量或{} 或如下的表达式 new Object() 来创建其他类型的javascript对象
var array = new Array();
var today = new Date();
new运算符的后面必须跟着一个函数调用。 new创建了一个新的没有任何属性的对象, 然后调用该函数, 把新的对象作为this关键字的值传递。 设计来和new运算符一起使用的函数叫做构造函数。。 构造函数的工作是初始化一个新创建的对象,设置在实用对象前需要设置的所有属性。可以定义自己的构造函数,只需要编写一个为this添加属性的函数就可以了。
function jacky(o,j) {
var zhong = 0;
this.width = o;
this.height = j;
function dd() {
}
}
var hua = new jacky(1,"52");
通过定义一个适合的构造函数,就定义了对象的一个类,所有实用jacky()构造函数的穿件的对象现在都确保初始化了width属性和height属性。
构造函数通常没有返回值。它们初始化作为this的值来传递的对象,并且没有返回值。然而,一个构造函数是允许返回一个对象值的,并且,如果它这么做了,返回的对象成为new表达式的值。在此情况下,作为this的值的对象会被抛弃。