ECMAScript1.3 数组 | 函数 | 作用域 | 预解析

数组array

数组可以存储很多项,有顺序,很多项形成一个集合,就是数组。

数组字面量是:[]

如何获取数组中的数据:索引/下标,数组中的第一项的索引是从0开始的。

['kay', 'andy', 18, 19, true]数组可以存储多个值,也可以是不同数据类型但不建议使用!

存储的数组是要有意义的比如  name就只存名字,其他的元素18,19会把我们的数据给打乱!

创建数组与增删改查:

// 创建数组
var arr = ['andy', 'kay', 'jack'];
// 获取数组里的第一项
console.log(arr[0]);    // andy
// 获取数组里的第二项
console.log(arr[1]);    // kay

// 获取数组的长度:就是数组中元素的个数
console.log(arr.length);    // 3

// 获取数组中的最后一个元素:数组长度-1
console.log(arr[arr.length - 1]);    // jack

// 修改数组中的元素
arr[1] = 'aa';
console.log(arr);    // ["andy", "aa", "jack"]
// 在修改某元素时索引超出了它的长度就会给数组增加项
arr[5] = 'kay';
// 跳过的那些值默认就是undefined。
console.log(arr);    // ["andy", "aa", "jack", empty × 2, "kay"]
// 这是数组的长度可以动态改变
console.log(arr.length);    // 6

// 追加元素
arr[arr.length] = 'abc';
console.log(arr);    // ["andy", "aa", "jack", empty × 2, "kay", "abc"]

// 清空数组
arr.length = 0;    
console.log(arr);    // []
View Code

遍历数组

var arr = ['kay', 'andy', 'jack'];
// 数组的第一个元素是从0开始,数组中的最后一个元素(就是数组的长度-1)
for (var i = 0; i < arr.length; i++) {
    console.log(arr[i]);
}

// 反向遍历数组
var array = ['kay', 'andy', 'jack'];
// 数组中的最后一个元素(就是数组的长度-1), 数组的第一个元素是从0开始
for (var j = array.length - 1; j >= 0; j--) {
    console.log(array[j]);
}
View Code

例子:求一组数的和和平均值

var numbers = [10, 20, 30];
// 总和
var sum = 0;
// 平均值
var avg = 0;

for (var i = 0; i < numbers.length; i++) {
    sum += numbers[i];
}
avg = sum / numbers.length;
console.log(sum);    // 60
console.log(avg);    // 20
View Code

job:求一组数中的最大值和最小值,以及所在位置

var numbers = [79, 21, 3, 8, 45, 88, 89];
// 假设数组中第一个元素就是最大
var max = numbers[0];
// 假设数组中第一个元素就是最小
var min = numbers[0];
//最大值的索引位置
var maxIndex;
// 最小值的索引位置
var minIndex;
// 拿到数组中的每一元素
for (var i = 0; i < numbers.length; i++) {
    // 比max大
    if (max < numbers[i]) {
        // 重新赋值
        max = numbers[i];
        // 索引位置
        maxIndex = i;  
    }
    // min大于numbers[i]
    if (min > numbers[i]) {
        // 重新赋值
        min = numbers[i];
        // 索引位置
        minIndex = i;
    }
}
console.log(max + '索引位置:' + maxIndex);
console.log(min + '索引位置:' + minIndex);
View Code

 job:将字符串数组用符号(|)分割

var names = ['人工智能', '大数据', '前端', 'kay', 'java'];

var str = names[0];
// 分隔符
var seperator = '|';

for (var i = 1; i < names.length; i++) {
    str += seperator + names[i];
}
console.log(str);    // 人工智能|大数据|前端|kay|java
View Code

job:将数组中的0项去掉,将不为0的的值存到一个新的数组,生成新的数组

var numbers = [88, 0, 13, 32, 0, 2, 0, 62];
// 新数组
var newArr = [];
// 遍历数组
for (var i = 0; i < numbers.length; i++) {
    // 不等于0
    if (numbers[i] !== 0) {
        // 储存到新数组里
        newArr[newArr.length] = numbers[i];
    }
}

console.log(newArr);    // [88, 13, 32, 2, 62]
View Code

job:翻转数组

var arr = ['kay', 18, 'jack', 19];
// 新数组
var newArr = [];
// 反向遍历
for (var i = arr.length - 1; i >= 0; i--) {
    // 存储到新数组里
    newArr[newArr.length] = arr[i];
}
console.log(newArr);    // [19, "jack", 18, "kay"]
View Code

job:冒泡排序-从小到大排

var numbers = [79, 12, 3, 1, 54, 7, 45, 68];
// 外层循环控制趟数
for (var i = 0; i < numbers.length; i++) {
    // 假如已排好
    var isOk = true;
    // 内层循环控制比较次数
    for (var j = 0; j < numbers.length - 1 - i; j++) {
        // 元素1比元素2大
        if (numbers[j] > numbers[j + 1]) {
            // 未排好序
            isOk = false;
            // 定义临时变量 赋予元素1
            var tmp = numbers[j];
            // 元素2 放到 元素1的位置
            numbers[j] = numbers[j + 1];
            // 元素1 放到 元素2的位置
            numbers[j + 1] = tmp;
        }
    }
    if (isOk) {
        // 终止循环
        break;
    }
}
console.log(numbers);    // [1, 3, 7, 12, 45, 54, 68, 79]
View Code

函数 function

函数的作用:封装代码,重复调用

定义函数

// 定义函数
function getSum() {
    // 函数体
    // 计算1到100之间所有数的和
    var sum = 0;
    for (var i = 1; i <= 100; i++) {
        sum += i;
    }
    console.log(sum);
}
// 调用函数
getSum();    // 5050
View Code

函数的参数:调用时,可以向其传递值

// 计算n到m之间所有数的和

// 定义函数(形参1, 形参2)
function getSum(n, m) {
    // 函数体
    var sum = 0;
    for (var i = n; i <= m; i++) {
        // 累加
        sum += i;
    }
    console.log(sum);
}
// 调用函数并传递实参
getSum(50, 100);    // 3825
View Code

 传入的参数可以是变量,在函数内部修改形参的值,不会影响外部的实参的值。

因为在调用函数时,复制了一份给形参的。

function getSum(a, b) {
    // 修改形参的值
    a = a + 1;
    b = b + 1;
    console.log(a);    // 2
    console.log(b);    // 3
}
var n1 = 1;
var n2 = 2;
getSum(n1, n2);
// 不会影响外部的值
console.log(n1);    // 1
console.log(n2);    // 2
View Code

函数的返回值:返回值只有一个

可以用变量接收返回值。当函数里不写return返回值时用用变量接收的是undefined,不写return也是返回undefined!

return后面的代码是不会执行的!

// 计算n到m所有数的和,并返回
function getSum (n, m) {
    // 函数体
    var sum = 0;
    for (var i = n; i <= m; i++) {
        // 累加
        sum += i;
    }
    // 返回所有数的和
    return sum;
}

// 接收返回值
var num = getSum(1, 100);
console.log(num);    // 5050
View Code

job: 判断一个数是否是素数(所谓质数就是只能被1或自身整除,不能被其他数整除)

// 定义函数
function getPrime(num) {
    // 只能被1或者自身整除
    for (var i = 2; i < num; i++) {
        // 被整除
        if (num % i === 0) {
            // 返回false
            return false;
        }
    }
    // 是质数
    return true;
}
console.log(getPrime(13));    // true
View Code

job:求1!+2!+3!+....+n!

// 求阶乘
// 定义函数
function getFactorial(num) {
    // 因为是算乘法,我们用1去乘
    var result = 1;
    for (var i = 1; i <= num; i++) {
        result *= i;
    }
    // 返回结果
    return result;
}
// console.log(getFactorial(3));    // 6


// 求阶乘的综合
// 定义函数
function getSum(num) {
    var sum = 0;
    for (var i = 1; i <= num; i++) {
        // 累加
        sum += getFactorial(i);
    }
    // 返回总和
    return sum;
}

console.log(getSum(3));    // 9
View Code

 

arguments:在函数里获取实参,实参的个数可以发生改变。

实参个数不确定的时候可以使用,定义函数时不写形参。

arguments是一个伪数组,有长度

// 定义函数时不写形参
function test() {
    console.log(arguments);    // [1, 66, 7, 34, 98, callee: ƒ, Symbol(Symbol.iterator): ƒ]
}

// 传递实参
test(1, 66, 7, 34, 98);
View Code

 job: 求任意个数的最大值

// 定义函数
function getMax() {
    // 假设第一就是最大的值
    var max = arguments[0];
    // 遍历这个伪数组
    for (var i = 1; i < arguments.length; i++) {
        // 比较    
        if (max < arguments[i]) {
            // max重新赋予值
            max = arguments[i];
        }
    }
    // 返回这个max
    return max;
}
// 传入任意个数的实参
var num = getMax(79, 78, 88, 45, 23, 21);
console.log(num);    // 88
View Code

job:求任意个数的和

// 定义函数
function getSum() {
    var sum = 0;
    // 遍历这个伪数组
    for (var i = 0; i < arguments.length; i++) {
        // 累加
        sum += arguments[i];
    }
    // 返回sum
    return sum;
}
// 传入任意个数的实参
var num = getSum(10, 20, 30);
console.log(num);    // 60
View Code

job:任意个数从小到大排|冒泡排序

// 定义函数
function sort() {
    // 外层循环控制趟,每执行完一趟就排好一个元素
    for (var i = 0; i < arguments.length; i++) {
        // 假设已经排好
        var isSort = true;
        // 内层循环控制比较次数
        for (var j = 0; j < arguments.length - 1 - i; j++) {
            // 比较两个元素
            if (arguments[j] > arguments[j + 1]) {
                // 还没有排好序
                isSort = false;
                // 交换位置
                var tmp = arguments[j];
                arguments[j] = arguments[j + 1];
                arguments[j + 1] = tmp;
            }
        }
        // 判断是否排好序
        if (isSort) {
            // 终止循环
            break;
        }
    }
    // 返回已排好序的伪数组
    return arguments;
}

// 传入任意个数的形参
var numbers = sort(79, 23, 56, 11, 2, 9);
console.log(numbers);    //  [2, 9, 11, 23, 56, 79, callee: ƒ, Symbol(Symbol.iterator): ƒ]
View Code

 函数其它

1,命名函数:有名

2,匿名函数:没名,赋给一个变量

// 赋给变量
var fn = function () {
    alert('hello kay');
}

fn();
View Code

3,自调用函数:没名,也不赋给变量

// 没名,不赋给变量
(function () {
    alert('hello kay');
}) ();    // 紧跟着一对括号直接调用
View Code

4.1函数当参数:传递给其它函数

// 先赋给一个变量
var fn1 = function () {
    alert('hello kay');
}

function fn2 (fn) {
    // 调用函数
    fn();
}

// 当参数传入
fn2(fn1);
View Code

4.2函数当返回值

function fn() {
    // 函数当返回值
    return function () {
        alert('hello');
    }
}

// 一个变量取接收这个函数
var fn1 = fn();
// 调用接收的函数
fn1();
View Code

 作用域:使用范围

全局变量和局部变量:

全局变量:声明的变量使用var声明的,那么这个变量就是全局变量,并且在任何位置都可以使用。

隐式全局变量:声明变量时没有加var,就叫全局变量。

全局变量不能被删除的,隐式全局变量可以被删除的,定义变量使用var是不会被删除的,没有var是可以用delete删除的

局部变量:在函数内部定义的变量,外面不能使用。

 

块级作用域:

{
    var num = 88;
}

// 可以使用
console.log(num);    // 88
View Code

一对大括号可以看成是一块,在这块区域中定义的变量,只能在这块区域使用,

但在js中在这块区域中定义的变量外面是可以使用的!

所以说明js没有块级作用域,也就是全局变量,函数除外

 

作用域链:

在函数中使用一个变量,先在该函数中搜索这个变量,找到了则使用,找不到则继续向外面找这个变量,找到了则使用,

一直找到全局作用域,找不到则报错!

// 0级全局作用域
var num = 456;
function f1() {
    // 1级作用域
    var num = 123;
    function f2() {
        // 2级作用域
        console.log(num);
    }
    f2();
}
f1();
View Code

 

预解析

 浏览器的解析引擎:

javascript代码的执行是由浏览器中的javascript解析器来执行的。

javascript解析器执行javascript代码时分为两个过程:预解析和代码执行过程。

两个问题:

console.log(num);    //  结果是undefined,而不是报错
var num = 666;
问题1

f1();
function f1() {
    console.log(666);
}

// 结果是666
问题2

预解析过程:

1,把变量的声明提升到当前作用域的最前面,只提升声明,不提升赋值!

2,把函数的声明提升到当前作用域的最前面,只提升声明,不提升调用!

3,先提升var,再提升function!

f1();
console.log(b);
console.log(c);
console.log(a);
function f1() {
    var a = b = c = 8;
    console.log(a);    
    console.log(b);
    console.log(c);
}
例子1
8
8
8
8
8
a is not defined
结果

由于a是局部变量,外部无法访问到,所以报错。

而b和c声明变量没有用var声明,是隐身全局变量,外部是可以访问到的。

 

console.log(a);
function a() {
    console.log('666');
}
var a = 8;
console.log(a);
例子2
a() {
    console.log('666');
}
8
结果

当变量名与函数名相同,函数优先

posted @ 2019-04-07 23:18  Kay_xs  阅读(195)  评论(0编辑  收藏  举报