javascript——函数

蓝咒 提交于 2019-12-22 05:43:24

函数的定义和调用

函数定义

1.函数声明方式,使用function关键字,声明命名函数

function fn(){};

2.函数表达式定义匿名函数

var func=function(){};

3.new Function(‘参数1’,‘参数2’,‘函数体’),参数和函数体要以字符串方式书写,执行效率低,书写麻烦,使用较少,所有函数都是Function的实例对象,函数属于对象

var func=new Function('a','b','console.log(a+b)');

函数调用

1.普通函数

function fn(){
    console.log('人生巅峰');
}
//调用
f();//fn.call()

2.对方的方法

var 0bj={
    sayHi:function(){
         console.log('人生巅峰');
    }
}
//调用
obj.sayHi();

3.构造函数

function Star(){};
//调用
new Star();

4.绑定事件函数

btn.onclick=function(){};
    //调用
//点击按钮就会调用

5.定时器函数

setInterval(function(){},1000);
//定时器自己每隔一定时间自动调用

6.立即执行函数

(function(){
     console.log('人生巅峰');
})();
//立即执行函数自动调用

this

函数内this的指向

函数不同调用方式决定了this的指向不同

1.普通函数的this指向window

2.对象的方法中this指向方法的调用者

3.构造函数的this指向实例对象,原型对象中的this也指向实例对象

4.绑定事件函数的this指向函数的调用者

5.定时器函数的this指向的是window

6.立即执行函数的this指向的是window

改变函数内部this指向

js专门提供了一些函数来处理函数内部this指向问题

1.call()

call()方法简单理解为调用函数的方式,但可以改变this的指向,主要用于实现继承

语法:func.call(thisArg,arg1,arg2,…)

thisArg:在函数运行时指定的this值

arg1,arg2:传递的其他参数

var obj={
    name:'Tom'
}
function fn(a,b){
    console.log(this);
     console.log(a+b);
};
fn.call(obj,1,2);

2.apply()

apply()方法也是调用函数的方式,也能改变this的指向,与call不同的是参数不同,主要用于处理数组相关

语法:func.apply(thisArg,[argsArray])

thisArg:在函数运行时指定的this值

argsArray:传递的值,必须包含在数组中

返回值就是函数的返回值

var obj={
    name:'Tom'
}
function fn(arr){
    console.log(this);
    console.log(arr);
};
fn.apply(obj,['blue']);

//apply()应用,EG:求数组的最大值
var arr=[1,2,33,99.100];
var max=Math.max.apply(Math,arr);
console.log(max);

3.bind()

bind()方法不会调用函数,但可以改变this的指向,主用于不需要立即调用函数,但又要改变this指向的场景

语法::func.call(thisArg,arg1,arg2,…)

thisArg:在函数运行时指定的this值

arg1,arg2:传递的其他参数

返回的是原函数改变this之后产生的新函数,即返回值是函数

var obj={
    name:'Tom'
}
function fn(a,b){
    console.log(this);
    console.log(a+b);
};
var f=fn.bind(obj,1,2);
f();

//应用举例:点击按钮后禁用,5秒钟后开启
var btn=document.querySelector('button');
btn.onclick=function(){
    this.disabled=true;//this指向的是按钮
    setTimeout(function(){
        this.disabled=false;//定时器this指向的是window,但此时this指向btn
    }.bind(this),5000);//this指向的btn对象
}

严格模式

概述

javascript除了提供正常模式外还提供了严格模式(strict mode)

ES5的严格模式是采用具有限制性avascript变体的一种方式,即在严格的条件下运行代码

严格模式在IE10以上版本才支持,旧浏览器会忽略

严格模式对正常js的语义做的改变:

1.消除js语法的一些不合理、不严谨地方,减少了一些怪异行为

2.消除代码运行的一些不安全之处

3.提高了编译效率,增加运行速度

4.禁用了在ECMAScript的未来版本中可能会定义的一些语法,为新版本做铺垫。比如一些保留字不能做变量名

开启严格模式

严格模式可以应用到整个脚本或个别函数,因此分为为脚本开启严格模式为函数开启严格模式

1.脚本开启严格模式

<script>
'use strict';//开启脚本严格模式,下面的js代码按严格,模式执行
</script>
<!--或者-->
<script>
    (function(){
        'use strict';
    })();
</script>

2.为函数开启严格模式

给某个函数开启严格模式,把’use strict’;声明放在函数体所有语句之前

function fn(){
    'use strict';//下面代码按照严格模式运行
}
function fun(){
    //里面的代码按照普通模运行
}

严格模式中的变化

1.变量规定

正常模式下,变量没声明,默认全局变量。严格模式下,必须先声明后使用

禁止删除已经声明的变量,如,delete x是错误语法

2.严格模式下this指向问题

正常模式下全局作用域函数的this指向Window对象。严格模式下,全局作用域函数的this指向undefined

正常模式下构造函数不加new可以当普通函数,this指向全局对象。严格模式下,this指向会报错,加new后可以

定时器中的this没有变化

事件、对象还是指向调用者

3.函数变化

严格模式下,函数中不能有重名参数

函数声明必须放在顶层,ES6中引入了块级作用域。不允许在非函数的代码块内声明函数

更多严格模式要求可以参考:MDN:https://developer.mozilla.org

高阶函数

高阶函数就是对其他函数进行操作的函数

高阶函数接收函数作为参数或者把函数作为返回值输出

函数是数据类型,可以作为参数传递给另一参数使用,最典型的例子是回调函数

// 高阶函数,把函数作为参数,典型回调函数
        function fn(a, b, callback) {
            console.log(a + b);
            callback && callback();
        }
        fn(1, 3, function() {
            console.log('函数作为参数');
        })

闭包

变量作用域

变量根据作用域分为全局变量和局部变量

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

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

函数执行完毕,函数作用域内的局部变量会销毁

闭包

闭包是指有权访问另一函数作用域中变量的函数

简单来说就是一个作用域可以访问另一个函数内部的局部变量

//fun内部作用域访问fn内部的局部变量
function fn() {
            //fn是闭包函数
            var num = 1;

            function fun() {
                // 函数fun访问了函数fn的局部变量
                console.log(num);
            }
            fun();
        }
        fn();



//fu外部作用域访问fn内部的局部变量
function fn() {
            //fn是闭包函数
            var num = 1;

            /*function fun() {
                // 函数fun访问了函数fn的局部变量
                console.log(num);
            }
            return fun;*/
   			 //返回匿名函数
    		return function(){
                console.log(num);
            }
        }
      /*  var f=fn();//类似于var f=function fun(){ console.log(num);}*/
		var f=fn();//类似于var f=function (){ console.log(num);}
		f();

闭包的作用:延升变量的作用范围

递归

一个函数内部可以调用自身,这个函数就是递归函数

递归函数的作用和循环效果一样

递归容易发生栈溢出问题,要加退出条件

 var i = 1;

        function fn() {
            console.log('递归');
            if (i == 3) {
                return;
            }
            i++;
            fn();
        }
        fn();

浅拷贝和深拷贝

浅拷贝只拷贝一层,更深层对象级别只拷贝引用

深拷贝拷贝多层,每一级别的数据都会拷贝

ES6增加了浅拷贝方法:Object.assign(target,…sources)

//浅拷贝
var obj = {
            id: 1,
            name: 'Tom',
            msg: {
                age: 19
            }
        }
        var o = {};
        Object.assign(o, obj);
        console.log(o);
//深拷贝
 var obj = {
            id: 1,
            name: 'Tom',
            msg: {
                age: 19
            },
            love: ['sing', 'cook']
        }
        var o = {};
        // 深拷贝,递归实现
        function deepCopy(newObj, oldObj) {
            for (var k in oldObj) {
                // 判断属性值类型
                // 获取属性值
                var item = oldObj[k];
                // 判断值是否为数组
                if (item instanceof Array) {
                    newObj[k] = [];
                    deepCopy(newObj[k], item);
                } else if (item instanceof Object) {
                    // 判断值是否为对象
                    newObj[k] = {};
                    deepCopy(newObj[k], item);
                } else {
                    // 属性值是否为简单数据类型
                    newObj[k] = item;
                }
            }
        }
        deepCopy(o, obj);
        console.log(o);
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!