15

11. 函数

11.1 函数的基础知识

为什么会有函数?

在写代码的时候,有一些常用的代码需要书写很多次,如果直接复制粘贴的话,会造成大量的代码冗余;

函数可以封装一段重复的javascript代码,它只需要声明一次,就可以多次调用;

冗余代码:

  • 冗余:多余的重复或啰嗦内容
  • 缺点:

    • 代码重复,可阅读性差
    • 不易维护,如果代码逻辑变了,所有地方的代码都要跟着改,效率太低了

11.2 函数的声明与调用

函数声明的语法:

var 是用来声明变量的, 函数是用function来声明的,一个函数一般是用来做一件事情的。
function 函数名 (){
    //函数体
}

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

调用函数的语法:

函数名();

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

示例代码:

// 声明函数
function sayHi (){
    // 函数体
    console.log("Hi!!");
}
// 调用这个函数
sayHi();  // console.log("Hi!!");

// 注意
console.log(sayHi);  // 打印的是整个函数 
// sayHi:指的就是这个函数
// ():指的是调用
// sayHi():这个函数的调用结果

12.3 声明函数的两种方式

1、函数声明(命名函数):

// 声明一个函数并且命名了
function 函数名(){
    函数体;
}
函数名();  // 调用函数

/********示例代码***********/
function fn(){
    console.log("哈哈哈");
}
fn();

2、函数表达式(匿名函数):

// 必须先声明才能调用
var 函数名 = function(){
    函数体;
}
函数名(); // 调用函数

/********示例代码***********/
var fn = function(){
    console.log("哈哈哈");
}
fn();

这两种函数的区别:

  • 命名函数可以先调用,再声明,因为预解析
  • 函数表达式必须先声明,再调用(在DOM中注册事件的时候用的非常的多)

匿名函数:

没有名字的函数,叫做匿名函数。匿名函数没有办法直接用,需要赋值给变量或者自调用

自调用函数也叫自执行函数,声明和调用一起

  • 可以防止变量全局污染
  • 匿名函数自调用示例代码:
(function(n1,n2){
    console.log(n1);        // 1
    console.log(n2);        // 2
    var name = "张三"
    var age = 18;
    function sayHello() {
      console.log(age);     // 18
      console.log(name);    // "张三"
    }
    sayHello();
})(1,2)

11.4 函数的参数

形式参数: 在声明一个函数的时候,为了函数的功能更加灵活,有些值是固定不了的,对于这些固定不了的值。我们可以给函数设置参数。这个参数没有具体的值,仅仅起到一个占位置的作用,我们通常称之为形式参数,也叫形参

实际参数: 如果函数在声明时,设置了行参,那么在函数调用的时候就需要传入对应的参数,我们把传入的参数叫做实际参数,也叫实参

语法:

//带参数的函数声明
function 函数名(形参1, 形参2, 形参...){
  //函数体
}

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

特点:

  • 在函数调用的时候,需要传递对应的参数,把实参的值赋值给形参。
  • 实参如果多于形参的个数:多传的参数就丢弃了
  • 实参如果少于形参的个数:没有传的参数,值就是undefined。(容易出问题)

示例代码:

// 设置两个形参
function getSum(num1,num2){
    console.log(num1+num2);
}
// 调用的时候传两个值进去
getSum(10,20);   // 打印出来就是 30

计算n1-n2之间所有数的乘积:

function getProduct(n1, n2) {
    var product = 1;
    for (var i = n1; i <= n2; i++) {
        product *= i;
    }
    console.log(product);
}
getProduct(1, 5);  // 120

11.5 函数的返回值

当函数执行完的时候,我们期望函数给我一些反馈(比如计算的结果),这个时候可以让函数返回一些东西。也就是返回值。函数通过return返回一个返回值

返回值语法:

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

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

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

示例代码:

// 计算 n1- n2之间所有数的乘积
function getProduct(n1, n2) {
    var product = 1;
    for (var i = n1; i <= n2; i++) {
        product *= i;
    }
    return product; // 返回计算的值
}
var pro = getProduct(1, 5); // 用变量pro接收一下返回的值
console.log(pro);   // 120

注意:

  • 函数一碰到return,就代表函数结束了。return后面的代码不会执行了。
  • 函数可以没有返回值, 会在最后面返回一个undefined

11.6 函数三要素

函数三要素包括:

  • 函数名
  • 参数
  • 返回值

11.7 文档注释

关于文档注释,javascript中还有一种注释叫做文档注释,经常用在函数声明处,用来解释这个函数的作用。

文档注释: /** 这是文档注释 */

以后写的函数的声明,都应该加上文档注释,方便阅读

示例代码:

/**
 * 求圆的面积
 * @param r {number} 圆的半径
 * @returns {number} 圆的面积
 */
function getArea (r) {
    return Math.PI * r * r;
}

11.8 函数综合练习

1、对任意数组从小到大排序

// 封装一个从小到大冒泡排序的函数
function bubbleSort(arr){
    for(var i = 0; i < arr.length - 1; i++){
        var flag = true;
        for(var j = 0; j < arr.length -1 -i; j++){
            if(arr[j] >arr[j+1]){
                flag =false;
                var temp = arr[j];
                arr[j] = arr[j+1];
                arr[j + 1] = temp;
            }
        }
        if(flag){
            break;
        }
    }
    return arr;
}
console.log(bubbleSort([12, 56, 14, 68, 45, 25, 17, 33]));
console.log(bubbleSort([25, 65, 48, 11, 15, 54, 24, 63]));

2、求任意数的阶乘(从1到n的积)

function getProduct (n){
    var product = 1; 
    for(var i = 1; i <= n; i++){
       product *= i; 
    }
    return product;
}
console.log(getProduct(5));  // 120
console.log(getProduct(3));  // 6   

3、求任意数组中的最大值与最小值

function getMaxAndMin(arr) {
    var max = arr[0];
    var min = arr[0];
    for (var i = 0; i < arr.length; i++) {
        if (max < arr[i]) {
            max = arr[i];
        }
        if (min > arr[i]) {
            min = arr[i];
        }
    }
    return [max, min]; // 返回一个数组
}
console.log(getMaxAndMin([11, 45, 59, 12, 8, 36, 14, 25]));  // [59 8]

11.9 函数的作用域

在函数中,只有全局作用域函数作用域,因为在ifwhilefor等语句中定义的变量都是全局变量。

全局变量:最外层声明的变量就是全局变量,全局变量在任何地方都能访问的到。

局部变量:函数中声明的变量,就是局部变量,局部变量只有在当前函数体内能够访问。

隐式全局变量: 没有使用var定义的变量也是全局变量。

作用域: 变量可以发挥作用的区域

全局作用域:script标签内,函数外定义的作用域就是全局作用域。在全局作用域中定义的变量都是全局变量。

函数作用域:函数中的区域叫做函数作用域,在函数作用域中定义的变量就是局部变量,只能在当前函数内访问。

11.10 预解析

js解析器执行js代码的时候,分为两个过程:预解析过程代码执行过程

预解析过程:

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

预解析例题:

第一题:

console.log(a);    // 打印a这个函数整体
var a = 1;
function a(){
console.log("呵呵");
}
console.log(a);    // 1

// 预解析后为
/**
var a;
function a(){
    console.log("呵呵");
}
console.log(a);    // 打印a这个函数整体
a = 1;
console.log(a);    // 1
*/

第二题:

var num = 10;
fn1();
function fn1() {
    //在函数调用的时候,这个函数也会做预解析操作。
    console.log(num);   // undefined
    var num = 20;
    console.log(num);   // 20
}
console.log(num);       // 10


// 预解析后为
/**
var num ;
function fn1() {
    var num;
    console.log(num);   // undefined
    num = 20;
    console.log(num);   // 20
}
num = 10;
fn1();
console.log(num);       // 10
*/

第三题:

var a = 18;
var b = 30;
fn();
function fn() {
    var b = 9;
    console.log(a); // undefined
    console.log(b); // 9
    var a = 20;
}


// 预解析后为
/**
var a;
var b;
function fn() {
    var b;
    b = 9;
    var a;
    console.log(a);     // 自己作用域里有的就不要出去找
    console.log(b);     // 9
    a = 20;
}
a = 18;
b = 30;
fn();
*/

第四题:

fn();
var b = 10;
console.log(c); // 9
console.log(b); // 10
console.log(a); // 报错

function fn() {
    var a = 9;
    b = 9;
    c = 9;
    console.log(a); // 9
    console.log(b); // 9 
    console.log(c); // 9
}


// 预解析之后
/**
var b;
function fn() {
    var a;
    a = 9;
    b = 9;
    c = 9;
    console.log(a); // 9
    console.log(b); // 9
    console.log(c); // 9
}
fn();
b = 10;
console.log(c); // 9
console.log(b); // 10
console.log(a); // 报错
*/

第五题:

function fn() { 
    console.log(num1);  // undefined
    console.log(num2);  // undefined
    console.log(num3);  // 30
    var num1 = 10;
    var num2 = 20;
    num3 = 40;
    console.log(num1);  // 10
    console.log(num2);  // 20
    console.log(num3);  // 40
}
var num1 = 20;
var num3 = 30;
fn();
console.log(num1);      // 20
console.log(num3);      // 40
console.log(num2);      // 报错


// 预解析之后
/**
var num1;
var num3;

function fn() {
    var num1;
    var num2;
    console.log(num1); // undefined
    console.log(num2); // undefined
    console.log(num3); // 30
    num1 = 10;
    num2 = 20;
    num3 = 40;
    console.log(num1); // 10
    console.log(num2); // 20
    console.log(num3); // 40
}
num1 = 20;
num3 = 30;
fn();
console.log(num1); // 20
console.log(num3); // 40
console.log(num2); // 报错
*/

11.11 递归函数

函数直接或者间接调用自己,必须要留出口,不然就调死了

示例代码:

// 用递归求1-100的和
/* 
    之前封装过一个getSum的函数比如getSum(100),就是求的1-100的和
    现在我们可以这样理解:
    1-100的和我们可以看做是 100 + getSum(99)
    getSum(99) 可以看成 99 + getSum(98)。。。
    依次这样推下去,但是要注意,到getSum(1)的时候,要留出口,否则会一直死循环下去
 */
function getSum(n) {
    if (n == 1) {       // 一定要留出口
        return 1;
    }
    return n + getSum(n - 1);
}
console.log(getSum(100));

11.12 回调函数

回调函数:把函数当成参数来使用,那么这个函数就叫回调函数。函数也是一种数据类型

示例代码:

/*
思考,之前封装了一个bubbleSort排序的函数,但是只能排元素是数字的数组
现在想要判断字符串的长度,或者对象的属性的时候就很麻烦,就需要重新写一个函数
比如字符串长度,就需要是arr[j].length - arr[i+1].length
*/
function bubbleSort(arr, fn) {
    for (var i = 0; i < arr.length; i++) {
        var flag = true;
        for (var j = 0; j < arr.length - 1 - i; j++) {
        
            // 传一个函数进来,并且将arr[j], arr[j + 1]作为两个参数传进去
            if (fn(arr[j], arr[j + 1]) > 0) {
                flag = false;
                var temp = arr[j];
                arr[j] = arr[j + 1];
                arr[j + 1] = temp;
            }
        }
        if (flag) {
            break;
        }
    }
}
// 纯数字数组
var arr = [4, 3, 1, 6, 22, 21, 41, 4];
// 调用的时候,我们需要将fn函数的两个参数也传进去
// 这种把一个函数作为参数传进另一个函数的方式就叫回调函数
bubbleSort(arr, function(a, b) { // a b 就相当于 arr[j] 和 arr[j+1]
    return a - b;
    // 如果是 return b - a 就相当于,上面的 arr[j+1] - arr[j]>0 那么就是从大到小排序 
});
console.log(arr);

// 封装后的排序函数也可以直接根据字符串的长度进行排序了
var arrStr = ["aaa", "bb", "cccc", "d"];
bubbleSort(arrStr, function(a, b) {
    // 因为传进去的是一个函数,arr[j] 和 arr[j+1]是以两个参数的形式传进去的
    // 当数组元素是字符串的时候,就可以进行.length操作了
    return a.length - b.length;
});
console.log(arrStr);

12. 对象

12.1 对象的基本概念

无序的键值对集合

为什么要有对象?

javascript中:对象跟数组、函数一样,都是一种复杂数据类型,是一系列相关的属性的集合,可以很方便对变量和函数进行管理。

什么是对象?

现实生活中: 万物皆对象,对象是一个具体的事物,一个具体的事物就会有行为特征

javascript: javascript中的对象其实就是生活中对象的一个抽象

  • 事物的特征在对象中用属性来表示。
  • 事物的行为在对象中用方法来表示。
  • 对象中的方法,其实就是对象里面的函数。

举个例子:

特征:名字、性别、年龄、身高、体重、爱好、星座、血型    (属性)
行为:罚钱、吃肉、打招呼                             (方法: 对象里面的函数)

12.2 创建对象

12.2.1 通过构造函数创建

通过var 对象名 = new Object();的方式创建一个对象,通过对象名.的语法,给这个对象添加属性;通过通对象名.方法名 = function(){} 给这个对象加上一个方法

示例代码:

// 创建一个英雄对象,并且给他加上属性和方法
var hero = new Object(); // 创建一个空的英雄对象

// 通过"."语法给这个hero加上一些属性
hero.name = "盖伦";         // 给对象添加了一个name的属性
hero.skill = "正义审判";    // 给对象添加一个技能属性

// 通过 对象名.方法名 = function(){} 给hero加上一个方法
hero.attack = function() {
  console.log("盖伦攻击了小怪物");
}
attack();

12.2.2 通过对象字面量

通过var 对象名 = {}的方式创建一个对象,通过键值对的方式,给这个对象加上属性和方法。

字面量:11 "abc" true [] {}{}就相当于 new Object();

示例代码:

// 创建一个英雄对象,并且给他加上属性和方法
var hero = {
    name  : "盖伦",          // 键值对的形式给hero加上属性
    skill : "正义审判",
    
    attcck : function(){    // 键值对的形式给hero加上方法
        console.log("盖伦攻击了小怪物");
    }
}

注意: 键值对之间用,号隔开

12.2.3 关于 this

示例代码:

var hero = {
    name  : "盖伦", 
    skill : "正义审判",
    
    attcck : function(){    
        // 这里的this指向的是当前的对象,表示当前对象下的skill属性,如果直接写skill 是报错的
        console.log("盖伦使用了"+this.skill+"攻击了敌人");
    }
}

注意:

  • this一定要出现在方法中才有意义,不在方法中的this没有意义。
  • 在方法中出现的this,指的是当前对象,即调用这个方法的对象

12.3 操作对象的属性

操作对象的属性分为存值取值

12.3.1 "." 语法

存值:

对象名.属性名 = "值";

存值-示例代码:

var obj = {
    age:18,
    name:"盖伦"
};

// 存值
obj.hobby = "K人";
obj.age = 20;
console.log(obj); // {age:20,name:"盖伦",hobby:"K人"}

存值-注意:

  • 如果对象原来就这个属性,会覆盖原来的值。
  • 如果对象没有这个属性,就会新增加这个属性。(属性在对象中是独一无二的)

取值:

对象名.属性名

取值-示例代码:

var obj = {
    age:18,
    name:"盖伦"
};

// 取值
console.log(obj.age);  // 18
console.log(obj.name); // "盖伦"

取值-注意:

  • 如果对象这个属性,就会返回对应的值
  • 如果对象没有这个属性,就会返回undefined

12.3.2 "[]"语法

关联数组的语法,把对象当成数组来看待

存值:

对象名[属性名(下标)] = "值"; 数组的下标是数字,对象的下标是字符串

存值-示例代码:

var obj = {
    age:18,
    name:"盖伦"
};

// 存值
obj["hobby"] = "K人";
obj["age"] = 20;
console.log(obj); // {age:20,name:"盖伦",hobby:"K人"}

取值:

对象名[属性名(下标)]

取值-示例代码:

var obj = {
    age:18,
    name:"盖伦"
};

// 取值
console.log(obj["age"]);  // 18
console.log(obj["name"]]); // "盖伦"

注意: []语法是将对象当数组看,数组的下标是数字,对象的下标是字符串,取值的时候一定要注意

12.3.3 两种方法的区别

当属性名是一个字符串存储在变量中的时候,只能使用关联数组的方式。

示例代码:

var obj = {
    age:18,
    name:"盖伦"
};
var temp = "age";
console.log(obj[temp]); // 打印 18 ==> obj["age"]
console.log(obj.temp);  //  点语法就不行,undefined 点语法会去对象中找temp的属性

大部分情况,都用.语法,比较简单,如果属性的名字存在一个变量中,只能用[]语法

12.4 遍历对象

通过for..in语法可以遍历一个对象:for(var in 对象)

示例代码:

var hero = {
    name : "盖伦",
    skill: "正义审判",

    attcck: function() {
        console.log("盖伦使用了" + this.skill + "攻击了敌人");
    }
}

for(var key in hero){      // key表示的是对象的属性名
    console.log(key);      // 遍历了所有的属性名
    console.log(hero[key]); // 遍历所有的值
    
    console.log(hero.key);  // undefined 这样写是错的,找的是hero的key属性
}

遍历对象案例:

var datas = [
    {name:"露娜", age:18, score:100, gender:"男"},
    {name:"妲己", age:1000, score:101, gender:"女"},
    {name:"甄姬", age:888, score:102, gender:"女"},
    {name:"大乔", age:21, score:103, gender:"女"},
    {name:"小乔", age:22, score:104, gender:"女"}
];

document.write("<table>");
for (var i = 0; i < datas.length; i++) {
    document.write("<tr>");
    var data = datas[i];
    for (var key in data) {
        document.write("<td>");
        document.write(data[key]);
        document.write("</td>");
    }
    document.write("</tr>");
}
document.write("</table>");

效果图:

效果

注意:遍历的时候for后面是键(属性名),in后面是对象

判断一个对象中是否有某一属性:

in关键字可以查看对象是否拥有某个属性。
var obj = {
    name:"zs",
    age:18,
    score:100
}
//in关键字可以查看对象是否拥有某个属性。
console.log( "sex" in obj );  // false
console.log( "name" in obj ); // true

12.5 查看对象的类型

1、typeof 查看对象类型

所有的复杂类型,使用typeof关键字的话,都是object

示例代码:

var arr = new Array();
console.log(typeof arr);     // Object

var obj = new Object();
console.log(typeof obj);     // Object

var student = new Object();
console.log(typeof student); // Object

function fn(){
    
}
console.log(typeof student); // Function

注意:

  • typeof只能区分出来是复杂类型,并不能区分出具体类型
  • 函数比较特殊,在js里面的地位比较高,typeof可以查看到它的类型

2、instanceof 查看对象类型

instance: 实例 这种方法也不能直接获得对象的具体类型

示例代码:

var arr = new Array();
console.log(arr instanceof Array);   // true 说明arr的实例是Array

这种方法还是比较麻烦,看下面这种方法

3、.constructor.name 查看对象类型

借助于js原型里的constructor关键字,可以直接获取到对象的具体类型

示例代码:

var arr = new Array();
console.log(arr.constructor.name);   // Array

var obj = new Object();
console.log(obj.constructor.name);   // Object

12.6 批量创建对象

1、使用普通函数批量创建对象

将创建对象封装在一个函数里,需要批量创建对象的时候,只需调用这个函数即可

示例代码:

// 封装
function createObj(name,age,gender){
    var heros = new Object();
    student.name = name;
    student.age  = age;
    student.gender = gender;
    student.sayHello = function () {
        console.log("大家好,我是"+this.name);
    }
    return heros;
}

// 调用
var stu1 = createObj("露娜",15,"女");
console.log(stu1);  // 打印这个对象
stu1.sayHello();    // "大家好我是露娜"


var stu2 = createObj("小乔",800,"女");
console.log(stu2);  // 打印这个对象
stu2.sayHello();    // "大家好我是小乔"

优点:可以同时创建多个对象
缺点:创建出来的没有具体的类型,都是object类型的

2、构造函数批量创建对象

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

一般创建一个对象的时候直接new object出来的没有具体的类型,都是object类型的,要想分类的更清楚就需要用到构造函数创建对象

首字母需要大写,通常是名词,表示一类对象。

语法:

// 首字母需要大写,通常是名词,表示一类对象。
function Teacher(){
    // 函数体
}
var cjk = new Teacher();            // 如果没有new, cjk就是一个普通的函数
console.log(cjk.constructor.name);  // 输出的对象类型为 Teacher

示例代码:

// 构造函数 this指向new出来的新对象
function Teacher(name, age){
    this.name = name;
    this.age = age;
    this.sayHello = function () {
        console.log("大家好,我是"+this.name+",今天晚上我给大家唱首歌");
    }
}

// new 创建了一个空对象 类型为Teacher
var cjk = new Teacher("苍井空", 18);
console.log(cjk);   // 对象的类型为Teacher {name:"苍井空",age:18}

var bdyjy = new Teacher("波多野结衣", 19);
console.log(bdyjy); //  对象的类型为Teacher {name:"波多野结衣",age:19,sayHello:function(){}}
bdyjy.sayHello();   //  大家好,我是波多野结衣,今天晚上我给大家唱首歌

new做了四件事情:

  • new 会创建一个空的对象,并且对象的类型是new 后面跟的名字;
  • 让函数内部的this指向这个空对象,操作this就相当于操作了这个对象;
  • 执行构造函数
  • 返回这个对象

优点:

  • 创建出来的对象,类型是可变的
  • 写法更加简洁

案例-批量创建一个英雄对象:

//属性:名字、性别、技能、口号、等级、金钱
//行为:打怪兽

function Hero(name, gender, skill, slogan, level, money){
//给this加属性和方法
    this.name = name;
    this.gender =gender;
    this.skill = skill;
    this.slogan = slogan;
    this.level = level;
    this.money = money;
    
    this.attack = function (n) {
      console.log(this.name + "使用了" + this.skill + "攻击了" + n);
    }
}

var atm = new Hero("奥特曼", "不详", "激光", "呵呵", 100, 0);
console.log(atm);      // 返回了一个Hero类型的对象
atm.attack("小怪兽");  // 奥特曼使用了激光攻击了小怪兽

var dm = new Hero("盖伦", "男", "大宝剑", "人在塔在", 18, 3150);
console.log(dm);       // 返回了一个Hero类型的对象
dm.attack("防御塔");   // 盖伦使用了大宝剑攻击了防御塔

12.7 值类型与引用类型

1、值类型(简单数据类型)

值类型 : 又叫简单数据类型,例如:numberstringbooleanundefinednull

变量储存数据的时候,存储的直接就是这个值本身

示例代码:

var num = 12;
var num1 = num;
num1 = 20;
console.log(num);   // 12
console.log(num1);  // 20

2、引用类型(复杂数据类型)

引用类型 :又叫复杂数据类型,例如:ObjectFunctionArray自定义类型

变量在储存数据的时候,不会直接存储这对象,存储的是这个对象的地址

示例代码:

var obj = {             // 在内存中存储了一个地址
    name: "凹凸曼",
    age: 100
}
    
var obj1 = obj;     // 把这个地址赋值给了obj1,obj1就有了obj的所有属性
obj1.name = "奥特曼";   // 因为obj1 和 obj 用的是同一个地址,所以当obj1的属性值改变的时候,obj也会改变
console.log(obj.name);  // "奥特曼"
console.log(obj1.name); // "奥特曼"    

引用类型详解:

//复杂类型变量不会存这个对象,只会存这个对象的地址。
var hero = {
    name: "大黄蜂",
    age: 100,
    car: {
        name: "科迈罗",
        price: 400000
    },
    brothers: ["擎天柱", "铁皮", "救护车"]
};

console.log(hero.car.name);     // "科迈罗"
console.log(hero.brothers[0]);  // "擎天柱"

image

面试题(一):

var num1 = 55;
var num2 = 66;
function f1(num, num1) {
    num = 100;
    num1 = 100;
    num2 = 100;
    console.log(num);   //100
    console.log(num1);  //100
    console.log(num2);  //100
}

f1(num1, num2);
console.log(num1);      //55
console.log(num2);      //100
console.log(num);       //报错

面试题(二):

function Person(name, age) {
    this.name = name;
    this.age = age;
}
var p1 = new Person("zs", 18);
var p2 = p1;

p2 = new Person("ls", 20);

p2.name = "ww";

console.log(p1.name); // zs
console.log(p2.name); // ww

image

3、栈内存与堆内存

栈内存: 空间比较小,但运算速度非常的快

堆内存:空间非常大,但运算速度相对而言比较慢

12.8 基本包装类型

简单类型有没有属性和方法?JS为了我们操作方便,内置了对应的复杂类型(StringNumberBoolean)

我们使用简单类型的时候,可以直接使用复杂类型的属性和方法。(js会自动帮我们把简单类型转换成复杂类型。用完之后,又自动的给我们转成了简单类型)

简单类型: number string boolean undefined null

复杂类型: Object Function Array String Number Boolean

基本包装类型:

  • 对于string number boolean基本类型来说,可以直接使用属性和方法。
  • 自动把简单类型转换成对应的复杂类型
  • 调用复杂类型的属性或者方法得到结果
  • 自动的把复杂类型转换成简单类型

12.9 伪数组(类数组)

不是数组,是对象, 叫伪数组(可以跟数组一样的使用下标,也可以遍历)
var obj = {
    0:"呵呵",
    1:"哈哈",
    2:"嘻嘻",
    3:"嘿嘿嘿",
    4:"呜呜",
    length:5
}

for(var k in obj){
    console.log(obj[k]);
}

12.10 arguments 对象

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

示例代码:

// Math.max 的原理是什么?
// 不知道形参个数的时候,怎么判别一个最大值或者最小值呢?
// arguments对象中 存储的是所有的实参 是以一个伪数组的形式存在的
function max(){
    var m = arguments[0];
    // 所以不管你传多少参数进来,arguments就储存多少参数
    for(var i = 0; i < arguments.length; i++) {
        if(m < arguments[i]){
            m = arguments[i];
        }
    }
    return m;
  }
}
console.log(max(1, 2, -1));     // 2
console.log(max(1, 2, 4, 10));  // 10

12.11 JSON 对象

JSON(JavaScript Object Notation)是一种轻量级的数据交换格式,采用完全独立于语言的文本格式,是理想的数据交换格式。同时,JSONJavaScript原生格式,这意味着在JavaScript中处理JSON数据跟处理对象是一样的。

JSON的属性必须用双引号引起来,对象字面量可以省略

示例代码:

// js里面,属性名可以用双引号引起来,也可以不引起来。
var obj = {
    name:"张三",
    age:18
}

// JSON属性名必须用双引号引起来
var json = {
    "name":"张三",
    "age":18
 }


//json是js对象    js对象不一定是json
console.log(json.name);     // "张三"
console.log(json["name"]);  // "张三"

json对象的两个方法:

  • 对象转换为JSON格式使用:JSON.stringify
  • JSON装换为对象格式:JSONparse()

13. 内置对象

JS内置对象就是指Javascript自带的一些对象,供开发者使用,这些对象提供了一些常用的的功能。

常见的内置对象有MathStringArrayDate

13.1 Math 对象

Math对象中封装很多与数学相关的属性和方法。Math对象比较特殊,不需要new

1、属性 PI

Math.PI 表示的就是圆周率,通常计算圆的周长或者面积的时候会用到。也可以用作表示角度、弧度(π= 180°)
console.log(Math.PI);  // 3.141592653589793

2、最大值/最小值

Math.max(x,y) 表示求出两者之间的最大值
console.log(Math.max(10,99)); // 返回99
Math.min(x,y) 表示求出两者之间的最小值
console.log(Math.min(10,99)); // 返回10

3、取整

Math.ceil() 天花板函数(向上取整)
  • 整数向上取整还是整数
  • 正小数向上取整,整数部分加1,小数部分舍去
  • 负小数向上取整,整数部分不变,小数部分舍去

示例代码:

console.log(Math.ceil(2));    // 2
console.log(Math.ceil(1.2));  // 2
console.log(Math.ceil(1.8));  // 2
console.log(Math.ceil(-1.2)); // -1
console.log(Math.ceil(-1.8)); // -1
Math.floor() 地板函数(向下取整)
  • 整数向下取整还是整数
  • 正小数向下取整,整数部分不变,小数部分舍去
  • 负小数向下取整,整数部分减1,小数部分舍去

示例代码:

console.log(Math.floor(2));    // 2
console.log(Math.floor(1.2));  // 1
console.log(Math.floor(1.8));  // 1
console.log(Math.floor(-1.2)); // -2
console.log(Math.floor(-1.8)); // -2
Math.round() 四舍五入(如果是.5,则取更大的那个数)
  • 正小数四舍五入,对小数点后面一位数进行判断,大于等于5整数部分加1,小数舍去;小于5,整数部分不变,小数部分舍去
  • 负小数四舍五入,对小数点后面一位进数行判断:

    • 小于5的时候,小数舍去,整数部分不变
    • 大于5的时候,小数舍去,整数部分减 1
    • 等于5的时候要再判断,如果后面没有数了,小数舍去,整数部分不变;如果后面还有数,小数舍去,整数部分减 1

示例代码:

console.log(Math.round(1.2));    // 1
console.log(Math.round(1.5));    // 2
console.log(Math.round(1.56));   // 2
console.log(Math.round(1.6));    // 2

console.log(Math.round(-0.3));   // 0
console.log(Math.round(-0.6));   // -1
console.log(Math.round(-1.5));   // -1
console.log(Math.round(-1.6));   // -2
console.log(Math.round(-1.56));  // -2

4、随机数

Math.random() 返回一个[0,1)之间的数,能取到0,取不到1

示例代码:

// 获得0-5的随机数,包括0-5
// parseInt:取整
console.log(parseInt(Math.random() * 6)); // 因为随机数 能取到0,取不到1,要想返回5 就需要乘以6 


// 获得3-5之间的随机数
// 3-5?可以先取到随机数0-2,然后再加3 获得的就是3-5
console.log(parseInt(Math.random() * 3) + 3);  

5、绝对值

Math.abs() 对一个数进行绝对值操作,纯数字字符串也可以转换

示例代码:

console.log(Math.abs(-11));   // 11
console.log(Math.abs(11));    // 11
console.log(Math.abs("-11")); // 11
console.log(Math.abs("aaa")); // NaN

6、次幂和开平方

Math.pow(num, power) 求 num 的 power 的次方

示例代码:

console.log(Math.pow(2,4));   // 2的4次方 16
Math.sqrt(num) 为 num 开平方根

示例代码:

console.log(Math.sqrt(9));   // 为9开平方根  3

13.2 Date对象

Data 对象是用来处理日期和时间的

13.2.1 创建一个日期对象

使用构造函数创建一个当前时间对象 var date = new Date();
var date = new Date();
console.log(date); // Fri Nov 17 2017 11:59:19 GMT+0800 (中国标准时间)
创建一个指定时间的日期对象 var date = new Date(指定时间);
var date = new Date("2017-03-22");          //创建一个指定时间的日期对象 Wed Mar 22 2017 08:00:00 GMT+0800 (中国标准时间)
var date = new Date("2017-03-22 00:52:34"); //创建一个指定时间的日期对象 Wed Mar 22 2017 00:52:34 GMT+0800 (中国标准时间)

13.2.2 日期格式化

日期格式化,一般用到的不多,通过格式化可以获得当前日期的日期部分或者时间部分
var date = new Date();
date.toString();            // 默认的日期格式
date.toLocalString();       // 本地风格的日期格式(存在兼容性)
date.toDateString();        // 获得当前日期时间的,日期部分 Fri Nov 17 2017
date.toLocalDateString();   // 本地风格的日期部分(存在兼容性)
date.toTimeString();        // 获得当前日期时间的,时间部分 13:23:42 GMT+0800 (中国标准时间)
date.toLocalTimeString();   // 本地风格的时间部分(存在兼容性)

13.2.3 获取日期的指定部分

  • getMilliseconds(); 获取毫秒值
  • getSeconds(); 获取秒
  • getMinutes(); 获取分钟
  • getHours(); 获取小时
  • getDay(); 获取星期,0-6 0:星期天
  • getDate(); 获取日,即当月的第几天
  • getMonth(); 返回月份,注意从0开始计算,这个地方坑爹,0-11
  • getFullYear(); 返回4位的年份 如 2016

示例代码:封装一个格式 xxxx-xx-xx xx:xx:xx 的日期函数

var date = new Date();
var year = date.getFullYear();     // 获取当前时间的年份

var month = date.getMonth() + 1;   // 获取当前时间的月份,注意月份是从0开始的0-11,所以加1
addZore(month);                    // 获得的月份有可能是一位数,此时需要给他再拼接一位

var d = date.getDate();            // 获得当前时间的日期天数
addZore(d);

var h = date.getHours();           // 获取当前时间的小时
addZore(h);

var m = date.getMinutes();         // 获取当前时间的分钟
addZore(m);

var s = date.getSeconds();         // 获取当前时间的秒
addZore(s);

function addZore(n) {
    return n > 10 ? n : "0" + n;   // 判断获取到的数字大于10的时候 返回本身,小于的时候需要拼串
}

var dateStr = year + "-" + month + "-" + d + " " + h + ":" + m + ":" + s;
console.log(dateStr); // 2017-11-17 13:58:53

13.2.4 时间戳

1970年01月01日00时00分00秒起至现在的总毫秒数叫做时间戳

获取时间戳:

var date = new Date();
// 方法一
console.log(date.getTime()); // getTime的方法获得毫秒数

// 方法二
console.log(+date);    // 直接通过计算的方式转换成毫秒数

示例代码:计算代码执行的时间

var start = new Date();
var sum = 0;
// 电脑性能不好的小伙伴 不要这么搞  循环的次数少一点
for (var index = 0; index < 1000000000; index++) {
    sum += index;
}
console.log(sum);  // 499999999067109000
var end = new Date();
console.log(end - start);  // 17899

13.3 Array 对象

数组对象在javascript中非常的常用

13.3.1 数组转换成字符串 join()

将数组的值拼接成字符串

语法:array.join(separator)

  • 数组的每一项默认的拼接符是逗号
  • 想要改变拼接符就在join()方法的括号里传入其他的拼接字符

示例代码:

var arr = ["大乔","小乔","甄姬","妲己","露娜"];
var str = arr.join();
console.log(str);  // "大乔,小乔,甄姬,妲己,露娜"

// 用“-”拼接符
var arr2 = ["大乔","小乔","甄姬","妲己","露娜"];
var str2 = arr2.join("-");
console.log(str2);  // "大乔-小乔-甄姬-妲己-露娜"

13.3.2 数组的增删操作

1、arr.push() 在数组最后面 添加元素,返回新数组的长度

var arr = ["大乔","小乔","甄姬"];
console.log(arr.push("妲己", "露娜"));  // 返回 5
console.log(arr);                       // ["大乔","小乔","甄姬","妲己","露娜"]

2、arr.pop() 在数组最后面删除一个元素,返回删除的那个元素

var arr = ["大乔","小乔","甄姬","妲己", "露娜"];
console.log(arr.pop());   // 返回 "露娜"
console.log(arr);         // ["大乔","小乔","甄姬","妲己"]

3、arr.unshift() 在数组前面添加元素,返回新数组的长度

var arr = ["甄姬","妲己", "露娜"];
console.log(arr.unshift("大乔","小乔"));   // 返回 5
console.log(arr);                          // ["大乔","小乔","甄姬","妲己", "露娜"];

4、arr.shift() 在数组最前面删除一个元素,返回删除的那个元素

var arr = ["大乔","小乔","甄姬","妲己", "露娜"];
console.log(arr.shift());   // 返回 "大乔"
console.log(arr);           // [小乔","甄姬","妲己", "露娜"];

示例代码(一):

var arr = ["刘备"];
//添加数据后变成:["赵云","马超","刘备","关羽","张飞"]
arr.push("关羽","张飞");
arr.unshift("赵云","马超");
console.log(arr);   //  ["赵云","马超","刘备","关羽","张飞"]

//删除数据后变成:["关羽","张飞"]
arr.shift();
arr.shift();
arr.shift();
console.log(arr);   // ["关羽","张飞"]

示例代码(二):

var arr = ["赵云","马超","刘备","关羽","张飞"];

//把数组的最后一个元素变成数组的第一个元素
arr.unshift(arr.pop());
console.log(arr);        // ["张飞","赵云","马超","刘备","关羽"]

13.3.3 数组的翻转与排序

1、arr.reverse() 翻转数组

var arr = [1,2,3,4,5];
var newArr = arr.reverse();
console.log(newArr);  // [5,4,3,2,1]   
console.log(arr);     // [5,4,3,2,1]

2、arr.sort() 数组排序

  • 默认按照字母顺序排序
  • sort方法可以传递一个函数作为参数,这个参数用来控制数组如何进行排序
  • a-b 从小到大排序,b-a 从大到小排序
var arr = [1,3,5,7,9,2,4,6,8,10];
var newArr = arr.sort(function(a,b){
    // 如果返回值>0,则交换位置
    return a - b;
});
console.log(newArr);  // [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]
console.log(arr);     // [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]

示例代码(一):

// 将字符串数组按照字符长度从大到小排列
var arr = ["ccc", "bb", "a", "dddd"];
arr.sort(function (a, b) {
    return b.length - a.length;
});
console.log(arr);       // ["dddd", "ccc", "bb", "a"]

示例代码(二):


//将学生数组按照年龄从小到大排列
var arr = [
    {name:"张三", age: 18, score: 50},
    {name:"李四", age: 70, score: 95},
    {name:"王五", age: 9, score: 33},
    {name:"赵六", age: 38, score: 100},
    {name:"田七", age: 6, score: 8},
    {name:"王八", age: 22, score: 66}
];

arr.sort(function(a, b) {
    return a.age - b.age;
});
console.log(arr);  

13.3.4 数组的拼接与截取

1、concat 数组的合并

var arr1 = [1, 3, 5, 7, 9];
var arr2 = [2, 4, 6, 8, 10];

// concat: 合并两个数组
var newArr = arr1.concat(arr2);
console.log(newArr);        //  [1, 3, 5, 7, 9, 2, 4, 6, 8, 10]

不会影响原来的数组,会返回一个新的数组

2、slice 数组切分

复制数组的一部分(浅拷贝)到一个新数组,并返回这个数组,原来的数组不受影响

slice有两个属性,分别是开始的下标和结束的下标,截取的时候包含begin,不包含end

var arr = [1, 3, 5, 7, 9];


// slice: 截取数组的一部分
var newArr = arr.slice(0,3);
console.log(newArr);        //  [1, 3, 5]

3、splice 数组拼接

splice:数组拼接,以新元素来替换旧元素,以此来修改数组的内容,常用于删除数组的某些项

array.splice(start, deleteCount, [items]); start:开始下标 deleteCount:删除的个数 items:替换的内容

splice 能实现多种用法:

  • 找到开始下标,删除个数为0,再输入替换的内容,此时就可以在数组中任意位置添加元素
  • 找到开始下标,需要删除的个数,再输入替换的内容,此时就可以在数组任意位置替换元素
  • 找到开始下标,需要删除的个数,不输入替换内容,此时就可以在数组任意位置,删除任意个数的元素
var arr = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10];

// 从下标是2的位置开始,删除0个,把 100 101 添加进去
var newArr = arr.splice(2, 0, 100, 101);
console.log(newArr); // 操作的是原数组,不会返回这个新数组
console.log(arr); // [1, 2,100,101,3, 4, 5, 6, 7, 8, 9, 10]     


// 也可以替换元素 (此时arr = [1, 2,100, 101, 3, 4, 5, 6, 7, 8, 9, 10] )
arr.splice(0, 2, 98, 99);
console.log(arr); // [98, 99, 100, 101, 3, 4, 5, 6, 7, 8, 9, 10]


// 也可以用于删除数组里的多个元素 (此时arr = [98, 99, 100, 101, 3, 4, 5, 6, 7, 8, 9, 10] )
arr.splice(0, 4);
console.log(arr); // [3, 4, 5, 6, 7, 8, 9, 10]

13.3.5 数组查找元素

indexOf()方法,是用来查找数组中,某个元素首次出现的位置,下标从0开始,找到的话返回位置信息,当找不到的时候返回-1

arr.indexOf(search,[fromIndex]);search:需要搜索的元素,fromIndex:规定在字符串中开始检索的位置。

示例代码:

var arr = [1, 5, 8, 11, 1, 2, 9];
arr.indexOf(8);  // 返回2
arr.indexOf(8,1) // 从下标1,往后查找 返回 2 
arr.indexOf(10); // 返回-1 说明找不到

与之对应的还有一个lastIndexOf(),从后往前找

var arr = [1, 5, 8, 11, 1, 2, 9];
arr.lastIndexOf(1);  // 返回4
arr.lastIndexOf(1,3) // 从下标3,往前查找 返回0 
arr.lastIndexOf(10); // 返回-1 说明找不到

13.3.6 清空数组

1、删除数组中的所有元素

var arr = [1,2,3,4,5];
arr.splice(0,arr.length);
console.log(arr);  // []

2、直接修改数组的长度

var arr = [1,2,3,4,5];
arr.length = 0;
console.log(arr);  // []

3、将数组赋值为一个空的数组

var arr = [1,2,3,4,5];
arr = [];
console.log(arr);  // []

13.3.7 数组的综合练习

var arr = ["c", "a", "z", "a", "x", "a", "a", "z", "c", "x", "a", "x"];
//1. 找到数组中第一个a出现的位置
console.log(arr.indexOf("a"));          // 1

//2. 找到数组中最后一个a出现的位置
console.log(arr.lastIndexOf("a"));      // 10

//3. 找到数组中每一个a出现的位置
for (var i = 0; i < arr.length; i++) {
    if (arr[i] == "a") {
        console.log(i);                 // 1 3 5 6 10
    }
}

//4. 数组去重,返回一个新数组
var newArr = [];
for (var i = 0; i < arr.length; i++) {
    if (newArr.indexOf(arr[i]) == -1) {   // 判断当newArr的数组里没有arr[i]的时候
        newArr.push(arr[i]);              // 将arr[i] 添加到newArr中 ["c", "a", "z", "x"]
    }
}
console.log(newArr);

//5. 获取数组中每个元素出现的次数
// 首先需要知道 如何判断一个对象中是否存在某属性
/*
    var obj = {
        name:"zs",
        age:18,
        score:100
    }
    //in关键字可以查看对象是否拥有某个属性。
    console.log( "sex" in obj );  // false
*/
var obj = {};
for(var i = 0; i < arr.length; i++){
    // 遍历数组,判断对象有没有这个属性, 
    if(arr[i] in obj){
        // 如果有这个属性,让这个属性的值+1 
        obj[arr[i]] ++;
    }else{
        // 如果没有这个属性,让这个属性等于1                    
        obj[arr[i]] = 1;
    }
}
console.log(obj);

13.4 String 对象

字符串可以看成是一个字符数组(伪数组)。因此字符串也有长度,也可以进行遍历。String对象很多方法的名字和和Array的一样。
// 遍历一段字符串
var str = "abcdefghijk";
for(var i = 0; i < str.length; i++){
    console.log(str[i]);  // "a" "b" "c" "d"...
}

13.4.1 字符串大小写转换的方法

小写转换成大写

toUpperCase(),toLocaleUpperCase()是将英文小写的字符串转换为大写,其中toLocaleUpperCase()方法则是针对特定地区的实现(如土耳其语会为Unicode大小写转换应用特殊的规则)。
var str = "hello world";
str.toUpperCase(); // "HELLO WORLD"
str.toLocaleUpperCase();

大写转换成小写

toLowerCase(),toLocaleLowerCase()是将英文小写的字符串转换为大写
var str = "HELLO WORLD";
str.toUpperCase(); // "hello world"
str.toLocaleUpperCase();

注意: 因为是方法,所以一定不要忘记加上()

13.4.2 indexOf 查找指定字符串

indexOf()方法,是用来判断指定字符,在当前字符串中首次出现的位置,下标从0开始,找到的话返回位置信息,当找不到的时候返回-1

示例代码:

var str= "good good study , day day up!";
str.indexOf("day");  // 返回18
str.indexOf("good"); // 返回0
str.indexOf("GOOD"); // 返回-1 说明找不到

与之对应的还有一个lastIndexOf(),是用来从后面开始查找字符第一次出现的位置

var str= "good good study , day day up!";
str.lastIndexOf("good");  // 返回 5

13.4.3 trim 去除空白

trim();方法,是用来去除字符串两边的空格,内部空格不会去除
var str = " A B C ";
console.log(str.trim());  // "A B C"

13.4.4 slice 截取字符串

slice()方法是用来截取一段字符串的,str.slice(start,end);它的两个参数都是表示下标的,一个表示开始,一个表示结束(截取时不包括结束下标)

说明:

  • start下标从0开始的str指定部分起始索引。如果start为负,将它作为length+start处理,此处length为字符串的长度。
  • end下标从0开始的str指定部分结束索引。如果end为负,将它作为length+end处理,此处length为字符串的长度。

示例代码:

// 起始位置结束位置都是正数
var str = "ABCDEFGHIJK";
str.slice(2,6);  // "CDEF"
// 当起始位置为负数的时候
var str = "ABCDEFGHIJK";
str.slice(-6, 10); // "FGHIJ"
// str的length为11,所以起始位置是-6+11=5,就是F结束是10(不包括10),那么就是J;
// 特殊情况 当起始位置在结束位置后面的时候,是截取不了的,返回空
var str = "ABCDEFGHIJK";
str.slice(-6, 2); // 空
// str的length为11,所以起始位置是-6+11=5,就是F,结束位置在2,这个时候是截取不了的

注意:

  • end为结束下标,截取的时候不包括end那一位
  • 截取是有顺序的,开始到结束的顺序必须是从左向右,否则是截取不了的,为空

13.4.5 substring 截取字符串

substring()方法返回位于String对象中指定位置的子字符串,str.substring(start,end);它的两个参数都是表示下标的,一个表示开始,一个表示结束(截取时不包括结束下标)

说明:

  • start指明子字符串的起始位置,该索引从0开始起算。
  • end指明子字符串的结束位置,该索引从0开始起算。
  • substring方法使用startend两者中的较小值作为子字符串的起始点。如果startendNaN或者为负数,那么将其替换为0

示例代码:

// 当起始位置,结束位置都是正数的时候
var str = "ABCDEFGHIJK";
str.substring(2,6); // "CDEF"
// 同样的,substring方法结束位置也不包括自己
// 当起始位置为负数的时候,直接转换成下标0
var str = "ABCDEFGHIJK";
str.substring(-2,6); // "ABCDEF" 下标转换成了0 
// 当开始的位置大于结束位置的时候,自动转换较小的值作为起点
var str = "ABCDEFGHIJK";
str.substring(6,2); // "CDEF"

利用substring方法,实现打字效果

/*样式部分*/
#box {
    width: 300px;
    height: 150px;
    border: 2px dashed fuchsia;
    margin: 100px auto;
    text-align: left;
    padding: 10px;
}
<!--html部分-->
<div id="box"></div>

<!--js部分-->
<script>
    var str = "ABCDEFGHIJKLMNOPQRSTUVWXYZ";
    var strLength = str.length;
    var index = 0;
    setInterval(function() {
        if (index >= strLength) {
            return;
        }
        index++;
        document.getElementById('box').innerHTML = str.substring(0, index);
    }, 100);
</script>

注意:

  • substring方法,end为结束下标,截取的时候同样不包括end那一位
  • start的值大于end的时候,两者中较小的值作为起始下标

13.4.6 字符串的 substr方法

substr()方法返回一个从指定位置开始,指定长度的子字符串。str.substr(start,length),start为开始的下标,length为需要返回字符串的长度

说明:

  • start所需的子字符串的起始位置。字符串中的第一个字符的索引为0
  • length在返回的子字符串中应包括的字符个数。

示例代码:

var str = "ABCDEFGHIJK";
str.substr(1,5); // BCDEF

13.4.7 match 查找字符串

match() 来查找字符串中特定的字符,并且如果找到的话,则返回这个字符,找不到的话返回null

示例代码:

var str= "good good study , day day up!";
str1.match("good");  // good
str1.match("Good");  // null

13.4.8 replace 替换字符串

replace() 方法在字符串中用某些字符替换另一些字符。

示例代码:

var str2 = "hello world";
str2.replace("world", "china"); // "hello china"

13.4.9 split 切割字符串转为数组

将一个字符串分割为子字符串,然后将结果作为字符串数组返回。str.split(separator,num),带一个参数separator表示切割的条件,第二个参数num表示需要切割的位数

说明:

  • separator(分隔符)字符串或正则表达式对象,它标识了分隔字符串时使用的是一个还是多个字符。如果忽略该选项,返回包含整个字符串的单一元素数组。
  • num该值用来限制返回数组中的元素个数。

示例代码:

var str = "ABCDEFGHIJK";
str.split("",6); // ["A", "B", "C", "D", "E", "F"]

13.5 Array对象 与 String对象综合练习

1、翻转一个字符串

var str = "abcdefg";
var strArr = str.split(""); // 将字符串转换为数组 ["a","b","c","d","e","f","g"]
strArr.reverse();           // 翻转这个数组       ["g","f","e","d","c","b","a"]
var newStr = strArr.join("");
console.log(newArr);        // "gfedcba"

2、将一串字符转化成对象

/*
有一个链接:http://www.baidu.com?name=cc&id=100&desc=很帅 
将链接的参数部分转换成一个对象
即{name:"cc", id=100 , desc: "很帅"}
*/
var str = "http://www.baidu.com?name=cc&id=100&desc=很帅";
var obj = {};
var strArr = str.split("?");          // ["http://www.baidu.com", "name=cc&id=100&desc=很帅"]
var strArr2 = strArr[1].split("=");   // ["name=cc", "id=100", "desc=很帅"]
for(var i = 0; i < strArr2.length; i++){
    console.log(strArr2[i]);          // "name=cc" "id=100" "desc=很帅"
    var key = strArr2[i].split("=")[0];     // name  id  desc
    var value = strArr2[i].split("=")[1];   // cc 100 很帅
    obj[key] = value;
}
console.log(obj);     // {name:"cc", id=100 , desc: "很帅"}

3、将对象转换成字符串

/*
有一个对象{name:"cc", id:100,desc:"很帅"}
和一个链接http://www.baidu.com,
拼接成链接http://www.baidu.com?name=cc&id=100&desc=很帅
*/
var prefix = "http://www.baidu.com";
var obj = {name:"cc", id:100,desc:"很帅"};
var arr = [];
for (var key in obj) {
    // console.log(key);            name id desc
    // console.log(obj[key]);       "cc" 100 "很帅"
    var str = key + "=" + obj[key];
    console.log(str);               // name=cc id=100 desc=很帅
    arr.push(str);  
    console.log(arr);               // ["name=cc", "id=100", "desc=很帅"]
}
var arrStr = arr.join("&");         
console.log(arrStr);                // name=cc&id=100&desc=很帅
var result = prefix + "?" + arrStr;
console.log(result);                // http://www.baidu.com?name=cc&id=100&desc=很帅

上一篇:JavaScript 基础知识 - 入门篇(一)
下一篇:JavaScript 基础知识 - DOM篇(一)


深海丶Deepsea
3.9k 声望1.4k 粉丝

Trust yourself,You know more than you think you do.