第二十二节:Javascript 高级(一)

第二十二节:Javascript 高级

this指向

这些 this 的指向,是当我们调用函数的时候确定的。调用方式的不同决定了this 的指向不同,一般指向我们的调用者

  1. 全局作用域或者普通函数中this指向全局对象window(注意定时器里面的this指向window)
  2. 方法调用中,谁调用 this就指向谁
  3. 构造函数中 this指向构造函数的实例
call 方法

作用:

  1. 调用函数
  2. 更改函数体中的this指向
  3. call 的继承性
/ 语法格式:
函数名.call(对象, 实参1, 实参2... 实参n);
let str = { name: '张学友' };
let star = { name: '刘德华' };

function fn (a, b, c) {
    console.log(this);
    console.log(a + b + c);
};

fn.call(star, 10, 20, 30);		// this是star,60

call 应用场景:经常做继承

function Father (name, age) {
    this.uname = name;
    this,age = age;
    // this ==> window
};

function Son (name, age) {
    // this ==> window
    // call 将Father中的this指向Son
    Father.call(this, uname, age);
};

let son = new Son('张三', 18);

console.log(son);	// Son {uname: "张三"}
apply 方法

作用:

  1. 立刻调用函数
  2. 更改函数体中的this指向
  3. 参数以数组形式存放

apply 应用场景:经常跟数组有关系

let arr = [10, 20, 30, 40, 50];
console.log(Math.max(10, 20, 30, 40, 50));

console.log(Math.max.apply(Array, arr));
bind 方法

作用:

  1. 更改this指向

特点:

  1. 不会立刻调用函数,会返回一个新函数
  2. 能改变函数内部this 指向,返回的是原函数改变this之后产生的新函数

如果只是想改变 this 指向,并且不想调用这个函数的时候,可以使用bind

/ 语法格式:
函数名.bind(对象)


bind 应用场景:不调用函数,但是还想改变this指向

严格模式

严格模式对正常的 JavaScript 语义做了一些更改:

  1. 消除了 Javascript 语法的一些不合理、不严谨之处,减少了一些怪异行为。
  2. 消除代码运行的一些不安全之处,保证代码运行的安全。
  3. 提高编译器效率,增加运行速度。
  4. 禁用了在 ECMAScript 的未来版本中可能会定义的一些语法,为未来新版本的 Javascript 做好铺垫。比如一些保留字如:class,enum,export, extends, import, super 不能做变量名
// 1. 开启全局作用域下的严格模式
'use strict'


// 2. 开启局部作用域下的严格模式
function fn () {
    // 为函数开启严格模式
    'use strict'
};

(function () {
    // 为脚本开启严格模式
    'use strict'
});
开启严格模式的变化
function fn () {
    'use strict';
    console.log(this);		// this不会指向window,而是指向 undefined
};

高阶函数

高阶函数:函数的参数是函数 或者 函数的返回值是函数

高阶函数是对其他函数进行操作的函数,它接收函数作为参数或将函数作为返回值输出

Array 方法
map()

遍历源数据,返回修改过的数据

let arr = [10, 20, 30, 40];

arr.map(function (item, index, arr) {
    return console.log(item);
});

// 结果为:10, 20, 30, 40

item:必须。当前元素

index:可选。当前元素索引值

arr:可选。整个数组

every()

判断每一项是否都满足条件,都满足返回 true,有一项不满足就返回 false

let arr = [10, 20, 30, 40];

arr.every(function(item, index, arr) {
    return item > 70;
});

// 结果为:false

item:必须。当前元素

index:可选。当前元素索引值

arr:可选。整个数组

some()

判断每一项是否都满足条件,只要有一项满足就返回 true,都不满足就返回 false

let arr = [10, 20, 30, 40];

arr.some(function(item, index, arr) {
    return item > 35;
});

// 结果为:true

item:必须。当前元素

index:可选。当前元素索引值

arr:可选。整个数组

filter()

创建一个新的数组,新数组中的元素是通过检查指定数组中符合条件的所有元素。

注意:

  • filter() 不会对空数组进行检测。

  • filter() 不会改变原始数组。

let arr = [10, 20, 30, 40];

arr.some(function(item, index, arr) {
    return item > 25;
});

// 结果为:

item:必须。当前元素

index:可选。当前元素索引值

arr:可选。整个数组

sort()

对数组元素进行排序

item1 - item2 是从小到大排序

item2 - item1 是从大到小排序

let arr = [10, 30, 20, 40];

arr.sort(function(item1, item2) {
	// item1 - item2 是从小到大排序
    return item1 - item2;
});

// 结果为:[10, 20, 30, 40]

item1:必须。当前元素

item2:必须。下一个元素

reduce()

计算数组元素相加的总和

let arr = [10, 20, 30, 40];

arr.some(function(total, item, index, arr) {
    return total + num;
});

// 结果为:100

total:必需。初始值, 或者计算结束后的返回值。

item:必需。当前元素

index:可选。当前元素的索引值

arr: 可选。当前元素所属的数组对象。

闭包

闭包(closure)指有权访问另一个函数作用域中变量的函数。简单理解就是 ,一个作用域可以访问另外一个函数内部的局部变量。

function fn1 () {
    let num = 100;
    function fn2 () {
        console.log(num);
    }
    fn2();
}

fn1();	// fn1() 变量在fn1()中,fn1() 就是闭包函数
变量的作用域

变量根据作用域的不同分为两种:全局变量和局部变量。

  1. 函数内部可以使用全局变量。

  2. 函数外部不可以使用局部变量。

  3. 当函数执行完毕,本作用域内的局部变量会销毁。

立即执行函数
/ 语法格式
// ()();

(
	function (形参) {
        
    }
)(实参);
闭包的作用

作用:延伸变量的作用范围。

简单理解:当函数执行完毕时,本作用域的局部变量不会销毁。

var arr = [];

for (var i=0; i<10; i++) {
    // 产生一个小闭包
    (function(i) {
        arr[i] = function () {
            console.log(i);
        }
    })(i);
};

for (var j=0; j<arr.length; j++) {
    console.log(arr[j]());
};


/ 语法
(function(形参) {
    console.log();
})(实参);

模拟场景:列表绑定点击事件,获取点击第几项

模拟场景,不推荐列表点击事件这么写,仅用于需要留存变量时使用

var lis = document.querySelectorAll('ul li');

for (var i=0; i<lis.length; i++) {
    (
        function (i) {
            lis[i].onclick = function () {
                console.log(i);
            }
        }
    )(i);
}

递归

如果一个函数在内部可以调用其本身,那么这个函数就是递归函数。

简单理解:函数内部自己调用自己,这个函数就是递归函数

注意:递归函数的作用和循环效果一样,由于递归很容易发生“栈溢出”错误(stack overflow),所以必须要加退出条件return。

递归求阶乘

阶乘:1 * 2 * 3 * 4 * … * n

function fn (n) {
    if (n == 1) {
        return 1;
    }
    return n * fn(n-1);
}

console.log(fn(4));

// 执行顺序:n * n-1 * n-2 * ... * 1
递归求斐波那契

斐波那契(兔子序列):前一项加后一项,循环计算

function fn (n) {
    if (n == 1 || n == 2) {
        return 1;
    }
    return fn(n-1) + fn(n-2);
}

console.log(fn(8));

// 执行顺序:n + n-1 + n-2 + ... + 1
递归扁平化数组

思路,判断每一项是否为数组,是数组

let arr = [1, [2, [3, [4, 5, [7, 8, 9]]]], 6];

let arrNew = [];

function fn(any) {
    for (let i=0; i<any.length; i++) {
        Array.isArray(any[i]) ? fn(any[i]) : arrNew.push(any[i]);
    };
};

fn(arr);
console.log(arrNew);
扩展:flat 方法 扁平化数组

flat() 方法创建一个新数组,其中所有子数组元素都以递归方式连接到该数组中,直到达到指定的深度为止。

返回值:一个新的数组,其中包含子数组元素。

/ 语法格式:
flat(depth);
// depth:指定嵌套数组结构应展平至多深的深度级别。默认为1

arr.flat(10000);
递归复制文件夹

模拟熊猫烧香病毒

MoveFile 方法

将指定文件或文件夹从一个位置移动到另一个位置

object.MoveFile(source, destination);

object:必须。应为 FileSystemObject 的名称

source:必须。需要移动的文件路径,source 参数的字符串只能在路径的最后成分中包含通配字符

destination:必须。文件要移到的路径。 destination 参数不能包含通配字符

注意:

如果 source 包含了通配字符,或者 destination 以路径分隔符 () 结束,那么将假定 destination 指定了一个已有的文件夹,匹配的文件将移入其中。 否则,将假定 destination 为需要创建的目的文件名。 无论哪种情况,如果移动的是单个文件,将有三种可能:

  • 如果 destination 不存在,那么那么文件将被移动。 这是普通情况。
  • 如果 destination 是已经存在了的文件,那么将出错。
  • 如果 destination 是目录,那么也将出错。

**重要: **只有在操作系统支持时,才能通过这种方法在卷之间移动文件。

CopyFile 方法

从一个位置向另一个位置移动一个或多个文件

object.CopyFile ( source, destination, overwrite );

object:必须。应为 FileSystemObject 的名称

source:必须。指定文件字符串,可以包含通配字符来复制一个或多个文件

destination:必须。目的字符串,文件将从 source 复制到这里。 不允许通配字符

overwrite:可选项。 Boolean 值,指明是否覆盖已有文件。 如果为 true ,则文件将被覆盖;如果为 false,则文件不会被覆盖。 默认的是 true。 注意,如果 destination 设置了只读属性,那么无论 overwrite 的值是什么,CopyFile 都会失败。

MoveFolder 方法

从一个位置向另一个位置移动一个或多个文件夹

object.MoveFolder (source, destination);

object:必须。 应为 FileSystemObject 的名称。

source:必须。 要移动的文件夹的路径。 source 参数的字符串只能在路径的最后成分中包含通配字符。

destination:必须。文件夹要移入的路径。 destination 参数不能包含通配字符。

注意:

如果 source 包含了通配字符,或者 destination 以路径分隔符 () 结束,那么将假定 destination 指定的是已经存在了的文件夹,匹配的文件将移入其中。 否则将假定 destination 是需要创建的目的文件夹的名称。 无论哪种情况,如果移动的是单个文件夹,将会有三种可能:

  • 如果 destination 不存在,那么文件夹将被移动。 这是普通情况。
  • 如果 destination 是已有的文件,那么将出错。
  • 如果 destination 是目录,那么也将出错。

如果 source 中使用的通配字符无法匹配任何文件夹,那么也将出错。 MoveFolder 方法在遇到第一个错误时终止。 出错后不会试图回滚出错前所做的修改。

重要 : 只有在操作系统支持时,才能通过这个方法在卷之间移动文件夹。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

孤安先生

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值