函数声明与函数表达式
时间:2022-07-24
本文章向大家介绍函数声明与函数表达式,主要内容包括其使用实例、应用技巧、基本知识点总结和需要注意事项,具有一定的参考价值,需要的朋友可以参考一下。
函数声明与函数表达式
定义一个函数的方法主要有三种 函数声明、函数表达式、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
引入的let
和const
块级作用域,此处if
不存在作用域的问题,为同一作用域,但是由于解释器在预处理期无法确定if
里面的内容,所以只对函数声明的变量进行了提升,而并未将函数体赋值。
函数表达式
函数表达式只会提升变量的声明,本质上是变量提升并将一个匿名函数对象赋值给变量。
console.log(s); // undefined
var s = function s(){
console.log(1);
}
console.log(s); // f s(){console.log(1);}
由此来看,直接进行函数声明与函数表达式声明的函数之间就存在一个优先级关系。
var s = function(){
console.log(0);
}
function s(){
console.log(1);
}
s(); // 0
在JS
中函数是第一等公民,在《你不知道的JavaScript
》(上卷)一书的第40
页中写到,函数会首先被提升,然后才是变量。也就是说,同一作用域下提升,函数会在更前面。即在JS
引擎的执行的优先级是函数声明、变量声明、变量赋值。
function s(){ //函数声明
console.log(1);
}
var s; // 变量声明
// 函数已声明`a` 相同的变量名`var`声明会被直接忽略
console.log(s); // f s(){...}
s = function(){ // 变量赋值
console.log(0);
}
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 Function
与eval
也有所不同,其对解析内容的运行环境的判定有所不同。
// 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://github.com/WindrunnerMax/EveryDay
参考
https://www.cnblogs.com/echolun/p/7612142.html
https://www.cnblogs.com/miacara94/p/9173843.html
https://blog.csdn.net/qq_41893551/article/details/83011752
- Angularjs基础(七)
- WordPress 中八个有用的代码片段
- 【释疑文】DeveMobile、EaseMobile 及Devework 主题的区别
- DeveMobile/EaseMobile 主题双双更新1.1,增加离线存储,社交媒体关注等功能
- Angularjs基础(六)
- 如果机器人拥有痛觉,这个世界会怎样
- 阻止iOS Web APP中点击链接跳转到Safari 浏览器新标签页
- 专门攻击工资支付系统的网络犯罪
- Angularjs基础(五)
- DW Replace Open Sans:将WordPress 后台中的open-sans字体加载源从Google Fonts换为360 CDN
- Google Fonts 已可正常访问,相关插件可卸
- 微信支付宝完成这几个设置,别人偷不走你一毛钱!
- Angularjs基础(四)
- Google Fonts导致WordPress 速度问题的三个解决方案
- JavaScript 教程
- JavaScript 编辑工具
- JavaScript 与HTML
- JavaScript 与Java
- JavaScript 数据结构
- JavaScript 基本数据类型
- JavaScript 特殊数据类型
- JavaScript 运算符
- JavaScript typeof 运算符
- JavaScript 表达式
- JavaScript 类型转换
- JavaScript 基本语法
- JavaScript 注释
- Javascript 基本处理流程
- Javascript 选择结构
- Javascript if 语句
- Javascript if 语句的嵌套
- Javascript switch 语句
- Javascript 循环结构
- Javascript 循环结构实例
- Javascript 跳转语句
- Javascript 控制语句总结
- Javascript 函数介绍
- Javascript 函数的定义
- Javascript 函数调用
- Javascript 几种特殊的函数
- JavaScript 内置函数简介
- Javascript eval() 函数
- Javascript isFinite() 函数
- Javascript isNaN() 函数
- parseInt() 与 parseFloat()
- escape() 与 unescape()
- Javascript 字符串介绍
- Javascript length属性
- javascript 字符串函数
- Javascript 日期对象简介
- Javascript 日期对象用途
- Date 对象属性和方法
- Javascript 数组是什么
- Javascript 创建数组
- Javascript 数组赋值与取值
- Javascript 数组属性和方法
- 【C++】勉强能看的线程池详解
- 国密SSL协议之Java编程
- 7. Jackson用树模型处理JSON是必备技能,不信你看
- epoll,求知者离我近点
- SOCKET网络编程 (通俗易懂入门篇)
- 进程 · 全家桶
- Posix线程 它们那一大家子事儿,要觉得好你就收藏进被窝慢慢看(2)
- Posix线程 它们那一大家子事儿,要觉得好你就收藏进被窝里慢慢看 (1)
- 种树:二叉树、二叉搜索树、AVL树、红黑树、哈夫曼树、B树、树与森林
- 【Linux内核】进程管理
- Django后台管理界面修改(代码修改)
- OpsnSSH抓包分析 | SSH协议分析
- 搭建简易的物联网服务端和客户端-第三次增补(二十二)
- ReentrantLock源码解析
- Nodejs连接PostgreSQL