首页 > 其他 > 详细

函数声明与函数表达式

时间:2020-03-24 15:01:26      阅读:55      评论:0      收藏:0      [点我收藏+]

函数声明与函数表达式

定义一个函数的方法主要有三种 函数声明、函数表达式、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.cnblogs.com/WindrunnerMax/p/12558458.html

(0)
(0)
   
举报
评论 一句话评论(0
关于我们 - 联系我们 - 留言反馈 - 联系我们:wmxa8@hotmail.com
© 2014 bubuko.com 版权所有
打开技术之扣,分享程序人生!