02_JavaScript函数与对象

发布时间 2023-10-31 15:29:29作者: 城市炊烟

一、JavaScript函数

为什么要有函数?

如果要在多个地方求1-100之间所有数的和,应该怎么做?

1.1、JavaScript函数的定义

1.1.1、函数概念

​ 函数是由事件驱动的或者当它被调用时执行的可重复使用的代码块。通俗来讲:把一段相对独立的具有特定功能的代码块封装起来,形成一个独立实体,就是函数,起个名字(函数名)。

​ 函数的作用就是封装一段代码,将来可以重复使用

​ 函数就是包裹在花括号中的代码块:

1.1.2、函数语法

  • 函数声明
function 函数名(参数列表){
    // 函数体
}
  • 函数表达式
var fn = function () {
  // 函数体
}
  • 特点:

    函数声明的时候,函数体并不会执行,只要当函数被调用的时候才会执行。

    函数一般都用来干一件事情,函数名称一般使用动词

1.2、JavaScript声明式函数的应用

函数的应用分为两步,一是先声明一个函数,再调用该函数。

声明函数:

1、声明无参函数语法

2、声明有参函数的语法

3、声明带有返回值的函数

1.2.1、函数的调用

  • 调用函数的语法:
函数名();
  • 特点:

    函数体只有在调用的时候才会执行,调用需要()进行调用。
    可以调用多次(重复使用)

在JavaScript中,调用函数时,如果没有返回值,就直接用函数方法名()调用。如果有参数,则必须给每个参数赋值,函数方法名(参数值),如果还有返回值,可以用一个变量来存储这个值。

代码示例:

// 声明无参函数:无参函数就是在函数名的小括号中不定义任何参数。
function sayHello() {
  console.log("吃了没?");
}
// 调用无参函数
sayHello();

// 求1-100之间所有数的和
function getSum() {
  var sum = 0;
  for (var  i = 0; i < 100; i++) {
    sum += i;
  }
  console.log(sum);
}
// 调用
getSum();

1.2.2、函数的参数

  • 为什么要有参数
function getSum() {
  var sum = 0;
  for (var i = 1; i <= 100; i++) {
    sum += i;
  }
  console.log();
}

// 虽然上面代码可以重复调用,但是只能计算1-100之间的值
// 如果想要计算n-m之间所有数的和,应该怎么办呢?
  • 语法:
// 函数内部是一个封闭的环境,可以通过参数的方式,把外部的值传递给函数内部
// 带参数的函数声明
function 函数名(var1, var2...) {
  // 函数体
}

上面的var1,var2就是参数,它代表一个不确定的值,这个值要参与函数代码块的运算,在调用函数时,可以给这些参数赋值。也可以在函数中定义多个参数,每个参数之间逗号 (,) 分隔:

当声明函数时,参数相当于作为变量来声明。

变量和参数必须以一致的顺序出现。第一个变量就是第一个被传递的参数的给定的值,以此类推。

// 带参数的函数调用
函数名(实参1, 实参2, 实参3); 
形参1 = 实参1
形参2 = 实参2
  • 形参和实参

    1. 形式参数:在声明一个函数的时候,为了函数的功能更加灵活,有些值是固定不了的,对于这些固定不了的值。我们可以给函数设置参数。这个参数没有具体的值,仅仅起到一个占位置的作用,我们通常称之为形式参数,也叫形参。
    2. 实际参数:如果函数在声明时,设置了形参,那么在函数调用的时候就需要传入对应的参数,我们把传入的参数叫做实际参数,也叫实参。

    需要注意的是,同一个函数,形参和实参是一一对应的。

    思考:如何区分实参和形参?
    ​ 1、出现的地方不一样,一个是在函数的声明中,一个出现在函数的调用中。

    ​ 2、代表的意义不一样,一个是声明一个变量,一个是该变量的值。

// 定义变量x和y
var x = 5, y = 6;
// 调用fn函数,把x和y传递到函数里面
fn(x,y); 

function fn(a, b) {
  console.log(a + b);
}
// x,y实参,有具体的值。函数执行的时候会把x,y复制一份给函数内部的a和b,函数内部的值是复制的新值,无法修改外部的x,y

代码示例:

// - 圆的面积 = pi * r * r;
function getArea(r) {
    var pi = 3.1415926;
    console.log(pi * r * r);
}
getArea(7);

// - 求2个数中的最大值
function getMax(a, b) {
    if (a > b) {
        console.log(a);
    } else {
        console.log(b);
    }
}
var x = 100;
var y = 1000;
getMax(x, y);

// - 求3个数中的最大值
function getMax(a, b, c) {
    if (a > b && a > c) {
        console.log(a);
    } else if (b > a && b > c) {
        console.log(b);
    } else if (c > a && c > b) {
        console.log(c);
    }
} 

getMax(11111, 100, 1000);

// 求n个数的最大值?
function getMax(arr) {
    // 参数arr  是数组
    var max = arr[0];
    for (var i = 1; i < arr.length; i++) {
        // 判断max和数组中之后的每一个元素进行比较
        if (max < arr[i]) {
            max = arr[i];
        }
    }
    console.log(max);
}
var array = [12, 2, 45, 1, 10];
getMax(array);

// - 判断一个数是否是素数(又叫质数,只能被1和自身整数的数)
function jdugePrimeNumber(number) {
    // 假设number是质数
    var isPrime = true;
    for (var i = 2; i < number; i++) {
        // 判断是否有能被number整数的数
        if (number % i === 0) {
            // 如果此处执行了。说明不是质数
            isPrime = false;
            break;
        }
    }
    if (isPrime) {
        console.log('质数');
    } else {
        console.log('不是质数');
    }
}
jdugePrimeNumber(13);

1.2.3、函数的返回值

当函数执行完的时候,并不是所有时候都要把结果打印。我们期望函数给我一些反馈(比如计算的结果返回进行后续的运算),这个时候可以让函数返回一些东西,也就是返回值。函数通过return返回一个返回值。

语法如下:

//声明一个带返回值的函数
function 函数名(形参1, 形参2, 形参3...) {
  //函数体
  return 返回值;
}

//可以通过变量来接收这个返回值
var 变量 = 函数名(实参1, 实参2, 实参3...);

函数的调用结果就是返回值,因此我们可以直接对函数调用结果进行操作。

示范:利用函数计算两个数相乘后的值,并返回。

//1、声明一个带参数的方法
function myFunction(a,b) {
	return a*b;
}
//2、调用带参的方法
var mul=myFunction(5,6);

代码示例:

// - 求一组数中的最大值
function getMax(arr) {
    var max = arr[0];
    for (var i = 1; i < arr.length; i++) {
        if (max < arr[i]) {
            max = arr[i];
        }
    }
    // 函数的返回值
    return max;
}

// 可以通过一个变量接受函数的返回值
var array = [12, 1, 99, 10, 20];
var max = getMax(array);
console.log(max);

// 返回值直接参与运算 
var num = 5;
var result = getMax(array) + num;
console.log(result);

// - 求阶乘   5 * 4 * 3 * 2 * 1
function getJieCheng(n) {
    var result = 1;
    for (var i = 1; i <= n; i++) {
        // result *= i;
        result = result * i;
    }
    return result;
}

var num = getJieCheng(5);
console.log(num);


// - 求1!+2!+3!+....+n!    n!
function getJieCheng(n) {
    var result = 1;
    for (var i = 1; i <= n; i++) {
        // result *= i;
        result = result * i;
    }
    return result;
}

function getSum(n) {
    // 求1-n之间每一个数的阶乘的累加
    var sum = 0;
    for (var i = 1; i <= n; i++) {
        // 累加的是每一个数的阶乘
        sum += getJieCheng(i);
    }
    return sum;
}

function getFactorial(num) {  
    var sum = 0; //保存阶乘的值
    for(var i = 1;i <= num;i++){
        var factorial = 1; //千万不要像求和定义为0,否则所有的阶乘结果都是0
        for(var j = 1;j <= i;j++){
            factorial *= j;
        }
        sum += factorial;
    }
    return sum;
}
// // 第一次循环  i = 1    sum = 0 + 1 
// // 第二次循环  i = 2    sum = 1! + 2!

// // 1! + 2! + 3! + 4! + 5!

1572861181047

需要注意的是,仅仅希望退出函数时 ,也可使用 return 语句。返回值是可选的:
function myFunction(a,b){
​ if (a>b){
​ return;
​ }
​ x=a+b
}
如果 a 大于 b,则上面的代码将退出函数,并不会计算 a 和 b 的总和。

返回值详解:

如果函数没有显示的使用 return语句 ,那么函数有默认的返回值:undefined
如果函数使用 return语句,那么跟再return后面的值,就成了函数的返回值
如果函数使用 return语句,但是return后面没有任何值,那么函数的返回值也是:undefined
函数使用return语句后,这个函数会在执行完 return 语句之后停止并立即退出,也就是说return后面的所有其他代码都不会再执行。

推荐的做法是要么让函数始终都返回一个值,要么永远都不要返回值。

1.2.4、函数是一种数据类型

function fn() {}
console.log(typeof fn);
  • 函数作为参数

因为函数也是一种类型,可以把函数作为另一个函数的参数,在另一个函数中调用

  • 函数做为返回值

因为函数是一种类型,所以可以把函数可以作为返回值从函数内部返回。

function fn(b) {
  var a = 10;
  return function () {
    alert(a+b);
  }
}
fn(15)();

1.3、JavaScript arguments对象

​ JavaScript中,arguments对象是比较特别的一个对象,实际上是当前函数的一个内置属性。也就是说所有函数都内置了一个arguments对象,arguments对象中存储了传递的所有的实参。arguments是一个伪数组,因此就可以进行遍历。

示例代码:

// 求任意个数的最大值
function getMax() {
    var max = arguments[0];
    for (var i = 1; i < arguments.length; i++) {
        if (max < arguments[i]) {
            max = arguments[i];
        }
    }
    return max;
}

var max = getMax(5, 10, 1, 5, 100);
console.log(max);


// 求任意个数的和
function getSum() {
    var sum = 0;
    for (var i = 0; i < arguments.length; i++) {
        sum += arguments[i];
    }
    return sum;
}

var sum = getSum(5, 1, 3, 4);
console.log(sum);

// 求斐波那契数列Fibonacci中的第n个数是多少?      1 1 2 3 5 8 13 21...
function getFib(n) {
    // 函数体
    var n1 = 1;
    var n2 = 1;
    var n3;
    for (var i = 3; i <= n; i++) {
        n3 = n1 + n2;
        n1 = n2;
        n2 = n3;
    }
    return n3;
}

var r = getFib(6);
console.log(r);

1.4、JavaScript函数作用域

变量从作用域的角度划分,分为两种:局部变量和全局变量。

什么是作用域?

​ 变量可以起作用的范围

1.4.1、局部变量

​ 在JavaScript函数内部声明的变量是局部变量,所以只能在函数内部访问它,该变量的作用域是局部的。

​ 可以在不同的函数中使用名称相同的局部变量,因为只有声明过该变量的函数才能识别出该变量。只要函数运行完毕,局部变量就会被删除。

function sayHello(){
	//该变量声明在一个函数内部,name就是一个局部变量,
	//局部变量只可以在本函数内调用
	var  name="H5";
	alert("Hello "+name);
}

1.4.2、全局变量

​ 在函数外声明的变量是全局变量,网页上的所有脚本和函数都能访问它。

//声明一个全局变量,任何函数都可以使用它
var  name="H5";
function sayHello(){
    alert("Hello "+name);
}
//调用函数
sayHello();

​ 需要注意的是,如果没有使用var声明变量,该变量将被自动作为全局变量声明,不推荐使用。

​ 比如这条语句:carname="Volvo";将声明一个全局变量 carname,即使它在函数内部声明。

1.4.3、变量的生命周期

​ JavaScript 变量的生命期从它们被声明的时间开始。

​ 局部变量会在退出作用域之后会销毁。

​ 全局变量会在关闭网页或浏览器才会销毁。

1.4.4、局部变量和全局变量的区别

1、声明位置不同

​ 局部变量声明在函数内部。全局变量声明在函数外部

2、作用域不一样

​ 局部变量只在某一个局部范围有效,比如函数内部。全局变量在整个页面有效,网页上的所有脚本和函数都能访问它。

3、生命周期不一样

​ 局部变量会在函数运行以后被删除,全局变量会在页面关闭后被删除

1.4.5、块级作用域

任何一对花括号({和})中的语句集都属于一个块,在这之中定义的所有变量在代码块外都是不可见的,我们称之为块级作用域。

在es5之前没有块级作用域的的概念,只有函数作用域,现阶段可以认为JavaScript没有块级作用域

1.4.6、作用域链

只有函数可以制造作用域结构, 那么只要是代码,就至少有一个作用域, 即全局作用域。凡是代码中有函数,那么这个函数就构成另一个作用域。如果函数中还有函数,那么在这个作用域中就又可以诞生一个作用域。

将这样的所有的作用域列出来,可以有一个结构: 函数内指向函数外的链式结构。就称作作用域链。

// 案例1:
function f1() {
    function f2() {
    }
}

var num = 456;
function f3() {
    function f4() {    
    }
}

// 案例2
function f1() {
    var num = 123;
    function f2() {
        console.log(num); 
    }
    f2();
}
var num = 456;
f1();

1.5、匿名函数

匿名函数,就是没有名字的函数。

一般的有名函数:

function  myFun( a,b ){
    console.info( a+b );
}
myFun( 10 , 30 );  // 输出40

匿名函数: 有关键词 function, 有小括号,有大括号,就是没有函数名。

function(a,b){
    console.info( a+b );
}

想要执行它,怎么执行?没有名字,怎么调用?

方式一:把它放进一个变量里,这个变量就相当于一个函数名了。没有名字的匿名函数,变成有“名”函数了,我们把这种方式称之为函数字面量

var  myFun = function( a,b ){
    console.info( a+b);
};

myFun( 10,30 );

方式二:干脆不要名字,直接执行~!-- 这么做可以在内部形成局部变量和局部函数,防止全局污染。

个人常用的直接执行匿名函数的方式!

(匿名函数)();

(匿名函数() );

//注意: 使用改写法一定要注意添加分号
(function(a,b){
	console.info( a+b );
})(10,30);

(function(a,b){
	console.info( a+b );
}(10,30));

其他直接调用的方式显得比较怪异了。

// 在function前面加一元操作符号  
!function () { /* code */ } ();  
~function () { /* code */ } ();  
-function () { /* code */ } ();  
+function () { /* code */ } ();

// 在function前面添加 new 关键词
new function () { /* code */ }  
new function () { /* code */ } () // 如果需要传递参数,只需要加上括弧()

方式三:利用事件去调用。

var  btn = document.getElementById("btn");  // 找到页面某个标签

// 添加事件
btn.onclick = function(){
	console.info("你点了我!");
}

方法四:作为对象的方法调用

var  myObj = {
	name : "John",
	sayHello:function(){
		console.info("Hello,"+ this.name );
	}
};

myObj.sayHello();

方法五:作为另一个函数的参数。

函数也可以作为另一个函数的参数的。当然有名函数也可以做参数。

function myFun(fn){
    fn();
}

myFun(function(){
    console.info("这个匿名函数是个参数");
});

1.6、构造函数

​ 通过 new 函数名 来实例化对象的函数叫构造函数。任何的函数都可以作为构造函数存在。之所以有构造函数与普通函数之分,主要从功能上进行区别的,构造函数的主要 功能为 初始化对象,特点是和new 一起使用。new就是在创建对象,从无到有,构造函数就是在为初始化的对象添加属性和方法构造函数定义时首字母大写(规范)。

​ 对new理解:new 申请内存, 创建对象,当调用new时,后台会隐式执行new Object()创建对象。所以,通过new创建的字符串、数字是引用类型,而是非值类型。

1、常用的构造函数:

1. var arr = [];     为      var arr = new Array();       的语法糖。
2. var obj = {}     为      var obj = new Object();     的语法糖
3. var date = new Date();
4. ...

2、自定义构造函数:

// 1. 构造函数名首字母要大写
// 2. 构造函数的作用就是用来创建对象的,
// 3. 功能上: 普通函数是用来执行某个行为;构造函数是用来创建对象的
// 4. 语法上: 基本没有差别
// 5. 从函数体: 普通函数的函数体里面就是要执行的逻辑代码; 构造函数的函数体里面是用来初始化对象成员以及对象方法的;
function Person(id,name,age) {
    //this关键字: 表示的当前对象
    this.id = id;   //对象的属性
    this.name = name;
    this.age = age;
    this.eat = function () {  //对象方法
        alert(this.name+"的吃饭行为");
    }
}

//直接通过函数名() 调用的是普通函数

//使用构造函数,必须结合new来使用
//Person()就算是构造函数,它也属于函数的一种
var p1 = new Person(1001,"张三",12); //创建一个Person对象

var p2 = new Person(1002,"李四",12);

document.write("p1的name是:"+p1.name+"<br>");

p1.eat();

1.7、回调函数

​ 我们先来看看回调的英文定义:A callback is a function that is passed as an argument to another function and is executed after its parent function has completed。

字面上的理解,回调函数就是一个参数,将这个函数作为参数传到另一个函数里面,当那个函数执行完之后,再执行传进去的这个函数。这个过程就叫做回调

​ 其实也很好理解对吧,回调,回调,就是回头调用的意思。主函数的事先干完,回头再调用传进来的那个函数。

​ 举一个别人举过的例子:约会结束后你送你女朋友回家,离别时,你肯定会说:“到家了给我发条信息,我很担心你。” 对不,然后你女朋友回家以后还真给你发了条信息。小伙子,你有戏了。其实这就是一个回调的过程。你留了个参数函数(要求女朋友给你发条信息)给你女朋友,然后你女朋友回家,回家的动作是主函数。她必须先回到家以后,主函数执行完了,再执行传进去的函数,然后你就收到一条信息了。

function modifyArray(arr, callback) {
 // 对 arr 做一些操作
 arr.push(100);
 // 执行传进来的 callback 函数
 callback();
}
var arr = [1, 2, 3, 4, 5];
modifyArray(arr, function() {
 console.log("array has been modified", arr);
});

​ 上面的代码中,我们先定义了主函数和回调函数,然后再去调用主函数,将回调函数传进去。

​ 定义主函数的时候,我们让代码先去执行callback()回调函数,但输出结果却是后输出回调函数的内容。这就说明了主函数不用等待回调函数执行完,可以接着执行自己的代码。所以一般回调函数都用在耗时操作上面。比如ajax请求,比如处理文件等。

1.8、预解析

JavaScript代码的执行是由浏览器中的JavaScript解析器来执行的。JavaScript解析器执行JavaScript代码的时候,分为两个过程:预解析过程和代码执行过程

1.8.1、执行环境

​ 执行环境定义了变量和函数有权访问的其他数据,决定了他们各自的行为。每个执行环境都有与之对应的变量对象(variable object),此对象保存着环境中定义的所有变量和函数。我们无法通过代码来访问变量对象,但是解析器在处理数据时会在后台使用到它。

全局执行环境:

​ 全局执行环境是最外围的一个执行环境,根据ECMAScript实现所在的宿主环境不同,表示执行环境的对象也不同。在web浏览器中,我们可以认为它是window对象,因此所有的全局变量和函数都是作为window对象的属性和方法创建的。代码载入浏览器时,全局环境被创建,应用程序退出,如关闭网页或者浏览器时,全局执行环境被销毁。

函数执行环境:

​ 每个函数都有自己的执行环境,当执行流进入一个函数时,函数的环境就被推入一个环境栈中,当函数执行完毕后,栈将其环境弹出,把控制权返回给之前的执行环境。

1.8.2、预解析过程

  1. 把变量的声明提升到当前作用域的最前面,只会提升声明,不会提升赋值。
  2. 把函数的声明提升到当前作用域的最前面,只会提升声明,不会提升调用。
  3. 先提升var,再提升function。

1.8.3、变量提升(hoisting)

ES5 提升有变量提升和函数提升。

原则:

​ 1、所有声明都会被提升到作用域的最顶上;

​ 2、同一个变量声明只进行一次,并且因此其他声明都会被忽略;

​ 3、函数声明的优先级优于变量申明,且函数声明会连带定义一起被提升。

变量提升:

​ 把变量声明提升到函数的顶部,但是变量赋值不会提升。

console.log(a);
var a = 10;
//输出为undefined

//与上例等价
var a;
console.log(a);
a = 10;

​ 注意:变量未声明,直接使用,输出‘变量 is not defined。

函数提升:

​ 函数提升会将函数声明连带定义一起提升。

​ 在JavaScript中函数的创建方式有三种:函数声明、函数表达式(函数字面量)、函数构造法(动态的,匿名的)。

​ 只有函数声明创建的函数会执行函数提升,字面量定义的函数(实质为变量+匿名函数)会执行变量提升。

test1();
function test1(){
    console.log("可以被提升");
}
test2();
var test2 = function(){
    console.log("不可以被提升");
}
console.log(test2);
var test2 = function(){
   console.log("不可以被提升");
}

函数和变量同时提升:

console.log(test3);
function test3(){console.log('func');}
var test3 = 'Mary';

1.9、防止全局污染

1.9.1、全局污染问题:

​ JavaScript 可以随意定义保存所有应用资源的全局变量。

​ 但全局变量可以削弱程序灵活性,增大了模块之间的耦合性。在多人协作时,如果定义过多的全局变量 有可能造成全局变量冲突,也就是全局变量污染问题。

1.9.2、解决全局污染

// 方式1: 定义全局变量命名空间,只创建一个全局变量,并定义该变量为当前应用容器,把其他全局变量追加在该命名空间下。

//my就是一个全局变量,我们可以把my这个全局变量当成一个命名空间,然后把其他的所有全局变量都放在它下面;
var my={};  //唯一的全局变量
my.name={
    big_name:"zhangsan",
    small_name:"lisi"
};
my.work={
    school_work:"study",
    family_work:"we are"
};

// alert(my.name.small_name);

// 方式2: 利用匿名函数将脚本包裹起来
(function(){
    var temp = {};
    //把两个变量赋值给temp
    //temp.school_work = "study";
    //temp.small_name = "李四";
    small_name = "李四";
    temp.getName = function(){
        return small_name;
    }

    //把tmep赋值给全局变量test
    window.test = temp;
}())
// alert(test.getName());

二、JavaScript对象

2.1、类和对象的概念

2.1.1、为什么要有对象

function printPerson(name, age, sex....) {
}
// 函数的参数如果特别多的话,可以使用对象简化
function printPerson(person) {
  console.log(person.name);
  ……
}

2.1.2、什么是对象

​ 所谓对象就是真实世界中的实体,对象与实体是一一对应的,也就是说现实世界中每一个实体都是一个对象,它是一种具体的存在,可以发现身边很多对象,汽车,狗,人等,这些对象都有一个属性和行为。

​ 比如一只狗,那么它的属性有名称、品种、颜色、体重;行为有吠叫、摇摆、跑等。

2.1.3、JavaScript中的对象

JavaScript语言没有“类”,而改用构造函数(constructor)作为对象的模板。前面说过,“对象”是单个实物的抽象。所以,通常需要一个模板,表示某一类实物的共同特征,然后“对象”根据这个模板生成。所谓“构造函数”,就是专门用来生成“对象”的函数。它提供模板,作为对象的基本结构。比如var date1=new Date()是通过调用Date的构造函数Date()(这里可以理解为一个类)来创建一个日期对象。一个构造函数,可以生成多个对象,这些对象都有相同的属性和行为,但是属性值可以不同。

​ 在 JavaScript 中,不会创建类,也不会通过类来创建对象(就像在其他面向对象的语言中那样),JavaScript 基于 prototype(原型),而不是基于类的。

​ 在Javascript没有类和接口,只有对象,而根据ECMAscript的定义,对象是“无序属性的集合,其属性包含基本值,对象或者函数”。

​ 需要注意的是,在ECMAscrip6.0中,已经使用class来定义类了。

​ 对象object是JavaScript的核心概念,也是最重要的数据类型。JavaScript的所有数据都可以被视为对象。对象是一个容器,封装了属性(propert)和方法(method)。所谓属性,就是对象的静态状态;所谓方法,就是对象的动态行为

​ JavaScript的对象是无序属性的集合。

​ 其属性可以包含基本值、对象或函数。对象就是一组没有顺序的值。我们可以把JavaScript中的对象想象成键值对,其中值可以是数据和函数。

​ 对象的行为和特征

​ 特征---属性:事物的特征在对象中用属性来表示。

​ 行为---方法:事物的行为在对象中用方法来表示。

在JavaScript中,其中一种定义对象的方法如下:

var o = {
    p: "Hello World",
    sayHello:function(){
        return p;
    }
};

​ 上面代码中,定义了一个对象o,这个对象内部包含2个键值对:p和sayHello,其中p键值对是描述静态属性的;sayHello键值对是描述对象的动态行为的。属性名与属性值之间用冒号分隔。

​ p是对象的属性名,字符串“Hello World”是对象的属性值。sayHello是对象的另一个属性名,属性值是function(){return p; }。

​ 如果对象内部包含多个属性对,每个属性对之间用逗号分隔。 需要注意的是,上面的代码后台隐式调用了new Object()这个构造函数创建了一个对象o,再通过键值对定义静态属性动态行为

​ 对象又分内置对象和自定义对象,其中内置对象是指JavaScript中已经定义好的,比如我们之后学的Date、Array、Math、String等,这些内置对象提供了许多方法和属性,只管调用和使用即可,比如Math对象中的PI和E是属性,pow(x,y)、sin(x)、sqrt(x)等方法。

​ 而在这一小节里,主要介绍自定义对象的使用。

2.2、对象的使用

2.2.1、对象的创建方式

  • 对象字面量
var hero = {
    name: '黄忠',
    weapon: '弓箭',
    equipment: ['头盔', '靴子', '盔甲'],
    blood: 100,
    attack: function () {
        console.log(this.name + ':射箭');
    },
    run: function () {
        console.log(this.name + ': 加速跑');
    }
}
console.log(hero.name);
console.log(hero.equipment);

hero.attack();
hero.run(); 
  • new Object()创建对象
// Object 是一个构造函数
// new 的方式来调用构造函数
// new Object() 调用构造函数   会在内存中创建一个对象
var hero = new Object(); // 创建了一个空的对象
// 打印一个不存在的属性 输出 undefined
// console.log(hero.name);
// 属性
// JavaScript的动态特性
hero.name = '关羽';
hero.weapon = '青龙偃月刀';
hero.equipment = ['头盔', '靴子', '赤兔马'];
hero.blood = 100;
// 方法
hero.attack = function () {
    console.log(this.name + ': 射箭');
}
hero.run = function () {
    console.log(this.name + ': 加速跑')
}
  • 工厂函数创建对象
function createHero(name, weapon, equipment, blood) {
    var hero = new Object(); //返回一个空的对象
    // 属性
    hero.name = name;
    hero.weapon = weapon;
    hero.equipment = equipment;
    hero.blood = blood;
    // 方法
    hero.attack = function () {
        console.log(this.name + ':攻击');
    }
    hero.run = function () {
        console.log(this.name + ':加速跑');
    }
    return hero;
}

var hero1 = createHero('黄忠', '弓箭', ['头盔', '靴子'], 100);
var hero2 = createHero('刘备', '剑', ['头盔', '盔甲'], 100);
  • 自定义构造函数
function Hero(name, weapon, equipment, blood) {
    // this 动态的给对象增加成员
    // this 指向了当前对象
    this.name = name;
    this.weapon = weapon;
    this.equipment = equipment;
    this.blood = blood;

    this.attack = function () {
        console.log(this.name + ':攻击');
    }
    this.run = function () {
        console.log(this.name + ': 加速跑');
    }
}

var hero1 = new Hero('黄忠', '弓箭', ['头盔', '靴子'], 100);
var hero2 = new Hero('刘备', '剑', ['头盔', '盔甲'], 100);

this代表的是当前对象

但是构造函数方有个缺点,就是对象的方法放在了构造函数内部,这样每创建一个方法就会需要多占用一些内存,所以js给构造函数设计了一个prototype属性,用来存放对象的方法:

function Student(name,age,id){
    this.name=name;
    this.age=age;
    this.id=id;
}
Student.prototype={
    work:function(skill){
        alert(this.name+"做"+skill+"开发相关的工作");
    },
    classId:"Java1班"
}
var stu1=new Student("李明",18,20151515);//得到的就是字面量对象
var stu2=new Student("王磊",18,20141000);//得到的就是字面量对象	

console.log(stu2.work==stu1.work);//ture,节省了内存空间
stu1.work("Java");
stu2.work("PHP");
console.log(stu1.classId);//20151515
console.log(stu2.classId);//20141000

2.2.2、属性和方法

​ 如果一个变量属于一个对象所有,那么该变量就可以称之为该对象的一个属性,属性一般是名词,用来描述事物的特征。
​ 如果一个函数属于一个对象所有,那么该函数就可以称之为该对象的一个方法,方法是动词,描述事物的行为和功能。

2.2.3、关键字详解

new关键字

构造函数 ,是一种特殊的函数。主要用来在创建对象时初始化对象, 即为对象成员变量赋初始值,总与new运算符一起使用在创建对象的语句中。

  1. 构造函数用于创建一类对象,首字母要大写。
  2. 构造函数要和new一起使用才有意义。
// Student 自定义构造函数
// 属性:name age sex score
// 方法:sayHi
function Student(name, age, sex, score) {
    // 属性
    this.name = name;
    this.age = age;
    this.sex = sex;
    this.score = score;
    // 方法
    this.sayHi = function () {
        console.log(this.name + ': hello');
    }
}

var stu1 = new Student('lilei', 18, '男', 100);
var stu2 = new Student('hanmeimei', 17, '女', 100);

new在执行时会做四件事情

new会在内存中创建一个新的空对象
new 会让this指向这个新的对象
执行构造函数  目的:给这个新对象加属性和方法
new会返回这个新对象

this详解

JavaScript中的this指向问题,有时候会让人难以捉摸,随着学习的深入,我们可以逐渐了解
现在我们需要掌握函数内部的this几个特点
	1. 函数在定义的时候this是不确定的,只有在调用的时候才可以确定
	2. 一般函数直接执行,内部this指向全局window
	3. 函数作为一个对象的方法,被该对象所调用,那么this指向的是该对象
	4. 构造函数中的this其实是一个隐式对象,类似一个初始化的模型,所有方法和属性都挂载到了这个隐式对象身上,后续通过new关键字来调用,从而实现实例化

2.2.4、对象的使用方法

对象属性的使用:

​ 1、可以用点符号访问对象属性值

​ 2、也可以通过数组的方式,即用["属性名称"]

对象方法的使用:

​ 可以使用对象名.方法名()来调用

遍历对象的属性

通过for..in语法可以遍历一个对象

var obj = {
    name: '张三',
    age: 18,
    sex: true,
    sayHi: function () {
        console.log(this.name);
    }
};
for(var key in obj) {
  console.log(key + "==" + obj[key]);
}

删除对象的属性

function fun() { 
  this.name = 'mm';
}
var obj = new fun(); 
console.log(obj.name); // mm 
delete obj.name;
console.log(obj.name); // undefined

简单类型和复杂类型的区别

基本类型又叫做值类型,复杂类型又叫做引用类型

值类型:简单数据类型,基本数据类型,在存储时,变量中存储的是值本身,因此叫做值类型。

​ Number String Boolean Null Undefined

引用类型:复杂数据类型,在存储是,变量中存储的仅仅是地址(引用),因此叫做引用数据类型。

​ Object Array

  • 堆和栈

    堆栈空间分配区别:
      1、栈(操作系统):由操作系统自动分配释放 ,存放函数的参数值,局部变量的值等。 
      2、堆(操作系统): 存储复杂类型(对象),一般由程序员分配释放, 若程序员不释放,由垃圾回收机制回收。
    
  • 注意:JavaScript中没有堆和栈的概念,此处我们用堆和栈来讲解,目的方便理解和方便以后的学习。

基本类型在内存中的存储

1498288494687

复杂类型在内存中的存储

1498700592589

基本类型作为函数的参数

1497497605587

复杂类型作为函数的参数

1497497865969

// 下面代码输出的结果?
// 构造函数
function Person(name,age,salary) {
  this.name = name;
  this.age = age;
  this.salary = salary;
}

// 普通函数
function f1(person) { // person为形参
  person.name = "lisi"; 
  person = new Person("aa",18,10); 
}

var p = new Person("zhangsan",18,1000);
console.log(p.name); // zhangsan
f1(p); // 把p对应的地址复制一份给person,person和p对应一个地址,那么修改地址对应的内容,会影响p
console.log(p.name); // lisi
//1. 
var num1 = 10;
var num2 = num1; // num2 = 10;
num1 = 20;
console.log(num1); // 20
console.log(num2); // 10

//2. 
var num = 50;
function f1(num) {
    num = 60;
    console.log(num);
}
f1(num); // 60
console.log(num); // 50

三、JavaScript内置对象

JavaScript中的对象分为3种:内置对象、自定义对象、浏览器对象

JavaScript 提供多个内置对象:Math/Array/Date....

对象只是带有属性方法的特殊数据类型。

学习一个内置对象的使用,只要学会其常用的成员的使用(通过查文档学习)

可以通过MDN/W3C来查询

内置对象的方法很多,我们只需要知道内置对象提供的常用方法,使用的时候查询文档。

Mozilla 开发者网络(MDN)提供有关开放网络技术(Open Web)的信息,包括 HTML、CSS 和万维网及 HTML5 应用的 API。

MDN:https://developer.mozilla.org/zh-CN/

如何学习一个方法?

  1. 方法的功能
  2. 参数的意义和类型
  3. 返回值意义和类型
  4. demo进行测试

3.1、Array对象

3.1.1、Array构造函数

// new关键字创建空数组
    var arr = new  Array();
// new关键字创建包含元素的数组
    var arr = new  Array(值1,值2.....值N);
// new关键字创建指定元素个数的数组
    var arr = new  Array(数值);
// 也可以使用[]直接创建数组
    var arr = [];
    var arr = [值1,值2.....值N];
// 可以使用length属性获取数组的长度;并且可以给一个数组长度赋值。

检测一个对象是否是数组

  • instanceof
  • Array.isArray() HTML5中提供的方法,有兼容性问题

函数的参数,如果要求是一个数组的话,可以用这种方式来进行判断;

sort排序底层源码(了解):

function sort(array, fnCompare) {
    // 外层循环 控制趟数
    for (var i = 0; i < array.length - 1; i++) {
        // 假设排好序了
        var isSort = true;
        // 内层循环 控制比较的次数
        for (var j = 0; j < array.length - 1 - i; j++) {

            if (fnCompare(array[j], array[j + 1]) > 0) {
                isSort = false;
                // 交换位置
                var tmp = array[j];
                array[j] = array[j + 1];
                array[j + 1] = tmp;
            }
        }
        // 判断是否排好了
        if (isSort) {
            break;
        }
    }
} 

var arr = [56, 10, 1, 17];


sort(arr, function (a, b) {
    return b - a;
})

console.log(arr);

3.1.2、Array对象方法

程序运行时通常需要读取数组中的数据,有时候需要对数据进行修改。

(一)读取数据:可以使用索引查询获取数组元素和添加数组元素

(二)添加数据:使用push()方法将新元素添加到数组尾部.

(三)删除数据:可以使用delete()运算符删除指定的元素。

(四)删除末尾元素(更新数据) : pop()方法,该方法会返回删除的元素。

(五)删除顶端的元素 : shift()方法

(六)在数组顶端添加元素 : unshift()方法,返回值为新数组的长度。

(七)字符转换:toString()方法将数组表示为字符串。

(八)join方法输出数组元素。(输出结果会转换成字符串)

(九)数组逆序reverse():颠倒数组元素的顺序;返回值为逆序后的新数组。

(十)数组排序 sort:

语法 数组名.sort(sortfunction)
sortfunction若省略,默认为从按照ASII字符顺序进行升序排列
sortfunction必须返回:正值、零、负值三者之一。正直表示第一个值大于第二个值,负值反之,零则相等。
var arr1 = [72,33,12,44,24];
arr1.sort(function(a,b){return a-b;});
alert(arr1);

var arr1 = [72,33,12,44,24];
arr1.sort(function(a,b){return b-a;});
alert(arr1);

(十一)扩充数组 concat:将多个数组的元素合并为一个新的数组。

(十二)splice方法:删除、替换、插入元素,会更改原数组
​ 第一参数为起始位置索引
​ 第二参数为切取元素个数
​ 第三个参数为插入元素,可选项

(十三)切取数组的一段元素 slice:
​ 切取部分作为新数组返回,不会对原数组改变。
​ 第一参数为起始位置索引(包含)
​ 第二参数为结束位置索引,注意区分splice(不包含)
​ 若省略第二个参数则直接切取到结尾

(十四)toString()/valueOf()

​ toString() 把数组转换成字符串,逗号分隔每一项

​ valueOf() 返回数组对象本身

将一个字符串数组输出为|分割的形式,比如“刘备|张飞|关羽”。使用两种方式实现

function myJoin(array, seperator) {
  if (array.length == 0){
    return '';
  }
  var str = array[0];
  for (var i = 1; i < array.length; i++) {
    str += seperator + array[i];
  }
  return str;
}
var array = [6, 3, 5, 6, 7, 8, 0];
console.log(myJoin(array, '-'));

console.log(array.join('-'))

将一个字符串数组的元素的顺序进行反转。使用两种种方式实现。

function myReverse(arr) {
  if (!arr || arr.length == 0) {
    return [];
  }
  for (var i = 0; i < arr.length / 2; i++) {
    var tmp = arr[i];
    arr[i] = arr[this.length - i - 1];
    arr[arr.length - i - 1] = tmp;
  }
  return arr;
}

var array = ['a', 'b', 'c'];
console.log(myReverse(array));

console.log(array.reverse());

3.2、Date对象

Date是JavaScript的内置对象,系统在Date对象中封装了与日期和时间相关的属性和方法。

Date使用UTC1970年1月1日0时开始经过的毫秒数来存储时间。

​ GMT 格林尼治时间

​ UTC 国际协调时间

注:January(Jan.)一月; February(Feb.)二月; March(Mar.)三月; April(Apr.)四月; May五月 June(六月; July(jul)七月; August(Aug.)八月; September(Sep.)九月; October(Oct.)十月; November(Nov.)十一月; December(Dec.)十二月

Monday 星期一 Tuesday 星期二 Wednesday 星期三 Thursday 星期四 Friday 星期五 Saturday 星期六 Sunday 星期日

3.2.1、Date构造函数

// 无参数的情况下返回值为当前时间。不同浏览器显示的时间格式会有细微差异
var date= new Date();

// 参数为毫秒值,距1970年1月1日(世界标准时间)起的毫秒数
var date = new Date(milliseconds);

// 参数为日期字符串
var date = new Date(dateString);

// 必选值:year, month, day;
var date = new Date(year, month, day, hours, minutes, seconds, milliseconds);

3.2.2、Date对象方法

通过使用针对日期对象的方法,我们可以很容易地对日期进行操作

getDate()			从 Date 对象返回一个月中的某一天 (1 ~ 31)。

getDay()			从 Date 对象返回一周中的某一天 (0 ~ 6)。

getFullYear()		从 Date 对象以四位数字返回年份。

getHours()			返回 Date 对象的小时 (0 ~ 23)。

getMilliseconds()   返回 Date 对象的毫秒(0 ~ 999)。

getMinutes()        返回 Date 对象的分钟 (0 ~ 59)。

getMonth()			从 Date 对象返回月份 (0 ~ 11)。

getSeconds()		返回 Date 对象的秒数 (0 ~ 59)。

getTime()			返回 1970 年 1 月 1 日至今的毫秒数。

setDate()			设置 Date 对象中月的某一天 (1 ~ 31)。

setFullYear()		设置 Date 对象中的年份(四位数字)。

setHours()			设置 Date 对象中的小时 (0 ~ 23)。

setMilliseconds()   设置 Date 对象中的毫秒 (0 ~ 999)。

setMinutes()		设置 Date 对象中的分钟 (0 ~ 59)。

setMonth()			设置 Date 对象中月份 (0 ~ 11)。

setSeconds()		设置 Date 对象中的秒钟 (0 ~ 59)。

setTime()			以毫秒设置 Date 对象。

Date对象相关的字符串表示方法:

toSting()			获取Date实例的字符串表示

toDateSting()		获取Date的日期部分字符串表示

toTimeSting()		获取Date的时间部分字符串表示

toLocaleString()    据本地时间格式,把 Date 对象转换为字符串。

toLocaleDateString()    根据本地时间格式,把 Date 对象的日期部分转换为字符串。

toLocaleTimeString()    根据本地时间格式,把 Date 对象的时间部分转换为字符串。

valueOf():			返回1970年1月1日午夜到指定日期的毫秒数

Date.now():			返回1970年1月1日午夜到指定日期的毫秒数(HTML5中提供的方法,有兼容性问题)

Date对象解析相关方法:

​ Date.parse()返回1970年1月1日午夜到指定日期(字符串)的毫秒数。

​ Date.parse()参数支持的时间格式如下:

​ ​ 1/24/2016;得到 Sun Jan 24 2016 10:10:10 GMT+0800

​ ​ 格式不正确会返回 无效的时间

写一个函数,格式化日期对象,返回yyyy-MM-dd HH:mm:ss的形式

function formatDate(d) {
  //如果date不是日期对象,返回
  if (!d instanceof Date) {
    return;
  }
  var year = d.getFullYear(),
      month = d.getMonth() + 1, 
      date = d.getDate(), 
      hour = d.getHours(), 
      minute = d.getMinutes(), 
      second = d.getSeconds();
  month = month < 10 ? '0' + month : month;
  date = date < 10 ? '0' + date : date;
  hour = hour < 10 ? '0' + hour : hour;
  minute = minute < 10 ? '0' + minute:minute;
  second = second < 10 ? '0' + second:second;
  return year + '-' + month + '-' + date + ' ' + hour + ':' + minute + ':' + second;
}

计算时间差,返回相差的天/时/分/秒

function getInterval(start, end) {
    var day, hour, minute, second, interval;
    interval = end - start;
    interval /= 1000;
    day = Math.round(interval / 60 / 60 / 24);
    hour = Math.round(interval / 60 / 60 % 24);
    minute = Math.round(interval / 60 % 60);
    second = Math.round(interval % 60);
    return {
        day: day,
        hour: hour,
        minute: minute,
        second: second
    }
}

console.log(getInterval(new Date("2019-12-31"),new Date("2020-5-2")))

3.3、String对象

​ 字符串是非常重要的数据类型,除了基本字符串外,JavaScript还提供了字符串的引用类型--字符串对象。

​ 字符串对象提供了字符串检索、替换、连接等方法...

字符串的不可变

var str = 'abc';
str = 'hello';
// 当重新给str赋值的时候,常量'abc'不会被修改,依然在内存中
// 重新给字符串赋值,会重新在内存中开辟空间,这个特点就是字符串的不可变
// 由于字符串的不可变,在大量拼接字符串的时候会有效率问题

3.3.1、String构造函数

​ 可以通过new 关键字创建字符串对象

var str=”hello”; // 字符串字面量

var str=new String(); // 字符串对象

​ 注:创建出来的类型虽说不同,但是对于内置的方法和属性都是可以使用的

​ length 属性返回字符串的长度(字符数)。

3.3.2、String对象方法

charAt(index)			返回在指定位置的字符。

charCodeAt()			返回在指定的位置的字符的 Unicode 编码。

concat([string1,string2...)  连接字符串。

slice(start,end)		提取字符串n到m之间的片断(不包括m位置的字符串),并在新的字符串中返回被提取的部分。

substring(star,end)		提取字符串中两个指定的索引号之间的字符。大多数情况和上一个作用相同,当参数为负值时会有不同,但这种情况较少用,不做讨论,有兴趣的话自己测试或查下资料

substr(start,length)     从起始索引号提取字符串中指定数目的字符。

split(separator,limit)   把字符串分割为字符串数组。

indexOf(subString[, startIndex]) 	检索字符串,返回某个指定的字符串值在字符串中首次出现的位置。注意,如果查找不到会返回 -1

lastIndexOf(subString[, startIndex]) 	返回指定字符串在字符串最后出现的位置。

toLowerCase()    	把字符串转换为小写。

toUpperCase()    	把字符串转换为大写。

match()  	找到一个或多个正则表达式的匹配。(正则表达式后续课程会讲),该方法会返回一个数组,数组中包含了所符合条件的文本。

replace(rgExp, replaceText)  	替换与正则表达式匹配的子串,并返回替换后的字符串,注意原字符串不会改变.

search(rgExp)		回与正则表达式查找内容匹配的第一个子字符串的位置。(与indexOf相似)

需要注意的是,JavaScript 的字符串是不可变的(immutable),String 类定义的方法都不能改变字符串的内容。像 String.toUpperCase() 这样的方法,返回的是全新的字符串,而不是修改原始字符串。

把字符串中所有的o替换成!

var s = 'abcoefoxyozzopp';
var index = -1;
do {
  index = s.indexOf('o', index + 1);
  if (index !== -1) {
    // 替换
    s = s.replace('o', '!');
  }
} while(index !== -1);
console.log(s);

3.4、Math对象

Math对象不是构造函数,它具有数学常数和函数的属性和方法,都是以静态成员的方式提供

跟数学相关的运算来找Math中的成员(求绝对值,取整)

Math

Math 对象并不像 Date 和 String 那样是对象的类,因此没有构造函数 Math()。

Math.PI				返回圆周率(约等于3.14159)。

Math.ceil(x)		返回大于等于其数字参数的最小整数。

Math.floor(x)		返回小于等于其数值参数的最大整数。

Math.round(x)		把数四舍五入为最接近的整数。

Math.random()		返回介于 0 和 1 之间的伪随机数。 注:产生的伪随机数介于 0 和 1 之间(含 0,不含 1),也就是,返回值可能为0,但总是小于1。

Math.max(x,y)		返回 x 和 y 中的最高值。

Math.min(x,y)		返回 x 和 y 中的最低值。

Math.abs(x)			返回x的绝对值		

代码示例:

// 求10-20之间的随机数
// 随机生成颜色RGB
// 模拟实现max()/min()

3.5、全局对象

1、parseInt

​ parseInt() 函数可解析一个字符串,并返回一个整数。

2、parseFloat方法

​ parseFloat()函数可解析一个字符串,并返回一个浮点数。

​ 该函数指定字符串中的首个字符是否是数字。如果是,则对字符串进行解析,直到到达数字的末端为止,然后以数字返回该数字,而不是作为字符串。

​ 如果参数字符串的第一个字符不能被解析成为数字,则 parseFloat 返回 NaN。

3、isNaN()方法

​ 定义和用法

​ isNaN(x):函数用于检查其参数是否是非数字值。 参数x是要检测的值

​ 如果x是特殊的非数字值NaN(或者能被转换为这样的值),返回的值就是 true。如果 x 是其他值,则返回 false。

​ isNaN()函数可用于判断其参数是否是NaN,该值表示一个非法的数字(比如被 0 除后得到的结果),如果把NaN与任何值(包括其自身)相比得到的结果均是false,所以要判断某个值是否是NaN,不能使用 == 或 === 运算符。正因为如此,isNaN() 函数是必需的。

​ 提示和注释
​ ​ 提示:isNaN()函数通常用于检测parseFloat()和parseInt()的结果,以判断它们表示的是否是合法的数字。当然也可以用isNaN()函数来检测算数错误,比如用0作除数的情况。

<script>
    var loginName = parseInt('amigo1121');
    if(isNaN(loginName)) {
        //如果loginName不是数值,执行如下语句
        alert("parseInt('amigo1121')的结果是: " + loginName);
    } else {
        alert("parseInt('amigo1121')的结果是数值!");
    }
</script>

URL编码和解码:https://www.jianshu.com/p/cfd3c8abb2c4

3.6、基本包装类型

为了方便操作简单数据类型,JavaScript还提供了三个特殊的简单类型类型:String/Number/Boolean

// 下面代码的问题?
// s1是基本类型,基本类型是没有方法的
var s1 = 'zhangsan';
var s2 = s1.substring(5);

// 当调用s1.substring(5)的时候,先把s1包装成String类型的临时对象,再调用substring方法,最后销毁临时对象, 相当于:
var s1 = new String('zhangsan');
var s2 = s1.substring(5);
s1 = null;
// 创建基本包装类型的对象
var num = 18;  				//数值,基本类型
var num = Number('18'); 	//类型转换
var num = new Number(18); 	//基本包装类型,对象
// Number和Boolean基本包装类型基本不用,使用的话可能会引起歧义。例如:
var b1 = new Boolean(false);
var b2 = b1 && true;		// 结果是什么

课后习题

part 1

1、在JavaScript中,定义一个函数所使用的关键字:(A)
    A、function  B、Function  C、fun D、method

2、变量从作用域的角度划分,分为两种(A B )。 
    A、全局变量  B、局部变量  C、整体变量  D、局域变量

3、在JavaScript函数中,声明一个变量没有用var,则该变量是(A)。
    A、全局变量  B、局部变量  C、整体变量  D、局域变量

4、下面(B)语句可以实现退出函数的功能。
    A、break   B、return  C、continue D、switch

5、下面代码的执行结果为(47, 34).
<script type="text/javascript">
    var max=34;
    function getMax(){
        var max=47;
        document.writeln(max);
    }
    getMax();
    document.write(max);
</script>

6、下面代码的执行结果为(47, 47).
<script type="text/javascript">
    var max=34;
    function getMax(){
        max=47;
        document.writeln(max);
    }
    getMax();
    document.write(max);
</script>

7、在调用函数时,给参数赋值的数据类型可以是(ABCD)
     A、string  B、number  C、object   D、boolean

8、编码实现如下业务逻辑:
    1、定义一个函数,函数包含三个参数begin,end,step,其中begin代表数列的初始值、end代表数列的结束值、step表示步长,即数列之间的增长量,比如sum=1+3+5+7+....+99,其中begin=1,end=99,step=2。

    2、函数的返回值是求该数列的和。

9、 下面代码的执行结果为:(B)
    function t(x,y){
        document.write(x*y);
    }
    t(23,12);
    A、语法错误  B、276   C、没有结果  D、23*12

part 2

1、JavaScript中数组元素的数据类型(AB)。
    A、可以相同 B、可以不相同   C、必须相同 D、必须不相同

2、JavaScript中数组的长度(A )。
    A、可变 B、不可变  C、一定变  D、一定不变

3、pop()方法和shift( )方法的区别是什么?

4、下面()方法可以添加数组元素到数组中。
    A、push()  B、splice()  C、pop()   D、sort()

5、下面()方法可以对数组进行排序。
    A、push()  B、splice()  C、pop()   D、sort()

6、slice()方法和splice()有什么不同?

7、( A)方法用于颠倒数组中元素的顺序。
    A、reverse()  B、sort()  C、join()  D、split()

8、( C)方法可以把数组转化为字符串。
    A、reverse()  B、sort()  C、join()  D、split()

part 3

1、把一个形如’6/13/2011’的字符串转化为日期,则使用Date对象的(B)方法。
    A、UTC()  B、parse()  C、setTime()  D、getTimezoneOffset()

2、把一个日期转化一个字符串,并且以特定地区格式显示月、日和年,则选用(C)方法。
    A、toDateString() B、toTimeString() C、toLocaleDateString() D、toLocaleTimeString()

3、下面()方法实现返回本地时间和UTC时间相差的分钟数。
    A、getMilliseconds() B、getMinutes()  C、getDate() D、getTimezoneOffset()

4、如果当前是星期二,则如下代码的值为()。
    var box = new Date();
    alert(box.getDay());
    A、0 B、1  C、2 D、3

5、如果当前是12月份,则如下代码的值为()。
    var box = new Date();
    alert(box.getMonth());
    A、10 B、11  C、12 D、13

6、在页面上编写代码实现显示时间。

7、在页面上编写代码实现显示年月日。

8、在页面上实现按如下格式显示内容:
       XXXX年XX月XX日 XX:XX:XX  星期X

part 4

练习1:
    获取系统当前时间,然后把日期转换为以下格式
    现在时间是:今天是:****年**月**日,现在时间是:上午/下午 HH:mm:ss

练习2:
    有以下身份证号:
        410105199009090001
    说明:前6位是身份和地区编号,7—14位为出生年月日,后4位为个人编号
    请使用字符串解析成以下格式:
    该用户的出生日期是:****年**月**日。

练习3:
	判断一个数是否是素数(又叫质数,只能被1和自身整数的数)

练习四:
    请根据弹出框输入的特定日期格式拆分日期

    如:请输入一个日期格式的字符串(格式如:月/日/年) 如: 11/24/2014
        经过处理得到:****年**月**日

练习五:
    根据输入的年份、产品类型和随机数产生固定资产编号
    即:固定资产编号=年份+0+产品类型+3位随机数
       程序运行流程:请输入年份:  
                  ……  如2014
                  请选择产品类型(1. 台式机 2. 笔记本 3. 其他):
                  ……  如3
                  生成3位随机数  如310
                  最后显示固定资产编号

    最后显示的结果应该是201403310
    var num = prompt("请输入一个数值:"); //从弹出框输入一个值
    提示:3位随机数按如下方法产生:[100,999]