函数

  • 函数表达式不用于函数声明。函数声明要求有名字,但函数表达式不需要。没有名字的函数表达式也叫作匿名函数。

函数声明的重要特性式函数声明提升(function declaration hoisting).

sayHi();  


//函数声明 和 函数声明提升
function sayHi(){
  alert("Hi");
}

//函数表达式
var functionName = function(arg0, arg1, arg2){

}

  • 递归函数应该始终使用arguments.callee来递归的调用自身,不要使用函数名–函数名可能会变化
function factorial(num){
  if(num <= 1){
    return 1
  }else{
    return num * factorial(num - 1)
  }
}

var anotherFactorail = factorial;
factorial = null;
alert(anotherFactorail(4)) //出错

以上代码把factorial() 函数保存在一个变量anotherFactorail中,再将factorial 变量设置为null. 但在调用anotherFactorail()时,由于需要执行factorial(),而 factorial不再是函数,所以会报错。

正确的做法

function factorial(num){
  if(num <= 1){
    return 1
  }else{
    return num * arguments.callee(num - 1)
  }
}

arguments.callee 是一个指向正在执行的函数的指针,因此可以用它来实现对函数的递归调用。

闭包(closure)

请看我的这篇文章

当函数内部定义了其它函数时,就创建了闭包。闭包有权访问包含函数内部的所有变量,原理如下

  • 在后台执行环境中,闭包的作用域链包含着他自己的作用域、包含函数的作用域和全局作用域
  • 通常,函数的作用域及其所有变量都会在函数执行结束后被销毁

  • 但是,当函数返回一个闭包时,这个函数的作用域会一直在内存中保存闭包不存在为止

闭包可以在javascript 中模仿块级作用域

  • 创建并立即调用一个函数,这样既可以执行其中的代码,又不会在内存中留下对函数的引用。
  • 结果就是函数内部的所有变量都会被立即销毁--除非将某些变量赋值给了包含作用域(即外部作用域)中的变量
(function (){
  //这里是一个块级作用域(block scope)
  })();


function outoutNumbers(count){
  (function(){
    for(var i = 0; i < count; i++){
      alert(i);
    }
    })();

    alert(i); //导致错误
}


  • 闭包还可以用于在对象中创建私有变量

  • JavaScript中没有正式的私有对象属性的概念,但可以使用闭包来实现公有方法,而通过公有方法可以访问在包含作用域中定义的变量

  • 有权访问私有变量的公有方法叫做特权方法 (Privileged Method)

  • 可以使用构造函数模式,原型模式来实现自定义类型的特权方法,也可以使用模块模式,增强的模块模式来实现单例的特权方法。

function MyObejct(){

  //私有变量和函数
  var privateVariable = 10;

  function privateFunction(){
    return false;
  }

  //特权方法
  this.publicMethod = function (){
    privateVariable++;
    return privateFunction();
  }
}

具体请看javascript高级程序设计 P187

JavaScript 中的函数表达式和闭包都是极其有用的特性,可以利用它们来实现很多功能。不过,因为创建闭包必须维护额外的作用域,所以过度使用它们可能会占用大量内存。

引用类型

此文章是总结javascript高级程序设计第5章内容

Object 数据类型

  • object 是一个基础类型,其他所有类型都从object继承基本行为

创建Object实例的两种方法

// new 和Object 构造函数
var person = new Object() 
person.name = "Nicholas";
person.age = 29;
//对象字面量
var person = {
    name: "Nicholas",
    age : 29
};

通过对象字面量定义对象时,不会调用Object构造函数

Array 类型

  • ECMAScript 数组每一项可以保存任何类型的数据
  • 数组大小可以动态调整

创建数组的方式

// new 和 Array 构造函数
var colors = new Array ()

//数组字面量
var colors = ["red","blue","green"];

与对象一样,在使用数组字面量时,不会调用Array构造函数

转换方法

  • 所有对象都具有toLocalString(), toString()和valueOf()方法
  • toString() 会返回有数组中每个值得字符串形式拼接而成的一个以逗号分隔得字符串

  • valueOf() 返回的还是数组
var colors = ["red","blue","green"];
alert(colors.toString()) //"red,blue,green"
alert(colors.valueOf()) //["red","blue","green"]

栈方法(LIFO)

  • push()
  • pop()
var colors = ["red","blue"];
colors.push("brown"); //添加一项
colors[3] = "black"; //添加一项
alert(colors.length); //4

var item = colors.pop();
alert(item); //"black"

队列方法(FIFO)

  • shift()
  • unshift()
  • push()

用shift()和push(),可以像使用队列一样使用数组

var colors = new Array(); // 创建一个数组
var count = colors.push("red","green"); //推入两项
alert(count); //2

count = colors.push("black"); //推入另一项
alert(count); //3

var item = colors.shift(); //取得第一项
alert(item);  // 'red'
alert(colors.length) //2

unshfit()和shift()刚好相反

var colors = new Array();
var count = colors.unshitf("red","green"); //推入两项
alert(count); //2

count = colors.unshift("black"); //推入另一项
alert(count); //3

var item = colors.pop();  //取得最后一项
alert(item); //"green"
alert(colors.length); //2

重排序方法

  • reverse()
  • sort()
//reverse()
var values = [1,2,3,4,5]
alert(values.reverse()); //5,4,3,2,1

// sort()
var values = [0,1,5,10,15];
alert(values.sort()); //0,1,10,15,5

sort()方法比较的是字符串
在进行字符串比较时,10位于5前面

我们可以pass一个函数

var values = [0,1,5,10,15]
alert(values.sort((a,b)=>{
    return a > b
})); // 0,1,5,10,15

操作方法

  • concat()
  • slice()
//concat()
var colors = ["red","green","blue"];
var colors2 = colors.concat("yellow",["black","brown"]);

alert(colors);  //red, green, blue
alert(colors2); //red,green,blue,yellow,black,brown

slice()接受一或两个参数,即要返回项的起始和结束位置(end 不包括)。在只有一个参数的情况下,slice()返回从该参数指定位置开始到当前数组末尾的所有项。

注意,slice()方法不会影响原始数组

var colors = ["red","green","blue","yellow","purple"];
var colors2 = colors.slice(1);
var colors3 = colors.slice(1,4);

alert(color2);  //green,blue,yellow,purple
alert(color3);  //green,blue,yellow

Javascript 教程(一)

Javascript 简介

JavaScript is one of the 3 languages all web developers must learn:
1. HTML to define the content of web pages
2. CSS to specify the layout of web pages
3. JavaScript to program the behavior of web pages

Javascript的实现

一个完整的Javascript实现应该由下面三个不同部分组成

  • 核心(ECMAScript)
  • 文档对象模型(DOM)
  • 浏览器对象模型(BOM)

ECMAScript

ECMAScript 规定了这门语言的下列组成部分:

  • 语法
  • 类型
  • 语句
  • 关键字
  • 保留字
  • 操作符
  • 对象

ECMAScript 就是对实现该标准规定的各个方面内容的语言的描述

文档对象类型(DOM)

文档对象模型(DOM, Document Object Model)把整个页面映射为一个多层节点结构。


通过DOM创建的这个表示文档的树形图,开发人员获得了控制页面内容和结构的主动权。

DOM 级别

DOM 1级有两个模块组成: DOM核心(DOM Core)和DOM HTML.

  • DOM Core 规定了如何映射基于XML的文档结构
  • DOM HTML 添加了对HTML的对象和方法

DOM 1级的目标主要是映射文档的结构
DOM 2 级引入了下列新模块

  • DOM视图(DOM Views)
  • DOM事件(DOM Events)
  • DOM 样式(DOM Style)
  • DOM 遍历和范围(DOM Traversal and Range)

DOM 3级引入了以统一方式加载和保存文档的方法

浏览器对象模型(BOM)

BOM(Browser Object MOdel)

从根本上讲,BOM只处理浏览器窗口和框架

以上的内容先做个了解就好,等到学到具体的章节的时候,在做具体了解。