学无先后,达者为师

网站首页 前端文档 正文

JS高级-函数定义与调用、函数内的this指向、改变this指向方法、闭包、递归、严格模式

作者:good法乐 更新时间: 2021-12-16 前端文档
  • 函数的定义与调用
方式1 函数声明方式 function 关键字 (命名函数)
function fn(){}

方式2 函数表达式(匿名函数)
var fn = function(){}

方式3 new Function()
var f = new Function('a', 'b', 'console.log(a + b)');
f(1, 2);
var fn = new Function('参数1','参数2'..., '函数体')
注意
/*Function 里面参数都必须是字符串格式
第三种方式执行效率低,也不方便书写,因此较少使用
所有函数都是 Function 的实例(对象)
函数也属于对象
*/
/* 1. 普通函数 */
function fn() {
console.log('人生的巅峰');
}
fn();
/* 2. 对象的方法 */
var o = {
sayHi: function() {
console.log('人生的巅峰');
}
}
o.sayHi();
/* 3. 构造函数*/
function Star() {};
new Star();
/* 4. 绑定事件函数*/
btn.onclick = function() {}; // 点击了按钮就可以调用这个函数
/* 5. 定时器函数*/
setInterval(function() {}, 1000); 这个函数是定时器自动1秒钟调用一次
/* 6. 立即执行函数(自调用函数)*/
(function() {
console.log('人生的巅峰');
})();
  • 函数内部的this指向
    this执行只有在调用函数的时候才确定、一般指向调用者
    在这里插入图片描述
  • 改变函数内部 this 指向的方法
call()方法、呼叫的意思、主要用于实现继承、
作用、1、调用方法、2、改变this指向

apply()方法、应用、运用的意思、
作用、1、调用方法、2、改变this指向
不同的是参数必须是数组()

bind()方法、捆绑、绑定的意思、
作用、1、不会调用函数、2、改变this指向
拷贝原来的函数改变this、返回一个新的函数
用于:不想立即执行函数、又想改变这个函数内部的this执行时用bind()
例如定时器、我想触发时才调用
  • call、apply、bind三者的异同
共同点 : 都可以改变this指向
不同点:
call 和 apply 会调用函数, 并且改变函数内部this指向.
call 和 apply传递的参数不一样,call传递参数使用逗号隔开,apply使用数组传递
bind 不会调用函数, 可以改变函数内部this指向.
应用场景
1. call 经常做继承.
2. apply经常跟数组有关系. 比如借助于数学对象实现数组最大值最小值
3. bind 不调用函数,但是还想改变this指向. 比如改变定时器内部的this指向.
  • 严格模式
    通过严格模式去解决一些不合理、不规范的地方

  • 开启严格模式
    –为脚本开启严格模式:让use strict模式作用与全局作用域

(function (){
//在当前的这个自调用函数中有开启严格模式,当前函数之外还是普通模式
"use strict";
var num = 10;
function fn() {}
})();
//或者
<script>
"use strict"; //当前script标签开启了严格模式
</script>

– 为函数开启严格模式 :让use strict模式作用于局部作用域
要给某个函数开启严格模式,需要把“use strict”; (或 ‘use strict’; ) 声明放在函数
体所有语句之前。

function fn(){
"use strict";
return "123";
}
//当前fn函数开启了严格模式
  • 严格模式中的变化
'use strict'
num = 10
console.log(num)//严格模式后使用未声明的变量
‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐
‐‐‐‐‐‐‐
var num2 = 1;
delete num2;//严格模式不允许删除变量
‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐
‐‐‐‐‐‐‐
function fn() {
console.log(this); // 严格模式下全局作用域中函数中的 this 是 undefined
}
fn();
‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐
‐‐‐‐‐‐‐‐
function Star() {
this.sex = '男';
}
// Star();严格模式下,如果 构造函数不加new调用, this 指向的是undefined 如果给
他赋值则 会报错.
var ldh = new Star();
console.log(ldh.sex);
‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐
‐‐‐‐‐‐‐‐‐
setTimeout(function() {
console.log(this); //严格模式下,定时器 this 还是指向 window
}, 2000);
  • 高阶函数
    传递的是函数或者返回的是函数就是高阶函数
    在这里插入图片描述
  • 闭包
    –变量的作用域

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

  1. 函数内部可以使用全局变量。
  2. 函数外部不可以使用局部变量。
  3. 当函数执行完毕,本作用域内的局部变量会销毁。
  • 什么是闭包
    闭包指一个函数访问另一个函数中的局部变量
 <script>
        // 闭包(closure)指有权访问另一个函数作用域中变量的函数。
        // 闭包: 我们fun 这个函数作用域 访问了另外一个函数 fn 里面的局部变量 num
        function fn() {
            var num = 10;
            function fun() {
                console.log(num);
            }
            fun();
        }
        fn();
    </script>

闭包的作用
延伸了变量的作用范围、 延长了变量的生命周期、

function fn() {
var num = 10;
function fun() {
console.log(num);
}
return fun;
}
var f = fn();
f();
  • 利用闭包的方式得到当前li 的索引号
for (var i = 0; i < lis.length; i++) {
// 利用for循环创建了4个立即执行函数
// 立即执行函数也成为小闭包因为立即执行函数里面的任何一个函数都可以使用它的i这变

(function(i) {
lis[i].onclick = function() {
console.log(i);
}
})(i);
}
  • 闭包应用-3秒钟之后,打印所有li元素的内容
for (var i = 0; i < lis.length; i++) {
(function(i) {
setTimeout(function() {
console.log(lis[i].innerHTML);
}, 3000)
})(i);
}
  • 闭包应用-计算打车价格
/*需求分析
打车起步价13(3公里内), 之后每多一公里增加 5块钱. 用户输入公里数就可以计算打车
价格
如果有拥堵情况,总价格多收取10块钱拥堵费*/
var car = (function() {
var start = 13; // 起步价 局部变量
var total = 0; // 总价 局部变量
return {
// 正常的总价
price: function(n) {
if (n <= 3) {
total = start;
} else {
total = start + (n ‐ 3) * 5
}
return total;
},
// 拥堵之后的费用
yd: function(flag) {
return flag ? total + 10 : total;
}
}
})();
console.log(car.price(5)); // 23
console.log(car.yd(true)); // 33

思考题

var name = "The Window";
var object = {
name: "My Object",
getNameFunc: function() {
return function() {
return this.name;
};
}
};
console.log(object.getNameFunc()())
‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐
‐‐‐‐‐‐‐‐‐‐
var name = "The Window";
var object = {
name: "My Object",
getNameFunc: function() {
var that = this;
return function() {
return that.name;
};
}
};
console.log(object.getNameFunc()())
  • 递归
    – 什么是递归
    简单理解:函数内部自己调用自己, 这个函数就是递归函数
    作用:重复执行某段代码

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

//利用递归函数求1~n的阶乘 1 * 2 * 3 * 4 * ..n
function fn(n) {
if (n == 1) { //结束条件
return 1;
}
return n * fn(n ‐ 1);
}
console.log(fn(3));

原文链接:https://blog.csdn.net/qq_39206750/article/details/102945704

栏目分类
最近更新