一、JavaScript流程控制-分支

1.1.流程控制 

流程控制就是来控制我们的代码按照什么结构顺序来执行。

流程控制主要有三种结构,分别是顺序结构、分支结构和循环结构,这三种结构代表三种代码执行的顺序。

jquery版的流程设计器 javascript流程控制_javascript

1.2.顺序流程控制

顺序结构是程序中最简单、最基本的流程控制,它没有特定的语法结构,程序会按照代码的先后顺序,依次执行,程序中大多数的代码都是这样执行的。

1.3.分支流程控制 if 语句

由上到下执行代码的过程中,根据不同的条件,执行不同的路径代码(执行代码多选一的过程),从而得到不同的结果。

JS语言提供了两种分支结构语句:if语句、switch语句。

// 1.多分支语句 就是利用多个条件来选择不同的语句执行 得到不同的结果 多选1的过程
// 2.if else if语句是多分支语句
// 3.语法规范
if (条件表达式1) {
    // 语句1;
} else if (条件表达式2) {
    // 语句2;
} else if (条件表达式3) {
    // 语句3;
} else {
    // 上述条件都不成立立即执行此处代码
}
// 4.执行思路
// 如果条件表达式1 满足就执行 语句1 执行完毕后,退出整个语句
// 如果条件表达式1 不满足,则判断条件表达式2 满足的话,执行语句2 依此类推
// 如果上面的所有条件表达式都不成立,则执行else里面的语句
// 5.注意点
// (1) 多分支语句还是多选1 最后只能有一个执行语句
// (2) else if里面的条件理论上是可以任意多个的
// 6.判断成绩案例
var score = prompt("请输入分数:");
if (score >= 90) {
    alert("优秀");
} else if (score >= 80) {
    alert("良好");
} else if (score >= 60) {
    alert("及格");
} else {
    alert("不及格");
}

1.4.三元表达式

三元表达式也能做一些简单的条件选择。有三元运算式子称为三元表达式。

语法结构:条件表达式 ? 表达式1 : 表达式2

执行思路:如果条件表达式为真则返回表达式1的值,如果表达式结构为假则返回表达式2的值。

console.log(1 > 2 ? '是的' : '不是的');

1.5.分支流程控制 switch 语句

// 1.switch语句也是多分支语句 也可以实现多选1
// 2.语法结构
switch (表达式) {
    case value1:
        执行语句1;
        break;
    case value2:
        执行语句2;
        break;
    ...
    default:
        执行最后的语句;
}
// 3.执行思路 利用我们的表达式的值和case后面的选项值匹配 如果匹配上,就执行case
// 里面的语句 如果都没有匹配上,那么执行default里面的语句
// 4.switch注意事项
var num = 1;
switch (num) {
    case 1:
        console.log(1);
    case 2:
        console.log(2);
    case 3:
        console.log(3);
        break;
}
// (1) 开发里面表达式我们经常写成变量
// (2) num的值和case里面的值相匹配的时候是 全等 必须是值和数据类型一致才可以 num === 1
// (3) break;如果当前的case里面没有break 则不会退出switch是继续执行下一个case
// 5.案例:查询水果
var fruit = prompt("请输入查询的水果名称:")
switch (fruit) {
    case '苹果':
        alert("苹果的价格是:3.5/斤");
        break;
    case '香蕉':
        alert("香蕉的价格是:2.5/斤");
        break;
    default:
        alert("没有此水果");
}

1.6.switch语句和if else if语句的区别

  • 一般情况下,它们两个语句可以互相替换。
  • switch...case 语句通常处理case为比较确定值的情况,而if...else...语句更加灵活,常用于范围判断。
  • switch语句进行条件判断后直接执行到查询的条件语句,效率更高。而if...else语句有几种条件,就得判断多少次。
  • 当分支比较少时,if...else语句的执行效率比switch语句高。
  • 当分支比较多时,switch语句的执行效率比较高,而结构更清晰。

二、JavaScript流程控制-循环

2.1.循环

在实际问题中,有许多具有规律性的重复操作,因此在程序中要完成这类操作就需要重复执行某些语句。

2.2.for循环

在程序中,一组被重复执行的语句被称之为循环体,能否继续重复执行,取决于循环的终止条件。由循环体及循环的终止条件组成的语句,被称之为循环语句。

// 1.for重复执行某些代码,通常跟计数有关系
// 2.for语法结构
for (初始化变量; 条件表达式; 操作表达式) {
    // 循环体
}
// 3.初始化变量 就是用var 声明一个普通变量,通常用于作为计数器使用
// 4.条件表达式 就是用来决定每一次循环是否继续执行 就是终止的条件
// 5.操作表达式是每次循环最后执行的代码 经常用于我们计数器变量进行更新(递增或者递减)
// 6.案例:求1-100之间所有整数的累加和
var sum = 0;
for (var i = 0; i <= 100; i++) {
    sum += i;
}
console.log(sum);
// 7.案例:九九乘法表
var str = '';
for (let i = 1; i <= 9; i++) {
    for (let j = 1; j <= i; j++) {
        str += j + ' * ' + i + ' = ' + i * j + '\t';
    }
    str += '\n';
}
console.log(str);

2.3.断点调试

断点调试是指自己在程序的某一行设置一个断点,调试时,程序运行到这一行就会停住,然后你可以一步一步往下调试,调试过程中可以看各个变量当前的值,出错的话,调试到出错的代码行即显示错误,停下。

断点调试可以帮我们观察程序的运行过程。

浏览器中按F12 --> sources --> 找到需要调试的文件 --> 在程序的某一行设置断点。

Watch:监视,通过watch可以监视变量的值的变化,非常的常用。

F11:程序单步执行,让程序一行一行的执行,这个时候,观察watch中变量的值的变化。

2.4.while循环

while语句可以在条件表达式为真的前提下,循环执行指定的一段代码,直到表达式不为真时结束循环。

while语句的语法结构如下:

        while (条件表达式) { // 循环体代码 }

执行思路

        1. 先执行条件表达式,如果结果为true,则执行循环体代码;如果为false,则退出循环,执行后面代码。

        2. 执行循环体代码

        3. 循环体代码执行完毕后,程序会继续判断执行条件表达式,如果条件仍为true,则继续执行循环体,直到循环条件为false时,整个循环过程才会结束。

2.5.do while循环

do...while语句其实是while语句的一个变体。该循环会先执行一次代码块,然后对条件表达式进行判断,如果条件为真,就会重复执行循环体,否则退出循环。

do { // 循环体代码-条件表达式为true是重复执行循环体代码 } while (条件表达式);

执行思路

        1. 先执行一次循环体代码。

        2. 在执行条件表达式,如果结果为true,则继续执行循环体代码,如果为false,则退出循环,继续执行后面代码。

注意:先执行循环体,再判断,do...while循环语句至少执行一次循环体代码。

2.6.continue break

continue关键字:用于立即跳出本次循环,继续下一次循环(本次循环体中continue之后的代码就会少执行一次)。

break关键字:用于立即跳出整个循环(循环结束)。

2.7.循环小结

  • JS中循环有for、while、do while。
  • 三个循环很多情况下都可以相互替代使用。
  • 如果是用来计次数,跟数字相关的,三者使用基本相同,推荐用for。
  • while和do...while可以做更复杂的判断条件,比for循环灵活一些。
  • while和do...while执行顺序不一样,while先判断后执行,do...while先执行一次,再判断执行。
  • while和do...while执行次数不一样,do...while至少会执行一次循环体,而while可能一次也不执行。
  • 实际工作中,更常用for循环语句,它写法更简洁直观。

三、数组

3.1.数组的概念

数组(Array):是指一组数据的集合,其中的每个数据被称作元素,在数组中可以存放任意类型的元素。

// 1.利用new创建数组

var arr = new Array();        // 创建了一个空的数组

// 2.利用数组字面量创建数组[]

var arr = [];        // 创建了一个空的数组

3.2.获取数组元素

3.2.1.数组的索引

索引(下标):用来访问数组元素的序号(数组下标从0开始)。

jquery版的流程设计器 javascript流程控制_javascript_02

数组可以通过索引来访问、设置、修改对应的数组元素,我们可以通过"数组名[索引]"的形式来获取数组中的元素。

这里的访问就是获取得到的意思。

3.2.2.遍历数组

遍历:就是把数组中的每个元素从头到尾都访问一次。

使用"数组名.length"可以访问数组元素的数量(数组长度)。

var arr = ['张三', '李四', '王五', '赵六'];

for (var i = 0; i < arr.length; i++) {

        console.log(arr[i]);

}

四、函数

4.1.函数的使用

函数使用分为两步:声明函数 和 调用函数。

声明函数:

        function 函数名() { // 函数体代码 }

        function是声明函数的关键字,必须小写。

函数名命名为动词,比如getSum。

调用函数:

        函数名();

注意:声明函数本身不会执行代码,只有调用函数才会执行函数体代码。

函数的封装就是把一个或多个功能通过函数的方式封装起来,对外只提供一个简单的函数接口。

4.2.函数的参数

在声明函数时,可以在函数名称后面的小括号中添加一些参数,这些参数被称为形参,而在调用该函数时,同样也需要传递相应的参数,这些参数被称为实参。

形参:形式上的数,函数定义的时候传递的参数,当前并不知道是什么。

实参:实际上的数,函数调用的时候传递的参数,实参的传递给形参的。

参数的作用:在函数内部某些值不能固定,我们可以通过参数在调用函数时传递不同的值进去。

4.3.函数形参和实参个数不匹配问题

实参等于形参个数:输出正确结果。

实参个数多于形参个数:只取到形参的个数。

实参个数小于形参个数:多的形参定义为undefined,结果为NaN。

小结:

        函数可以带参数也可以不带参数。

        声明函数的时候,函数名括号里面的是形参,形参的默认值为undefined。

        调用函数的时候,函数名括号里面的是实参。

        多个函数中间用逗号分隔。

        形参的个数可以和实参个数不匹配,但是结果不可预计,尽量要匹配。

4.4.函数的返回值格式

function 函数名() { return 需要返回的结果; }

函数名();

1. 我们函数只是实现某种功能,最终的结果需要返回给函数的调用者函数名() 通过return实现的。

2. 只要函数遇到return就把后面的结果 返回给函数的调用者 函数名() = return后面的结果。

3. return语句之后的代码不被执行。

4. return只能返回一个值。如果用逗号隔开多个值,以最后一个为准。

5. 函数没有return返回undefined。

4.5.arguments的使用

当我们不确定有多少个参数传递的时候,可以用arguments来获取。在JavaScript中,arguments实际上它是当前函数的一个内置对象。所有函数都内置了一个arguments对象,arguments对象中存储了传递的所有实参。

arguments展示形式是一个伪数组,因此可以进行遍历。伪数组具有以下特点:

        1. 具有length属性

        2. 按索引方式存储数据

        3. 不具有数组的push,pop等方法

五、作用域

5.1.作用域概述

通常来说,一段程序代码中所有用到名字并不总是有效和可用的,而限定这个名字的可用性的代码范围就是这个名字的作用域。作用域的使用提高了程序逻辑的局部性,增强了程序的可靠性,减少了名字冲突。

全局作用域:整个script标签或者是一个单独的js文件。

局部作用域(函数作用域):在函数内部就是局部作用域,这个代码的名字只在函数内部起效果和作用。

5.2.变量的作用域

全局变量:在全局作用域下声明的变量叫做全局变量(在函数外部定义的变量)。

局部变量:在局部作用域下声明的变量叫做局部变量(在函数内部定义的变量)。

六、预解析

1. js引擎运行js分为两步:预解析和代码执行

        (1). 预解析js引擎会把js里面所有的var还有function提升到当前作用域的最前面。

        (2). 代码执行 按照代码书写的顺序从上往下执行。

2. 预解析分为 变量预解析(变量提升)和函数预解析(函数提升)

        (1). 变量提升 就是把所有的变量声明提升到当前的作用域最前面 不提升赋值操作。

        (2). 函数提升 就是把所有的函数声明提升到当前作用域的最前面 不调用函数

七、对象

7.1.什么是对象

现实生活中:万物皆对象,对象是一个具体的事务,看得见摸得着的实物。例如:一本书、一辆汽车、一个人可以是"对象",一个数据库、一张网页、一个与远程服务器的连接也可以是"对象"。

在JavaScript中,对象是一组无序的相关属性和方法的集合,所有的事务都是对象,例如字符串、数值、数组、函数等。

对象是由属性和方法组成的。

属性:事务的特征,在对象中用属性来表示(常用名词)

方法:事务的行为,在对象中用方法来表示(常用动词)

7.2.创建对象的三种方式

在JavaScript中,现阶段可以采用三种方式创建对象(object):

字面量创建对象

new Object创建对象

构造函数创建对象

7.2.1.利用字面量创建对象

// 对象字面量:就是花括号{ }里面包含了表达这个具体事务(对象)的属性和方法。
// 1.利用对象字面量创建对象
// var obj = {};   // 创建了一个空对象
var obj = {
    uname: '张三',
    age: 100,
    sex: '男',
    sayHi: function () {
        console.log('你好!')
    }
}
// (1).里面的属性或者方法采用键值对的形式 键 属性名 : 值 属性值
// (2).多个属性或者方法中间用逗号隔开的
// (3).方法冒号后面跟的是一个匿名函数
// 2.使用对象
// (1).调用对象的属性采取对象名.属性值
console.log(obj.uname);
// (2).调用属性还有一种方法 对象名['属性名']
console.log(obj['age']);
// (3).调用对象的方法 sayHi 对象名.方法名()
obj.sayHi();

7.2.2.利用new Object创建对象

// 利用new Object创建对象
var obj = new Object(); // 创建了一个空对象
obj.uname = '张三';
obj.age = 100;
obj.sex = '男';
obj.sayHi = function () {
    console.log('你好!');
}
// 1.利用 等号 = 赋值的方法 添加对象的属性和方法
// 2.每个属性和方法之间用分号结束
console.log(obj.uname);
console.log(obj['sex']);
obj.sayHi();

7.2.3.利用构造函数创建对象

// 构造函数:是一种特殊的函数,主要用来初始化对象,即为对象成员变量赋值初始化,它总与new运算符一起使用。
// 可以把对象中一些公共的属性和方法抽取出来,然后封装到这个函数里面。
// 构造函数的语法格式:
function 构造函数名() {
    this.属性 = 值;
    this.方法 = function () {};
}

new 构造函数名();

function Star(uname, age, sex) {
    this.name = uname;
    this.age = age;
    this.sex = sex;
    this.sing = function (sang) {
        console.log(sang);
    }
}

var zs = new Star('张三', 100, '男');  // 调用函数返回的是一个对象
console.log(typeof zs);
console.log(zs.name);
console.log(zs['sex']);
zs.sing('稻香');
// 1.构造函数首字母要大写
// 2.构造函数不需要return就可以返回结果
// 3.调用构造函数必须使用new
// 4.只要new Star()调用函数就创建一个对象 zs {}
// 5.属性和方法前面必须添加this

7.3.new关键字执行过程

1. 在内存中创建一个新的空对象。

2. 让this指向这个新的对象。

3. 执行构造函数里面的代码,给这个新对象添加属性和方法。

4. 返回这个新对象(所以构造函数里面不需要return)。

7.4.遍历对象

var obj = {name: '张三', age: 100, sex: '男'}
// for in遍历对象
for (var key in obj) {
    console.log(key, obj[key]);
}

7.5.小结

1. 对象可以让代码结构更清晰。

2. 对象复杂数据类型object。

3. 本质:对象就是一组无序的相关属性和方法的集合。

4. 构造函数泛指某一大类,比如苹果,不管是红色还是绿色苹果,都通统称为苹果。

5. 对象实例特指一个事物,比如这个苹果。

6. for...in语句用于对对象的属性进行循环操作。

八、内置对象

8.1.什么是内置对象

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

内置对象就是指JS语言自带的一些对象,这些对象供开发者使用,并提供了一些常用的或是最基本而必要的功能(属性和方法)

8.2.Math对象

// 1.Math.E:欧拉常数,也是自然对数的底数,约等于 2.718。
console.log(Math.E);    // 2.718281828459045
// 2.Math.LN2:2 的自然对数,约等于 0.693。
console.log(Math.LN2);  // 0.6931471805599453
// 3.Math.LOG2E:以 2 为底的 E 的对数,约等于 1.443。
console.log(Math.LOG2E);    // 1.4426950408889634
// 4.Math.LOG10E:以 10 为底的 E 的对数,约等于 0.434。
console.log(Math.LOG10E);   // 0.4342944819032518
// 5.Math.PI:圆周率,一个圆的周长和直径之比,约等于 3.14159。
console.log(Math.PI);   // 3.141592653589793
// 6.Math.SQRT1_2:二分之一 ½ 的平方根,同时也是 2 的平方根的倒数 ,约等于 0.707。
console.log(Math.SQRT1_2);  // 0.7071067811865476
// 7.Math.SQRT2:2 的平方根,约等于 1.414。
console.log(Math.SQRT2);    // 1.4142135623730951
// 8.Math.abs(x):返回一个数的绝对值。
console.log(Math.abs(-10)); // 10
// 9.Math.cbrt(x):返回一个数的立方根。
console.log(Math.cbrt(8));  // 2
// 10.Math.max([x[, y[, …]]]):返回零到多个数值中最大值。
console.log(Math.max(111, 22, 553, 4));    // 553
// 11.Math.min([x[, y[, …]]]):返回零到多个数值中最小值。
console.log(Math.min(111, 22, 553, 4));    // 4
// 12.Math.pow(x, y):返回一个数的 y 次幂。
console.log(Math.pow(2, 3)); // 8
// 13.Math.random():返回一个 0 到 1 之间的伪随机数。
console.log(Math.random()); // 0.007275407654927291
// 14.Math.sqrt(x):返回一个数的平方根。
console.log(Math.sqrt(4));  // 2
// 具体查看MDN:https://developer.mozilla.org/zh-CN/docs/Web/JavaScript/Reference/Global_Objects/Math

8.3.日期对象

// Date():日期对象 是一个构造函数,必须使用new来调用创造日期对象
// 1.使用Date如果没用参数返回当前系统时间
var date = new Date();
console.log(date)   // Fri Jan 27 2023 14:52:49 GMT+0800 (中国标准时间)
// 2.参数常用写法,数字型2022,12,12或者是字符串型'2022-12-12 12:12:12'
var date1 = new Date(2022, 12, 12);
console.log(date1); // Thu Jan 12 2023 00:00:00 GMT+0800 (中国标准时间)
var date2 = new Date('2022-12-12 12:12:12');
console.log(date2); // Mon Dec 12 2022 12:12:12 GMT+0800 (中国标准时间)
// 3.日期格式
console.log(date.getFullYear());   // 返回年
console.log(date.getMonth() + 1);  // 返回月(0-11)
console.log(date.getDate());   // 返回日
console.log(date.getDay());    // 返回星期 周日-周六(0-6)
console.log(date.getHours());   // 返回时
console.log(date.getMinutes());  // 返回分
console.log(date.getSeconds()); // 返回秒
var year = date.getFullYear();
var month = date.getMonth() + 1;
var dates = date.getDate();
var arr = ['星期日', '星期一', '星期二', '星期三', '星期四', '星期五', '星期六'];
var day = date.getDay();
console.log('今天是:' + year + '年' + month + '月' + dates + '日 ' + arr[day]);    // 今天是:2023年1月27日 星期五
// 4.时间戳
// (1).通过valueOf()  getTime()
console.log(date.valueOf());    // 1674804148694
console.log(date.getTime());    // 1674804148694
// (2).简单的写法(最常用的写法)
var dada = +new Date(); // 返回的就是总的毫秒数
console.log(dada);  // 1674804148694
// (3).H5新增的获得总的毫秒数
console.log(Date.now());    // 1674804148694
// 5.倒计时案例
function conutDown(time) {
    var nowTime = +new Date();  // 返回的是当前时间总的毫秒数
    var inputTime = +new Date(time);  // 返回的是用户输入时间总的毫秒数
    var times = (inputTime - nowTime) / 1000; // time是剩余时间总的秒数
    var d = parseInt(times / 60 / 60 / 24);    // 天
    d = d < 10 ? '0' + d : d;
    var h = parseInt(times / 60 / 60 % 24);   // 时
    h = h < 10 ? '0' + h : h;
    var m = parseInt(times / 60 % 60);    // 分
    m = m < 10 ? '0' + m : m;
    var s = parseInt(times % 60);   // 秒
    s = s < 10 ? '0' + s : s;
    return d + '天' + h + '时' + m + '分' + s + '秒';
}
console.log(conutDown('2023-2-21 08:00:00'));

8.4.数组对象

// 常用方法 
var arr = ['张三', '李四', '王五', '赵六'];
// 1.toString():把数组转换为数组值(逗号分割)的字符串
console.log(arr.toString());    // 张三,李四,王五,赵六
// 2.join:将所有的数组元素结合为一个字符串,类似于toString(),但是可以规定分隔符
console.log(arr.join('*')); // 张三*李四*王五*赵六
// 3.pop():从数组中删除最后一个元素,返回"被删除的值"
var res1 = arr.pop();
console.log(res1);   // 赵六
console.log(arr);   // ['张三', '李四', '王五']
// 4.push():在数组结尾处向数组添加一个新元素,返回新数组的长度
var res2 = arr.push('千岁忧');
console.log(res2);  // 4
console.log(arr);   // ['张三', '李四', '王五', '千岁忧']
// 5.shift():删除第一个元素,返回被删除的值
var res3 = arr.shift();
console.log(res3);  // 张三
console.log(arr);   // ['李四', '王五', '千岁忧']
// 6.unshift():在开头向数组添加新元素,返回数组的长度
var res4 = arr.unshift('晚来雪');
console.log(res4);  // 4
console.log(arr);   // ['晚来雪', '李四', '王五', '千岁忧']
// 7.修改元素
arr[1] = '惊鸿舞';
console.log(arr);   // ['晚来雪', '惊鸿舞', '王五', '千岁忧']
// 8.删除任意元素,元素改为 undefined
delete arr[2];
console.log(arr);   // ['晚来雪', '惊鸿舞', 空, '千岁忧']
// 9.splice():拼接数组,也可以用来删除元素
// 第一个参数(2)定义了应添加新元素的位置(拼接)。
// 第二个参数(2)定义应删除多少元素。
// 其余参数('孔明','李耳')定义要添加的新元素。
var res5 = arr.splice(2, 2, '孔明', '李耳');
console.log(res5);  // [空, '千岁忧']
console.log(arr);   // ['晚来雪', '惊鸿舞', '孔明', '李耳']
// 10.concat():合并数组返回一个新数组(可以添加多个参数)
var arr2 = ['千岁忧', '张三'];
var new_arr = arr.concat(arr2);
console.log(new_arr);  // ['晚来雪', '惊鸿舞', '孔明', '李耳', '千岁忧', '张三']
// 11.slice():切片
var res6 = arr.slice(2);
console.log(res6);  // ['孔明', '李耳']

// 数组排序
var arr = ['b', 'a', 'c', 1, 7, 2, 4];
// 1.sort():方法以字母顺序对数组进行排序
console.log(arr.sort());    // [1, 2, 4, 7, 'a', 'b', 'c']
// 2.reverse():方法反转数组中的元素
console.log(arr.reverse()); // ['c', 'b', 'a', 7, 4, 2, 1]
// 3.数字排序
// 默认地,sort() 函数按照字符串顺序对值进行排序。
// 该函数很适合字符串("Apple" 会排在 "Banana" 之前)。
// 不过,如果数字按照字符串来排序,则 "25" 大于 "100",因为 "2" 大于 "1"。
// 正因如此,sort() 方法在对数值排序时会产生不正确的结果。
// 我们通过一个比值函数来修正此问题:
var arr1 = [40, 66, 8, 0, 7, 5, 99];
arr1.sort(function (a, b) {
    // return a - b;   // 升序
    return b - a;   // 降序
})
console.log(arr1);  // [99, 66, 40, 8, 7, 5, 0]
// 4.以随机顺序排序数组
arr1.sort(function (a, b) {
    return 0.5 - Math.random();
})
console.log(arr1);  // [8, 0, 99, 5, 7, 66, 40]
// 5.冒泡排序是一种简单的排序算法,它重复地走访要排序的数列,一次比较两个元素,如果它们的顺序错误就把它们交换过来。
// 走访数列的工作是重复地进行直到没有在需要交换,也就是说该数列已经排序完成。
var arr2 = [5, 2, 1, 3, 4];
for (var i = 0; i < arr2.length; i++) {
    for (var j = 0; j < arr2.length - i - 1; j++) {
        if (arr2[j] > arr2[j + 1]) {
            var temp = arr2[j];
            arr2[j] = arr2[j + 1];
            arr2[j + 1] = temp;
        }
    }
}
console.log(arr2);

8.5.字符串对象

8.5.1.基本包装类型

基本包装类型:就是包简单数据类型包装成为复杂数据类型,这样基本数据类型就有了属性和方法。

// 下面代码有什么问题
var str = '千岁忧';
console.log(str.length);


按道理基本数据类型是没有属性和方法的,而对象才有属性和方法,但上面代码却可以执行,这是因为js会把基本数据类型包装为复杂数据类型,其执行过程如下:

// 1.生成临时变量,把简单类型包装为复杂数据类型
var temp = new String('千岁忧');
// 2.赋值给我们声明的字符变量
str = temp;
// 3.销毁临时变量
temp = null;

8.5.2.字符串的不可变

指的是里面的值不可变,虽然看上去可以改变内容,但其实是地址变了,内存中新开辟了一个内存空间。

var str = 'abc';
str = 'hello';
// 当重新给str赋值的时候,常量'abc'不会被修改,依然在内存中
// 重新给字符串赋值,会重新在内存中开辟空间,这个特点就是字符串的不可变
// 由于字符串的不可变,在大量拼接字符串的时候会有效率问题
var str = '';
for (var i = 0; i < 10000; i++) {
        str +=i;
}
console.log(str);        // 这个结果需要花费大量时间来显示,因为需要不断的开辟的空间

8.5.3.根据字符返回位置

字符串所有的方法,都不会修改字符串本身(字符串是不可变的),操作完成会返回一个新的字符串。

indexOf('要查找的字符',开始位置):返回指定内容在元字符串中的位置,如果找不到就返回-1,开始的位置是index索引号。

lastIndexOf():从后往前找,只找第一个匹配的。

8.5.4.根据位置返回字符

charAt(ubdex):返回指定位置的字符(index字符串的索引号)。

charCodeAt(index):获取指定位置处字符的ASCII码(index索引号)。

str[index]:获取指定位置处字符。

8.5.5.字符串操作方法

concat(str1,str2,str3...):concat()方法用于连接两个或多个字符串。拼接字符串,等效于+,+更常用。

substr(start,length):从start位置开始(索引号),length取的个数。

slice(start,end):从start位置开始,截取到end位置,end取不到。

substring(start,end):从start位置开始,截取到end位置,end取不到,基本和slice相同,但是不接受负值。

replace('被替换的字符','替换为的字符'):它只会替换第一个字符。

split('分隔符'):字符转换为数组。

九、简单类型与复杂类型

简单类型又叫做基本数据类型或者值类型,复杂类型又叫做引用类型。

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

        string、number、boolean、undefined、null

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

        通过new关键字创建的对象(系统对象、自定义对象),如Object、Array、Date等

9.1.堆和栈

栈(操作系统):由操作系统自动分配释放函数的参数值、局部变量的值等。其操作方式类似于数据结构中的栈。简单数据类型存放到栈里面。

堆(操作系统):复杂数据类型(对象),一般由程序员分配,若程序员不释放,由垃圾回收机制回收。复杂数据类型存放到堆里面。

注意:JavaScript中没有堆栈的概念,通过堆栈方式,便于理解代码的一些执行方式。

9.2.简单类型传参

函数的形参也可以看做是一个变量,当把一个值类型变量作为参数传递给函数的形参时,其实是把变量在栈空间里面复制了一份给形参,那么在方法内部对形参做任何修改,都不会影响到外部变量。

function fn(a) {
        a++;
        console.log(a);
}
var x = 10;
fn(x);
console.log(x);

9.3.复杂类型传参

函数的形参也可以看做是一个变量,当我们把引用类型变量传递给形参时,其实是把变量在栈空间里面保存地址复制给了形参,形参和实参其实保存的是同一个堆地址,所以操作的是同一个对象。

function Person(name) {
        this.name = name;
}
function f1(x) {        // x = p
        console.log(x.name);        // 2.这个输出什么?晚来雪
        x.name = "千岁忧";
        console.log(x.name);        // 3.这个输出什么?千岁忧
}
var p =new Person("晚来雪");
console.log(p.name);        // 1.这个输出什么?晚来雪
f1(p);
console.log(p.name);        // 4.这个输出什么?千岁忧

十、APIs简介

Web APIs阶段:

        Web APIs是W3C组织的标准

        Web APIs主要学习DOM和BOM

        Web APIs是JS独有的部分

        主要页面交互功能

API:

API(Application Programming Interface,应用程序编程接口)是一些预先定义的函数,目的是提供应用程序与开发人员基于某软件或硬件得以访问一组例程的能力,而又无需访问源码,或理解内部工作机制的细节。

        API是给程序员提供的一种工具,以便能更轻松的实现想要完成的功能。

Web API:Web API是浏览器提供的一套操作浏览器功能和页面元素的API(BOM和DOM)

小结:

API是为程序员提供的一个接口,实现某种功能。

        2. Web API主要是针对于浏览器提供的接口,主要针对于浏览器做交互效果。