函数声明与函数表达式

前端之家收集整理的这篇文章主要介绍了函数声明与函数表达式前端之家小编觉得挺不错的,现在分享给大家,也给大家做个参考。

函数声明与函数表达式

定义一个函数方法主要有三种 函数声明、函数表达式、new Function构造函数函数声明与函数表达式定义的函数较为常用,构造函数的方式可以将字符串定义为函数

函数声明

函数声明会将声明与赋值都提前,也就是整个函数体都会被提升到作用域顶部

s(); // 1
function s(){
    console.log(1);
}

也就是说,在某个作用域中定义的函数可以在这个作用域的任意位置调用,整个函数体都将被提前,当然也有不一样的情况:

console.log(s); // undefined // 函数的声明提升但是并未赋值函数体
console.log(ss); // Uncaught ReferenceError: ss is not defined // 打印未定义的ss是为了对比说明函数的声明提升
s(); // Uncaught TypeError: s is not a function
if(1){
    function s(){
        console.log(1);
    }
}

此处可以看到函数的声明被提升,但是函数体并未被提升,JS只有函数作用域与全局作用域以及ES6引入的letconst块级作用域,此处if不存在作用域的问题,为同一作用域,但是由于解释器在预处理期无法确定if里面的内容,所以只对函数声明的变量进行了提升,而并未将函数体赋值。

函数表达式

函数表达式只会提升变量的声明,本质上是变量提升并将一个匿名函数对象赋值给变量,

console.log(s); // undefined
var s = function s(){
    console.log(1);
}
console.log(s);  // f s(){console.log(1);}

在JS引擎的执行的优先级是 变量声明 函数声明 变量赋值

console.log(s); // ƒ s(){console.log(1);}
var s = function(){
    console.log(0);
}
function s(){
    console.log(1);
}
s(); // 0

new Function

new Function的方式可以将字符串解析为函数

var s = new Function("a","b","console.log(a,b);");
s(1,2); // 1,2
console.log(s.__proto__ === Function.prototype); //true
function ss(){} // 声明的函数都是Function的一个实例
console.log(ss.constructor === Function); // true
console.log(ss.__proto__ === Function.prototype); // true

new Functioneval也有所不同,其对解析内容的运行环境的判定有所不同

// eval中的代码执行时的作用域为当前作用域,它可以访问到函数中的局部变量,并沿着作用域链向上查找。
// new Function中的代码执行时的作用域为全局作用域,无法访问函数内的局部变量。
var a = 'Global Scope';
(function b(){
    var a = 'Local Scope';
    eval("console.log(a)"); //Local Scope
    (new Function("console.log(a)"))() //Global Scope
})();
原文链接:https://www.f2er.com/js/992910.html

猜你在找的JavaScript相关文章