JavaScript权威指南 - 函数

本文全面解析JavaScript函数,涵盖函数定义、调用、属性、闭包、函数式编程等核心概念,探讨函数在JavaScript中的特殊角色及其强大功能。

函数本身就是一段JavaScript代码,定义一次但可能被调用任意次。如果函数挂载在一个对象上,作为对象的一个属性,通常这种函数被称作对象的方法。用于初始化一个新创建的对象的函数被称作构造函数。

相对于其他面向对象语言,在JavaScript中的函数是特殊的,函数即是对象。JavaScript可以把函数赋值给变量,或者作为参数传递给其他函数,甚至可以给它们设置属性等。

JavaScript的函数可以嵌套在其他函数中定义,这样定义的函数就可以访问它们外层函数中的任何变量。这也就是所谓的“闭包”,它可以给JavaScript带来强劲的编程能力。

函数定义

函数使用function关键字定义,有函数语句和函数表达式两种定义方式。

//一.函数语句类:

//打印对象所有属性名称和值。
function printprops(obj) {
    for (var key in obj) {
        console.log(key + ":" + obj[key]);
    }
}
//计算阶乘的递归函数,函数名称将成为函数内部的一个局部变量。
function factorial(n) {
    if (n <= 1) return 1;
    return n * factorial(n);
}

//二.函数表达式类:

//计算n的平方的函数表达式。这里将一个函数赋给一个变量。
var square = function (x) { return x * x; }

//兔子数列。函数表达式也可以包含名称,方便递归。
var foo = function foo(n) {
    if (n <= 1) return 1;
    else foo(n - 1) + foo(n - 2);
}

//数组元素升序排列。函数表达式也能作为参数传递给其他函数。
var data = [5, 3, 7, 2, 1];
data.sort(function (a, b) { return a - b; });

//函数表达式有时定义后立即调用。
var tensquared = (function (x) { return x * x; }(10));

函数命名

函数名称要求简洁、描述性强,因为这样可以极大改善代码的可读性,方便别人维护代码;函数名称通常是动词或以动词开头的词组。通常来说,函数名编写有两种约定:

  • 一种约定是函数名第一个单词首字母小写,后续单词首字母大写,就像likeThis()
  • 当函数名包含多个单词时,另一种约定是用下划线来分割单词,就像like_this()

项目中编写方法名时尽量选择一种保持代码风格一致。还有,对于一些私有函数(不作为公用API的一部分),这种函数通常以一条下划线作为前辍。

函数调用

函数声明后需要通过调用才能被执行。JavaScript中通常有4种方式来调用函数:

  • 作为普通函数;
  • 作为对象方法;
  • 作为构造函数;
  • 通过它们的call()apply()方法间接调用。

下面就通过一些具体示例来演示上述4中函数的调用方式。

1.对于普通函数,通过调用表达式就可直接调用,这种方式很直接也很常见。

//定义一个普通函数。
var strict = function () { return !this; }; //检测当前运行环境是否为严格模式。
//通过函数名直接调用。
console.log(strict()); 

注:根据ES3和非严格的ES5对普通函数调用的规定,调用上下文this是全局对象;在严格模式下,调用上下文则是undefined

2.通常,保存在对象属性里的JavaScript函数被称作“方法”。

//定义一个对象直接量。
var calc = { 
    a: null,
    b: null,
    add: function () { //将函数保存在对象属性中。
        return this.a + this.b;
    }
};
//通过对象名调用方法。
calc.a = 1, calc.b = 2;
console.log(calc.add()); 

注:对象方法中的调用上下文this不同于普通函数中的上下文。这里this指代当前对象。

方法链:当方法返回值是一个对象,那么这个对象还可以再调用它的方法。每次调用的结果都是另外一个表达式的组成部分,这种方法调用方式最终会形成一个序列,也被称为“方法链”。所以,在自己设计API的时候,当方法并不需要返回值时,最好直接返回this。这样以后使用API就可以进行“链式调用”风格的编程。

需要注意的是,this是一个关键字,Javascript语法不允许给它赋值。再者,关键字this没有作用域的限制,嵌套的函数不会从外层调用它的函数中继承this。也就是说,如果嵌套函数作为方法调用,其this指向为调用它的对象。如果嵌套函数作为函数调用,其this值不是全局对象就是undefined。下面通过一段代码来具体说明。

var o = {
    m: function () { //对象中的方法
        var self = this; //将this的值保存在一个变量中
        console.log(this === o); //输出true,表明this就是这个引用对象o
        f(); //调用嵌套函数f()
        function f() { //定义一个嵌套函数(**普通函数,非对象方法)
            console.log(this === o); //输出false,this的值为全局对象或undefined
            console.log(self === o); //输出true,变量self指外部函数的this值
        }
    }
}

3.如果函数或者防方法调用之前带有关键字new,它就构成构造函数调用。构造函数调用会创建一个新的对象,构造函数通常不使用return,函数体执行完毕它会显示返回。还有,创建的对象继承自构造函数的prototype属性,构造函数中使用this关键字来引用这个新创建的对象。

//与普通函数一样的定义方式。
function Person(name, age) {
    this.name = name;
    this.age = age;
    this.say = function () {
        console.log("My name is " + this.name + ", I am " + this.age + " years old.");
    }
}
//用关键字new调用构造函数,实例化对象。
var obj = new Person("Lamb", "21");
obj.say();//调用对象方法。

4.我们知道Javascript中的函数也是对象,所以函数对象也是可以包含方法的,其中call()apply()两个方法可以用来间接地调用函数,这两个方法都可以显式指定调用函数里面的调用上下文this

//定义一个打印函数。
function print() {
    if (this.text) {
        alert(this.text);
    } else {
        alert("undefined");
    }
}
//call方法间接调用方法,并指定其调用上下文。
print.call({ text: "hello" });

关于call()apply()两个方法的用法以及区别下面详细讨论。

函数的实参和形参

JavaScript中的函数定义不需要指定函数形参的类型,调用函数时也不检查传入形参的个数。这样,同时也会留下两个疑问给我们:

当调用函数时的实参个数和声明的形参个数不匹配的时候如何处理;
如何显式测试函数实参的类型,以避免非法的实参传入函数。
下面就简单介绍JavaScript是如何对上述两个问题做出处理的。

可选参数

当调用函数的时候传入的实参比函数定义时指定的形参个数要少,剩下的形参都将设置为undefined。一般来说,为了保持函数较好的适应性,都会给省略的参数设置一个合理的默认值。

function getPropertyNames(obj,/*optional*/arr) {
    arr=arr||[];
    for (var property in obj) { arr.push(property); }
    return arr;
}

需要注意的是,当使用这种可选实参来实现函数时,需要将可选实参放在实参列表的最后。一般来书,函数定义中使用注释/*optional*/来强调形参是可选的。

实参对象

当调用函数时传入的参数个数超过了原本函数定义的形参个数,那么方法中可以通过实参对象来获取,标识符arguments是指向实参对象的引用。实参对象是一个类数组对象,可以通过数字下标来访问传入函数的实参值。实参对象有一个重要的用处,就是让函数可以操作任意数量的实参,请看下面的例子:

//返回传入实参的最大值。
function max(/* ... */) {
    var max = Number.NEGATIVE_INFINITY; //该值代表负无穷大。
    for (var i = 0; i < arguments.length; i++) {
        if (arguments[i] > max) {
            max = arguments[i];
        }
    }
    return max;
}
//调用。
var largest = max(10, 45, 66, 35, 21); //=>66

还有重要的一点,如果函数中修改arguments[]元素,同样会影响对应的实参变量。

除以上之外,实参对象还包含了两个属性calleecaller

  • callee是ECMAScript标准规范的,它指代当前正在执行的函数。

  • caller是非标准属性但是大多数浏览器都支持,它指代当前正在执行函数的函数。

//callee可以用来递归匿名函数。
var sum = function (x) {
    if (x <= 1) return 1;
    return x + arguments.callee(x - 1);
}

//调用函数b,方法a中打印结果为函数b。
 var a = function () {
     alert(a.caller); 
 }
 var b = function () {
     a();
 }

注意,在ECMAScript 5严格模式下,对这两个属性进行读写会产生一个类型错误。

实参类型

声明JavaScript函数时形参不需要指定类型,在形参传入函数体之前也不会做任何类型检查,但是JavaScript在必要的时候会进行类型转换,例如:

function mult(a, b) {
    return a * b;
}
function conn(x, y) {
    return x + y;
}
console.log(mult(3, "2")); //字符串类型自动转为数字类型,输出结果:6
console.log(conn(3, "2")); //数字类型自动转为字符串类型,输出结果:"32"

上述的两种类型存在隐式转换关系所以JS可以自动转换,但是还存在其他情况:比如,一个方法期望它第一个实参为数组,传入一个非数组的值就可能引发问题,这时就应当在函数体中添加实参类型检查逻辑。

作为值的函数

开篇提到过,在JavaScript中函数不仅是一种语法,函数即是对象,简单归纳函数具有的几种性质:

1.函数可以被赋值给一个变量;

function square(x) { return x * x; }
var s = square; //现在s和square指代同一个函数对象
square(5); //=>25
s(5); //=>25

2.函数可以保存在对象的属性或数组元素中;

var array = [function (x) { return x * x; }, 20];
array[0](array[1]); //=>400

3.函数可以作为参数传入另外一个函数;

//这里定义一些简单函数。
function add(x, y) { return x + y; }
function subtract(x, y) { return x - y; }
function multipty(x, y) { return x * y; }
function divide(x, y) { return x / y; }
//这里函数以上面某个函数做参数。
function operate(operator, num1, num2) {
    return operator(num1, num2);
}
//调用函数计算(4*5)-(2+3)的值。
var result = operate(subtract, operate(multipty, 4, 5), operate(add, 2, 3));
console.log(result); //=>15

4.函数可以设置属性。

//初始化函数对象的计数器属性。
uniqueInteger.counter = 0;
//先返回计数器的值,然后计数器自增1。
function uniqueInteger() {
    return uniqueInteger.counter+=1; 
}

当函数需要一个“静态”变量来在调用时保持某个值不变,最方便的方式就是给函数定义属性,而不是定义全局变量,因为定义全局变量会让命名空间变的杂乱无章。

作为命名空间的函数

函数中声明的变量只在函数内部是有定义,不在任何函数内声明的变量是全局变量,它在JavaScript代码中的任何地方都是有定义的。JavaScript中没有办法声明只在一个代码块内可见的变量的。基于这个原因,常常需要定义一个函数用作临时的命名空间,在这个命名空间内定义的变量都不会污染到全局变量。

//该函数就可看作一个命名空间。
function mymodule() {
    //该函数下的变量都变成了“mymodule”空间下的局部变量,不会污染全局变量。
}
//最后需要调用命名空间函数。
mymodule();
上段代码还是会暴露出一个全局变量:mymodule函数。更为常见的写法是,直接定义一个匿名函数,并在单个表达式中调用它:

//将上面mymodule()函数重写成匿名函数,结束定义并立即调用它。
(function () {
    //模块代码。
}());

闭包

闭包是JavaScript中的一个难点。在理解闭包之前先要明白变量作用域和函数作用域链两个概念。

  • 变量作用域:无非就是两种,全局变量和局部变量。全局变量拥有全局作用域,在任何地方都是有定义的。局部变量一般是指在函数内部定义的变量,它们只在函数内部有定义。

  • 函数作用域链:我们知道JavaScript函数是可以嵌套的,子函数对象会一级一级地向上寻找所有父函数对象的变量。所以,父函数对象的所有变量,对子函数对象都是可见的,反之则不成立。需要知道的一点是,函数作用域链是在定义函数的时候创建的。

关于“闭包”的概念书本上定义很具体,但是也很抽象,很难理解。简单的理解,“闭包”就是定义在一个函数内部的函数(这么说并不准确,应该说闭包是函数的作用域)。

var scope = "global scope"; //全局变量
function checkscope() {
    var scope = "local scope"; //局部变量
    function f() { return scope; } //在作用域中返回这个值
    return f();
}
checkscope(); //=>"local scope"

上面一段代码就就实现了一个简单的闭包,函数f()就是闭包。根据输出结果,可以看出闭包可以保存外层函数局部变量,通过闭包可以把函数内的变量暴露在全局作用域下。

闭包有什么作用呢?下面一段代码是上文利用函数属性定义的一个计数器函数,其实它存在一个问题:恶意代码可以修改counter属性值,从而让uniqueInteger函数计数出错。

//初始化函数对象的计数器属性。
uniqueInteger.counter = 0;
//先返回计数器的值,然后计数器自增1。
function uniqueInteger() {
    return uniqueInteger.counter+=1; 
}

闭包可捕捉到单个函数调用的局部变量,并将这些局部变量用作私有状态,故我们可以利用闭包的特性来重写uniqueInteger函数。

//利用闭包重写。
var uniqueInteger = (function () { //定义函数并立即调用
    var counter = 0; //函数的私有状态
    return function () {
        return counter += 1;
    };
})();
//调用。
uniqueInteger(); //=>1
uniqueInteger(); //=>2
uniqueInteger(); //=>3

当外部函数返回后,其他任何代码都无法访问counter变量,只有内部的函数才能访问。根据输出结果可以看出,闭包会使得函数中的变量都被保存在内存中,内存消耗大,所以要合理使用闭包。

counter一样的私有变量在多个嵌套函数中都可以访问到它,因为这多个嵌套函数都共享同一个作用域链,看下面一段代码:

function counter() {
    var n = 0;
    return {
        count: function () { return n += 1; },
        reset: function () { n = 0; }
    };
}
var c = counter(), d = counter(); //创建两个计时器
c.count(); //=>0
d.count(); //=>0 能看出它们互不干扰
c.reset(); //reset和count方法共享状态
c.count(); //=>0 因为重置了计数器c
d.count(); //=>1 而没有重置计数器d

书写闭包的时候还需注意一件事,this是JavaScript的关键字,而不是变量。因为闭包内的函数只能访问闭包内的变量,所以this必须要赋给that才能引用。绑定arguments的问题与之类似。

var name = "The Window";
var object = {
    name: "My Object",
    getName: function () {
        var that = this;
        return function () {
            return that.name;
        };
    }
};
console.log(object.getName()()); //=>"My Object"

到这里如果你还不明白我在说什么,这里推荐两篇前辈们写的关于“闭包”的文章。

函数属性、方法和构造函数

前文已经介绍过,在JavaScript中函数也是对象,它也可以像普通对象一样拥有属性和方法。

length属性

在函数体里,arguments.length表示传入函数的实参的个数。而函数本身的length属性表示的则是“形参”,也就是在函数调用时期望传入函数的实参个数。

function check(args) {
    var actual = args.length; //参数的真实个数
    var expected = args.callee.length; //期望的实参个数
    if (actual!=expected) { //如果不同则抛出异常
        throw Error("Expected "+ expected+"args;got "+ actual);
    }
}
function f(x,y,z) {
    check(arguments); //检查实参和形参个数是否一致。
    return x + y + z; 
}

prototype属性

每个函数都包含prototype属性,这个属性指向一个对象的引用,这个对象也就是原型对象。当将函数用作构造函数的时候,新创建的对象会从原型对象上继承属性。

call()方法和apply()方法

上文提到,这两个方法可以用来间接调用函数。call()apply()的第一个实参表示要调用函数的母对象,它是调用上下文,在函数内通过this来引用母对象。假如要想把函数func()以对象obj方法的形式来调用,可以这样:

func.call(obj);
func.apply(obj);

call()apply()的区别之处是,第一个实参(调用上下文)之后的所有实参传入的方式不同。

func.call(obj, 1, 2); //实参可以为任意数量
func.apply(obj, [1, 2]); //实参都放在了一个数组中

下面看一个有意思的函数,他能将一个对象的方法替换为一个新方法。这个新方法“包裹”了原始方法,实现了AOP。

/调用原始方法之前和之后记录日志消息
function trace(o, m) {
    var original = o[m]; //在闭包中保存原始方法
    o[m] = function () { //定义新方法
        console.log(new Date(), "Entering:", m); //输出日志消息
        var result = original.apply(o, arguments); //调用原始方法
        console.log(new Date(), "Exiting:", m); //输出日志消息
        return result; //返回结果
    }
}

这种动态修改已有方法的做法,也被称作“猴子补丁(monkey-patching)”。

bind()方法

bind()方法是ES5中新增的方法,这个方法的主要作用是将函数绑定至某个对象。该方法会返回一个新的函数,调用这个新的函数会将原始函数当作传入对象的方法来调用。

function func(y) { return this.x + y; } //待绑定的函数
var o = { x: 1 }; //将要绑定的对象
var f = func.bind(o);//通过调用f()来调用o.func()
f(2); //=>3

ES3中可以通过下面的代码来实现bind()方法:

if (!Function.prototype.bind) {
    Function.prototype.bind = function (o /* , args */) {
        //将this和arguments保存在变量中,以便在嵌套函数中使用。
        var self = this, boundArgs = arguments;
        //bind()方法返回的是一个函数。
        return function () {
            //创建一个参数列表,将传入bind()的第二个及后续的实参都传入这个函数。
            var args = [], i;
            for (var i = 1; i < boundArgs.length; i++) {
                args.push(boundArgs[i]);
            }
            for (var i = 0; i < arguments.length; i++) {
                args.push(boundArgs[i]);
            }
            //现在将self作为o的方法来调用,传入这些实参。
            return self.apply(o,args);
        }
    }
}

Function()构造函数

定义函数时需要使用function关键字,但是函数还可以通过Function()构造函数来定义。Function()构造函数可以传入任意数量字符串实参,最后一个实参字符串表示函数体,每两条语句之间也需要用分号分隔。

var f = Function("x", "y", "return x*y;");
//等价于下面的函数
var f = function f(x, y) { return x * y; }

关于Function()构造函数需要注意以下几点:

  • Function()构造函数允许Javascript在运行时动态创建并编译函数;
  • 每次调用Function()构造函数都会解析函数体并创建新的函数。如果将其放在循环代码块中执行,执行效率会受到影响;
  • 最重要的一点,它所创建的函数并不是使用词法作用域,相反,函数体代码的编译总是会在顶层函数执行。比如下面代码所示:
var scope = "global scope"; 
function checkscope() {
var scope = "local scope"; 
return Function("return scope;"); //无法捕获局部作用域
}
checkscope(); //=>"global scope"

Function()构造函数可以看作是在全局作用域中执行的eval(),在实际开发中很少见到。

函数式编程

JavaScript中可以像操控对象一样操控函数,也就是说可以在JavaScript中应用函数式编程技术。

使用函数处理数组

假设有一个数组,数组元素都是数字,我们想要计算这些元素的平均值和标准差。可以利用map()reduce()等数组方法来实现,符合函数式编程风格。

//首先定义两个简单的函数。
var sum = function (x, y) { return x + y; }
var square = function (x) { return x * x }
//将上面的函数和数组方法配合使用计算出平均数和标准差。
var data = [1, 1, 3, 5, 5];
var mean = data.reduce(sum) / data.length;
var deviations = data.map(function (x) { return x - mean; });
var stddev = Math.sqrt(deviations.map(square).reduce(sum) / (data.length - 1));

高阶函数

所谓高阶函数就是函数操作函数,它接收一个或多个函数作为参数,并返回一个新的函数。

//返回传入函数func返回值的逻辑非。
function not(func) {
    return function () {
        var result = func.apply(this, arguments);
        return !result;
    };
}
//判断传入参数a是否为偶数。
var even = function (x) {
    return x % 2 === 0;
}
var odd = not(even); //odd为新的函数,所做的事和even()相反。
[1, 1, 3, 5, 5].every(odd); //=>true 每个元素都是奇数。

这里是一个更常见的例子,它接收两个函数f()g(),并返回一个新的函数用以计算f(g())

//返回一个新的函数,计算f(g(...))。
function compose(f, g) {
    return function () {
        //需要给f()传入一个参数,所以使用f()的call()方法。
        //需要给g()传入很多参数,所以使用g()的apply()方法。
        return f.call(this, g.apply(this, arguments));
    }
}

var square = function (x) { return x * x; }
var sum = function (x, y) { return x + y; }
var squareofsum = compose(square, sum);
squareofsum(2, 3); //=>25

记忆

能将上次计算的结果缓存起来,在函数式编程当中,这种缓存技巧叫做“记忆”。下面的代码展示了一个高阶函数,memorize()接收一个函数作为实参,并返回带有记忆能力的函数。

//返回f()的带有记忆功能的版本。
function memorize(f) {
    //将值保存在闭包中。
    var cache = {};
    return function () {
        //将实参转换为字符串形式,并将其用做缓存的键。
        var key = arguments.length + Array.prototype.join.call(arguments, ",");
        if (key in cache) {
            return cache[key];
        } else {
            return cache[key] = f.apply(this, arguments);
        }
    }
}

memorize()所返回的函数将它的实参数组转换成字符串,并将字符串用做缓存对象的属性名。如果缓存中存在这个值,则直接返回它,否则调用既定的函数对实参进行计算,将计算结果缓存起来并保存。下面代码展示了如何使用memorize()

//返回两个整数的最大公约数。
function gcd(a, b) {
    var temp;
    if (a < b) { //确保 a >= b
        temp = b;
        b = a;
        a = temp;
    }
    while (b != 0) { //这里是求最大公约数的欧几里德算法
        temp = b;
        b = a % b;
        a = temp;
    }
    return a;
}
var gcdmemo = memorize(gcd);
gcdmemo(85, 187);

//当写一个递归函数时,往往需要实现记忆功能。
var factorial = memorize(function (n) {
    return (n <= 1) ? 1 : n * factorial(n - 1);
});
factorial(5); //=>120

参考与扩展

本篇内容源自我对《JavaScript权威指南》第8章 函数 章节的阅读总结和代码实践。总结的比较粗糙,你也可通过原著或MDN更深入了解函数。

[1] David Flanagan,JavaScript权威指南(第6版)
[2] MDN,JavaScript 参考文档 - Functions - JavaScript | MDN

转载于:https://www.cnblogs.com/esofar/p/6256157.html

JavaScript权威指南 犀牛书 Chapter 1. Introduction to JavaScript Section 1.1. JavaScript Myths Section 1.2. Versions of JavaScript Section 1.3. Client-Side JavaScript Section 1.4. JavaScript in Other Contexts Section 1.5. Client-Side JavaScript: Executable Content in Web Pages Section 1.6. Client-Side JavaScript Features Section 1.7. JavaScript Security Section 1.8. Example: Computing Loan Payments with JavaScript Section 1.9. Using the Rest of This Book Section 1.10. Exploring JavaScript Part I: Core JavaScript Chapter 2. Lexical Structure Section 2.1. Character Set Section 2.2. Case Sensitivity Section 2.3. Whitespace and Line Breaks Section 2.4. Optional Semicolons Section 2.5. Comments Section 2.6. Literals Section 2.7. Identifiers Section 2.8. Reserved Words Chapter 3. Data Types and Values Section 3.1. Numbers Section 3.2. Strings Section 3.3. Boolean Values Section 3.4. Functions Section 3.5. Objects Section 3.6. Arrays Section 3.7. null Section 3.8. undefined Section 3.9. The Date Object Section 3.10. Regular Expressions Section 3.11. Error Objects Section 3.12. Primitive Data Type Wrapper Objects Chapter 4. Variables Section 4.1. Variable Typing Section 4.2. Variable Declaration Section 4.3. Variable Scope Section 4.4. Primitive Types and Reference Types Section 4.5. Garbage Collection Section 4.6. Variables as Properties Section 4.7. Variable Scope Revisited Chapter 5. Expressions and Operators Section 5.1. Expressions Section 5.2. Operator Overview Section 5.3. Arithmetic Operators Section 5.4. Equality Operators Section 5.5. Relational Operators Section 5.6. String Operators Section 5.7. Logical Operators Section 5.8. Bitwise Operators Section 5.9. Assignment Operators Section 5.10. Miscellaneous Operators Chapter 6. Statements Section 6.1. Expression Statements Section 6.2. Compound Statements Section 6.3. if Section 6.4. else if Section 6.5. switch Section 6.6. while Section 6.7. do/while Section 6.8. for Section 6.9. for/in Section 6.10. Labels Section 6.11. break Section 6.12. continue Section 6.13. var Section 6.14. function Section 6.15. return Section 6.16. throw Section 6.17. try/catch/finally Section 6.18. with Section 6.19. The Empty Statement Section 6.20. Summary of JavaScript Statements Chapter 7. Functions Section 7.1. Defining and Invoking Functions Section 7.2. Functions as Data Section 7.3. Function Scope: The Call Object Section 7.4. Function Arguments: The Arguments Object Section 7.5. Function Properties and Methods Chapter 8. Objects Section 8.1. Objects and Properties Section 8.2. Constructors Section 8.3. Methods Section 8.4. Prototypes and Inheritance Section 8.5. Object-Oriented JavaScript Section 8.6. Objects as Associative Arrays Section 8.7. Object Properties and Methods Chapter 9. Arrays Section 9.1. Arrays and Array Elements Section 9.2. Array Methods Chapter 10. Pattern Matching with Regular Expressions Section 10.1. Defining Regular Expressions Section 10.2. String Methods for Pattern Matching Section 10.3. The RegExp Object Chapter 11. Further Topics in JavaScript Section 11.1. Data Type Conversion Section 11.2. By Value Versus by Reference Section 11.3. Garbage Collection Section 11.4. Lexical Scoping and Nested Functions Section 11.5. The Function( ) Constructor and Function Literals Section 11.6. Netscape's JavaScript 1.2 Incompatibilities Part II: Client-Side JavaScript Chapter 12. JavaScript in Web Browsers Section 12.1. The Web Browser Environment Section 12.2. Embedding JavaScript in HTML Section 12.3. Execution of JavaScript Programs Chapter 13. Windows and Frames Section 13.1. Window Overview Section 13.2. Simple Dialog Boxes Section 13.3. The Status Line Section 13.4. Timeouts and Intervals Section 13.5. Error Handling Section 13.6. The Navigator Object Section 13.7. The Screen Object Section 13.8. Window Control Methods Section 13.9. The Location Object Section 13.10. The History Object Section 13.11. Multiple Windows and Frames Chapter 14. The Document Object Section 14.1. Document Overview Section 14.2. Dynamically Generated Documents Section 14.3. Document Color Properties Section 14.4. Document Information Properties Section 14.5. Forms Section 14.6. Images Section 14.7. Links Section 14.8. Anchors Section 14.9. Applets Section 14.10. Embedded Data Chapter 15. Forms and Form Elements Section 15.1. The Form Object Section 15.2. Defining Form Elements Section 15.3. Scripting Form Elements Section 15.4. Form Verification Example Chapter 16. Scripting Cookies Section 16.1. An Overview of Cookies Section 16.2. Storing Cookies Section 16.3. Reading Cookies Section 16.4. Cookie Example Chapter 17. The Document Object Model Section 17.1. An Overview of the DOM Section 17.2. Using the Core DOM API Section 17.3. DOM Compatibility with Internet Explorer 4 Section 17.4. DOM Compatibility with Netscape 4 Section 17.5. Convenience Methods: The Traversal and Range APIs Chapter 18. Cascading Style Sheets and Dynamic HTML Section 18.1. Styles and Style Sheets with CSS Section 18.2. Element Positioning with CSS Section 18.3. Scripting Styles Section 18.4. DHTML in Fourth-Generation Browsers Section 18.5. Other DOM APIs for Styles and Style Sheets Chapter 19. Events and Event Handling Section 19.1. Basic Event Handling Section 19.2. Advanced Event Handling with DOM Level 2 Section 19.3. The Internet Explorer Event Model Section 19.4. The Netscape 4 Event Model Chapter 20. Compatibility Techniques Section 20.1. Platform and Browser Compatibility Section 20.2. Language Version Compatibility Section 20.3. Compatibility with Non-JavaScript Browsers Chapter 21. JavaScript Security Section 21.1. JavaScript and Security Section 21.2. Restricted Features Section 21.3. The Same-Origin Policy Section 21.4. Security Zones and Signed Scripts Chapter 22. Using Java with JavaScript Section 22.1. Scripting Java Applets Section 22.2. Using JavaScript from Java Section 22.3. Using Java Classes Directly Section 22.4. LiveConnect Data Types Section 22.5. LiveConnect Data Conversion Section 22.6. JavaScript Conversion of JavaObjects Section 22.7. Java-to-JavaScript Data Conversion Part III: Core JavaScript Reference Chapter 23. Core JavaScript Reference Sample Entry arguments[ ] Arguments Arguments.callee Arguments.length Array Array.concat( ) Array.join( ) Array.length Array.pop( ) Array.push( ) Array.reverse( ) Array.shift( ) Array.slice( ) Array.sort( ) Array.splice( ) Array.toLocaleString( ) Array.toString( ) Array.unshift( ) Boolean Boolean.toString( ) Boolean.valueOf( ) Date Date.getDate( ) Date.getDay( ) Date.getFullYear( ) Date.getHours( ) Date.getMilliseconds( ) Date.getMinutes( ) Date.getMonth( ) Date.getSeconds( ) Date.getTime( ) Date.getTimezoneOffset( ) Date.getUTCDate( ) Date.getUTCDay( ) Date.getUTCFullYear( ) Date.getUTCHours( ) Date.getUTCMilliseconds( ) Date.getUTCMinutes( ) Date.getUTCMonth( ) Date.getUTCSeconds( ) Date.getYear( ) Date.parse( ) Date.setDate( ) Date.setFullYear( ) Date.setHours( ) Date.setMilliseconds( ) Date.setMinutes( ) Date.setMonth( ) Date.setSeconds( ) Date.setTime( ) Date.setUTCDate( ) Date.setUTCFullYear( ) Date.setUTCHours( ) Date.setUTCMilliseconds( ) Date.setUTCMinutes( ) Date.setUTCMonth( ) Date.setUTCSeconds( ) Date.setYear( ) Date.toDateString( ) Date.toGMTString( ) Date.toLocaleDateString( ) Date.toLocaleString( ) Date.toLocaleTimeString( ) Date.toString( ) Date.toTimeString( ) Date.toUTCString( ) Date.UTC( ) Date.valueOf( ) decodeURI( ) decodeURIComponent( ) encodeURI( ) encodeURIComponent( ) Error Error.message Error.name Error.toString( ) escape( ) eval( ) EvalError Function Function.apply( ) Function.arguments[] Function.call( ) Function.caller Function.length Function.prototype Function.toString( ) Global Infinity isFinite( ) isNaN( ) Math Math.abs( ) Math.acos( ) Math.asin( ) Math.atan( ) Math.atan2( ) Math.ceil( ) Math.cos( ) Math.E Math.exp( ) Math.floor( ) Math.LN10 Math.LN2 Math.log( ) Math.LOG10E Math.LOG2E Math.max( ) Math.min( ) Math.PI Math.pow( ) Math.random( ) Math.round( ) Math.sin( ) Math.sqrt( ) Math.SQRT1_2 Math.SQRT2 Math.tan( ) NaN Number Number.MAX_VALUE Number.MIN_VALUE Number.NaN Number.NEGATIVE_INFINITY Number.POSITIVE_INFINITY Number.toExponential( ) Number.toFixed( ) Number.toLocaleString( ) Number.toPrecision( ) Number.toString( ) Number.valueOf( ) Object Object.constructor Object.hasOwnProperty( ) Object.isPrototypeOf( ) Object.propertyIsEnumerable( ) Object.toLocaleString( ) Object.toString( ) Object.valueOf( ) parseFloat( ) parseInt( ) RangeError ReferenceError RegExp RegExp.exec( ) RegExp.global RegExp.ignoreCase RegExp.lastIndex RegExp.source RegExp.test( ) RegExp.toString( ) String String.charAt( ) String.charCodeAt( ) String.concat( ) String.fromCharCode( ) String.indexOf( ) String.lastIndexOf( ) String.length String.localeCompare( ) String.match( ) String.replace( ) String.search( ) String.slice( ) String.split( ) String.substr( ) String.substring( ) String.toLocaleLowerCase( ) String.toLocaleUpperCase( ) String.toLowerCase( ) String.toString( ) String.toUpperCase( ) String.valueOf( ) SyntaxError TypeError undefined unescape( ) URIError Part IV: Client-Side JavaScript Reference Chapter 24. Client-Side JavaScript Reference Sample Entry Anchor Applet Area Button Button.onclick Checkbox Checkbox.onclick Document Document.all[] Document.captureEvents( ) Document.clear( ) Document.close( ) Document.cookie Document.domain Document.elementFromPoint( ) Document.getSelection( ) Document.handleEvent( ) Document.lastModified Document.links[] Document.open( ) Document.releaseEvents( ) Document.routeEvent( ) Document.URL Document.write( ) Document.writeln( ) Element Event FileUpload FileUpload.onchange Form Form.elements[] Form.onreset Form.onsubmit Form.reset( ) Form.submit( ) Form.target Frame getClass( ) Hidden History History.back( ) History.forward( ) History.go( ) HTMLElement HTMLElement.contains( ) HTMLElement.getAttribute( ) HTMLElement.handleEvent( ) HTMLElement.insertAdjacentHTML( ) HTMLElement.insertAdjacentText( ) HTMLElement.onclick HTMLElement.ondblclick HTMLElement.onhelp HTMLElement.onkeydown HTMLElement.onkeypress HTMLElement.onkeyup HTMLElement.onmousedown HTMLElement.onmousemove HTMLElement.onmouseout HTMLElement.onmouseover HTMLElement.onmouseup HTMLElement.removeAttribute( ) HTMLElement.scrollIntoView( ) HTMLElement.setAttribute( ) Image Image.onabort Image.onerror Image.onload Input Input.blur( ) Input.click( ) Input.focus( ) Input.name Input.onblur Input.onchange Input.onclick Input.onfocus Input.select( ) Input.type Input.value JavaArray JavaClass JavaObject JavaPackage JSObject JSObject.call( ) JSObject.eval( ) JSObject.getMember( ) JSObject.getSlot( ) JSObject.getWindow( ) JSObject.removeMember( ) JSObject.setMember( ) JSObject.setSlot( ) JSObject.toString( ) Layer Layer.captureEvents( ) Layer.handleEvent( ) Layer.load( ) Layer.moveAbove( ) Layer.moveBelow( ) Layer.moveBy( ) Layer.moveTo( ) Layer.moveToAbsolute( ) Layer.offset( ) Layer.releaseEvents( ) Layer.resizeBy( ) Layer.resizeTo( ) Layer.routeEvent( ) Link Link.onclick Link.onmouseout Link.onmouseover Link.target Location Location.reload( ) Location.replace( ) MimeType Navigator Navigator.javaEnabled( ) Navigator.plugins.refresh( ) Option Password Plugin Radio Radio.onclick Reset Reset.onclick Screen Select Select.onchange Select.options[] Style Submit Submit.onclick Text Text.onchange Textarea Textarea.onchange URL Window Window.alert( ) Window.back( ) Window.blur( ) Window.captureEvents( ) Window.clearInterval( ) Window.clearTimeout( ) Window.close( ) Window.confirm( ) Window.defaultStatus Window.focus( ) Window.forward( ) Window.handleEvent( ) Window.home( ) Window.moveBy( ) Window.moveTo( ) Window.name Window.navigate( ) Window.onblur Window.onerror Window.onfocus Window.onload Window.onmove Window.onresize Window.onunload Window.open( ) Window.print( ) Window.prompt( ) Window.releaseEvents( ) Window.resizeBy( ) Window.resizeTo( ) Window.routeEvent( ) Window.scroll( ) Window.scrollBy( ) Window.scrollTo( ) Window.setInterval( ) Window.setTimeout( ) Window.status Window.stop( ) Part V: W3C DOM Reference Chapter 25. W3C DOM Reference Sample Entry AbstractView AbstractView.getComputedStyle( ) Attr CDATASection CharacterData CharacterData.appendData( ) CharacterData.deleteData( ) CharacterData.insertData( ) CharacterData.replaceData( ) CharacterData.substringData( ) Comment Counter CSS2Properties CSSCharsetRule CSSFontFaceRule CSSImportRule CSSMediaRule CSSMediaRule.deleteRule( ) CSSMediaRule.insertRule( ) CSSPageRule CSSPrimitiveValue CSSPrimitiveValue.getCounterValue( ) CSSPrimitiveValue.getFloatValue( ) CSSPrimitiveValue.getRectValue( ) CSSPrimitiveValue.getRGBColorValue( ) CSSPrimitiveValue.getStringValue( ) CSSPrimitiveValue.setFloatValue( ) CSSPrimitiveValue.setStringValue( ) CSSRule CSSRuleList CSSRuleList.item( ) CSSStyleDeclaration CSSStyleDeclaration.getPropertyCSSValue( ) CSSStyleDeclaration.getPropertyPriority( ) CSSStyleDeclaration.getPropertyValue( ) CSSStyleDeclaration.item( ) CSSStyleDeclaration.removeProperty( ) CSSStyleDeclaration.setProperty( ) CSSStyleRule CSSStyleSheet CSSStyleSheet.deleteRule( ) CSSStyleSheet.insertRule( ) CSSUnknownRule CSSValue CSSValueList CSSValueList.item( ) Document Document.createAttribute( ) Document.createAttributeNS( ) Document.createCDATASection( ) Document.createComment( ) Document.createDocumentFragment( ) Document.createElement( ) Document.createElementNS( ) Document.createEntityReference( ) Document.createEvent( ) Document.createNodeIterator( ) Document.createProcessingInstruction( ) Document.createRange( ) Document.createTextNode( ) Document.createTreeWalker( ) Document.getElementById( ) Document.getElementsByTagName( ) Document.getElementsByTagNameNS( ) Document.getOverrideStyle( ) Document.importNode( ) DocumentCSS DocumentEvent DocumentFragment DocumentRange DocumentStyle DocumentTraversal DocumentType DocumentView DOMException DOMImplementation DOMImplementation.createCSSStyleSheet( ) DOMImplementation.createDocument( ) DOMImplementation.createDocumentType( ) DOMImplementation.createHTMLDocument( ) DOMImplementation.hasFeature( ) DOMImplementationCSS Element Element.getAttribute( ) Element.getAttributeNode( ) Element.getAttributeNodeNS( ) Element.getAttributeNS( ) Element.getElementsByTagName( ) Element.getElementsByTagNameNS( ) Element.hasAttribute( ) Element.hasAttributeNS( ) Element.removeAttribute( ) Element.removeAttributeNode( ) Element.removeAttributeNS( ) Element.setAttribute( ) Element.setAttributeNode( ) Element.setAttributeNodeNS( ) Element.setAttributeNS( ) ElementCSSInlineStyle Entity EntityReference Event Event.initEvent( ) Event.preventDefault( ) Event.stopPropagation( ) EventException EventListener EventTarget EventTarget.addEventListener( ) EventTarget.dispatchEvent( ) EventTarget.removeEventListener( ) HTMLAnchorElement HTMLAnchorElement.blur( ) HTMLAnchorElement.focus( ) HTMLBodyElement HTMLCollection HTMLCollection.item( ) HTMLCollection.namedItem( ) HTMLDocument HTMLDocument.close( ) HTMLDocument.getElementById( ) HTMLDocument.getElementsByName( ) HTMLDocument.open( ) HTMLDocument.write( ) HTMLDocument.writeln( ) HTMLDOMImplementation HTMLElement HTMLFormElement HTMLFormElement.reset( ) HTMLFormElement.submit( ) HTMLInputElement HTMLInputElement.blur( ) HTMLInputElement.click( ) HTMLInputElement.focus( ) HTMLInputElement.select( ) HTMLOptionElement HTMLSelectElement HTMLSelectElement.add( ) HTMLSelectElement.blur( ) HTMLSelectElement.focus( ) HTMLSelectElement.remove( ) HTMLTableCaptionElement HTMLTableCellElement HTMLTableColElement HTMLTableElement HTMLTableElement.createCaption( ) HTMLTableElement.createTFoot( ) HTMLTableElement.createTHead( ) HTMLTableElement.deleteCaption( ) HTMLTableElement.deleteRow( ) HTMLTableElement.deleteTFoot( ) HTMLTableElement.deleteTHead( ) HTMLTableElement.insertRow( ) HTMLTableRowElement HTMLTableRowElement.deleteCell( ) HTMLTableRowElement.insertCell( ) HTMLTableSectionElement HTMLTableSectionElement.deleteRow( ) HTMLTableSectionElement.insertRow( ) HTMLTextAreaElement HTMLTextAreaElement.blur( ) HTMLTextAreaElement.focus( ) HTMLTextAreaElement.select( ) LinkStyle MediaList MediaList.appendMedium( ) MediaList.deleteMedium( ) MediaList.item( ) MouseEvent MouseEvent.initMouseEvent( ) MutationEvent MutationEvent.initMutationEvent( ) NamedNodeMap NamedNodeMap.getNamedItem( ) NamedNodeMap.getNamedItemNS( ) NamedNodeMap.item( ) NamedNodeMap.removeNamedItem( ) NamedNodeMap.removeNamedItemNS( ) NamedNodeMap.setNamedItem( ) NamedNodeMap.setNamedItemNS( ) Node Node.appendChild( ) Node.cloneNode( ) Node.hasAttributes( ) Node.hasChildNodes( ) Node.insertBefore( ) Node.isSupported( ) Node.normalize( ) Node.removeChild( ) Node.replaceChild( ) NodeFilter NodeIterator NodeIterator.detach( ) NodeIterator.nextNode( ) NodeIterator.previousNode( ) NodeList NodeList.item( ) Notation ProcessingInstruction Range Range.cloneContents( ) Range.cloneRange( ) Range.collapse( ) Range.compareBoundaryPoints( ) Range.deleteContents( ) Range.detach( ) Range.extractContents( ) Range.insertNode( ) Range.selectNode( ) Range.selectNodeContents( ) Range.setEnd( ) Range.setEndAfter( ) Range.setEndBefore( ) Range.setStart( ) Range.setStartAfter( ) Range.setStartBefore( ) Range.surroundContents( ) Range.toString( ) RangeException Rect RGBColor StyleSheet StyleSheetList StyleSheetList.item( ) Text Text.splitText( ) TreeWalker TreeWalker.firstChild( ) TreeWalker.lastChild( ) TreeWalker.nextNode( ) TreeWalker.nextSibling( ) TreeWalker.parentNode( ) TreeWalker.previousNode( ) TreeWalker.previousSibling( ) UIEvent UIEvent.initUIEvent( ) ViewCSS Part VI: Class, Property, Method, and Event Handler Index Chapter 26. Class, Property, Method, and Event Handler Index Section 26.1. A Section 26.2. B Section 26.3. C Section 26.4. D Section 26.5. E Section 26.6. F Section 26.7. G Section 26.8. H Section 26.9. I Section 26.10. J Section 26.11. K Section 26.12. L Section 26.13. M Section 26.14. N Section 26.15. O Section 26.16. P Section 26.17. Q Section 26.18. R Section 26.19. S Section 26.20. T Section 26.21. U Section 26.22. V Section 26.23. W Section 26.24. X Section 26.25. Y Section 26.26. Z
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值