JavaScript 函数的两种声明方式
1.函数声明的方式
JavaScript声明函数有两种选择:函数声明法,表达式定义法。
函数声明法
function sum (num1 ,num2){
return num1+num2
}表达式定义法
var sum = function(num1,num2){
return num1+num2
};
2.扒一扒两种函数声明的区别
解析器会率先读取函数声明(也就是说函数声明的优先级较高),并使其在执行任何代码之前可以访问(将函数声明提升到代码树顶部);至于函数表达式声明,则必须等到解析器执行到它所在的代码行,才会执行,无法自动提升。
同样的函数使用不同的定义方式,调用的时候会产生不同的效果。
// 函数声明法
var num = add(1, 2);
console.log(num);// 3
function add(a, b) {
return a + b
}
// 函数表达式声明
var num = add(1, 2);
console.log(num);//Uncaught TypeError: undefined is not a function
var add = function (a, b) {
return a + b
}
我们来看一看这两种声明方式到底对代码产生了怎样的影响。
首先看函数声明,由于发生了代码提升,实际的代码如下
// 函数声明法
function add(a, b) {
return a + b
}
var num = add(1, 2);
console.log(num);// 3
//function add(a, b) {
// return a + b
//}
再看表达式声明法,同样将变量add提升,add()函数调用的时候,只声明了变量add,却没有进行赋值。(此时的add变量是undefined)实际的代码如下。
// 函数表达式声明
var add;
var num = add(1, 2);
console.log(num);//Uncaught TypeError: undefined is not a function
add = function (a, b) {
return a + b
}
3.关于变量提升和执行顺序
JavaScript是解释型语言,但它并不是逐行执行的。解析过程可以理解为两个阶段:一个是预处理阶段,JavaScript将脚本代码转换为字节码,该过程中将所有定义的变量提升到代码树顶端;第二个阶段,JavaScript解释器借助执行环境,把字节码生成机械码,该过程中才发生变量的赋值,并顺序执行。
console.log(a);
//Error:a is not defined ,直接报错,下面语句没法执行,以下结果为注释该句后结果
console.log(b) //undefined ,变量发生提升
var b="Test";
console.log(b);//Test
也就说JavaScript值执行第一句语句之前就已经将函数/变量声明预处理了
var b="Test" 相当于两个语句
var b;(undefined结果的来源,在执行第一句语句之前已经解析)
b=”Test”(这句是顺序执行的,在第二句之后执行)
这也是为什么我们可以在方法声明语句之前就调用方法的原因。
4.练一练
下面我们用一个经典的面试题目的一部分来对本篇文章进行总结
请问下面这段代码的执行结果是什么?
function Foo() {
getName = function () {
alert (1);
};
return this;
}
Foo.getName = function () {
alert (2);
};
Foo.prototype.getName = function () {
alert (3);
};
var getName = function () {
alert (4);
};
function getName() {
alert (5);
}
getName()
答案加载中...
答案加载中...
答案加载中...
答案加载中...
答案加载中...
答案加载中...
答案加载中...
答案加载中...
答案加载中...
答案加载中...
答案加载中...
答案加载中...
答案加载中...
答案加载中...
揭晓答案:
4
这里我主要讲解一下第二问中为什么是4,其他的在后续文章中进行说明。上面的代码实际上是这个样子滴
function Foo() {
getName = function () {
alert (1);
};
return this;
}
var getName;//只提升变量声明
function getName() { //提升函数声明,覆盖var的声明
alert (5);
}
Foo.getName = function () {
alert (2);
};
Foo.prototype.getName = function () {
alert (3);
};
getName = function () { //最终的赋值再次覆盖function getName声明
alert (4);
};
getName();//最终输出4
JavaScript 函数的两种声明方式的更多相关文章
- JavaScript脚本的两种放置方式
JavaScript脚本的两种放置方式 1在body里用 script标签引用 2 直接写在<script></script>标签之中
- 第63天:json的两种声明方式
一. json 两种声明方式 1. 对象声明 var json = {width:100,height:100} 2. 数组声明 var man = [ // 数组的 js ...
- javascript中对象两种创建方式
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8&quo ...
- javascript 函数的4种调用方式与 this(上下文)的指向
前言:这是笔者学习之后自己的理解与整理.如果有错误或者疑问的地方,请大家指正,我会持续更新! javascript中作用域链和this(上下文)的指向是很容易混淆的,简单的说就是: 作用域链取决于函数 ...
- 第十篇----------javascript函数的三种定义方式及区别
javascript定义函数有3种方式: //3种函数定义方式,前两种常用 /** * 1,function 语句式 * 形式:句子 * 名称:有名 * 性质:静态 * 解析时机:优先解析 * 作用域 ...
- javascript 函数的几种声明函数以及应用环境
本页只列出常用的几种方式,当然还有比如new Function()以及下面三种的组合. 1.函数式声明 例子:function sum(a,b){ return a+b; }; 2.函数表达式声明(匿 ...
- javascript函数的4种调用方式
在javascript中一共有4种函数调用模式,分别是:方法调用模式.函数调用模式.构造函数调用模式和apply(call)调用模式,这4种模式的主要差异在于如何初始化关键参数this. 方法调用模式 ...
- js的数据类型、函数、流程控制及变量的四种声明方式
运算符 基本运算符 加 + 减 - 乘 * 除 / 取余 % 自增 ++ eg: 1++ 或 ++1 自减 -- eg: 1-- 或 --1 注:++或--写在前面表示优先级最高,先进行自增或者自减 ...
- JavaScript 函数的4种调用方法
JavaScript 函数有 4 种调用方式. 每种方式的不同方式在于 this 的初始化. 作为一个函数调用 function myFunction(a, b) { return a * b; } ...
随机推荐
- hoops暂时用过的一些方法
(中文全部为谷歌翻译) HC_EXTERNAL void HC_CDECL HC_Show_Shell HC_PROTO ((HC_KEY, int *, HC_POINT *, int *, int ...
- startssl申请配置免费https证书
之前给业务配置都是在沃通上申请免费证书,而后通过反向代理层的Nginx进行https认证. 今天来了个新需求,要求域名直接解析至阿里云SLB.https配置需要通过阿里云的控制台部署这倒无所谓,只是在 ...
- 图片采用base64压缩,可以以字符串的形式传送base64给服务端转存为图片
(function () { var coverImage = document.querySelector('<div id="coverImage">file< ...
- vim 插件之 gist.vim 的安装
用 IntelliJ 的时觉得 create gist 很好用,查了下,发现 vim 下也有这个插件,于是马上配置上. 安装 下载 Gist.vim 解压后进入目录,拷贝文件 cp plugin/gi ...
- swift 上手
学习swift的笔记,偶尔会更新一下 变量与常量 变量定义使用var,常量使用let,类型安全,有自动类型推导,注意赋值的=号两边必须有空格. 变量和常量名是可以几乎所有字符,这些都非常像javasc ...
- 深入理解JavaScript中 fn() 和 return fn() 的区别
在js中,经常会遇到在函数里调用其它函数的情况,这时候会有 fn() 这种调用方式,还有一种是 return fn() 这种调用方式,一些初学者经常会一脸萌逼地被这两种方式给绕晕了.这里用一个优雅的面 ...
- sublime 安装 插件
从菜单 View - Show Console 或者 ctrl + ~ 快捷键,调出 console.将以下 Python 代码粘贴进去并 enter 执行,不出意外即完成安装.以下提供 ST3 和 ...
- spring静态代理
一.代理概念 为某个对象提供一个代理,以控制对这个对象的访问. 代理类和委托类有共同的父类或父接口,这样在任何使用委托类对象的地方都可以用代理对象替代.代理类负责请求的预处理.过滤.将请求分派给委托类 ...
- grunt-connect-proxy解决开发时跨域问题
最近的项目中前后端是完全分离开发的,前端用grunt管理项目.这样就会导致一个问题:开发时前端调用后台的接口时因为不在一个服务器,所以会出现跨域问题.但是也不能用JSONP或CROS方式实现真正的跨域 ...
- [WPF] 我的WPF自学日记2,自定义入口
在winform中入口文件就是Program.cs,而在WPF中看不到,因为它是自动生成的,可以说隐藏了,我们可以自定义一个入口文件,然后修改项目属性中的启动对象为我们自定义的入口文件. 首先新建入口 ...