js提升机制(hoisting)

这是我申请博客园写的第一篇文章,想把这两天学习的关于js的变量和函数提升机制(hoisting)记录下来。

从网上看到这么一段代码:

 var c = 2;

 function c(){

  c = 22;

  console.log("c="+c);

}

c();//会报错,变量提升机制导致的(c is not a function)

问运行结果是什么,然后不假思索的就以为是22,因为c=22这行看起来就是对外面的全局变量c重新定义了

但是实际上不是的,这句话不会执行到c()的时候会报错(number is not a function),有点蒙蔽,这是怎么了,查了好久,才知道js有个提升机制,变量和函数(函数声明的方式有提升机制,函数表达式没有这个机制)都有提升机制,而且函数提升机制的优先级高于变量的,这也就是说当函数名和变量名相同的时候,拿上面这个例子来说,c被提升到代码最前端,并且被赋值为一个函数,然后才会 被赋值为2,上面的代码等效于下面这个:

var c = function c(){

  c = 22;

  console.log("c="+c);

};

c = 2;

c();

执行的时候,c先被赋值为一个函数,然后紧接着又被赋值为数字2,这样在这句赋值语句下面执行c()的时候,c就不是函数了,而是数字,如果在c = 2;这句话的上面执行c()的话,就没有问题了,结果是c = 22;

再来看另一个问题,函数声明和函数表达式有什么不同,就是下面这两种情况:

d();//1

function d(){//方式1

  alert("1");

}

d();//undefined is not a function

var d = function(){//方式2

  alert("1");

};

这两种声明函数方式不同之一在于:

方式1可以在d声明之前使用d()来调用函数,方式2却不可以

这个也是可以用变量提升机制来解释的,方式1的写法和下面这个等价:

var d = function d(){

  alert("1");

};

d();

所以执行没有问题,但是第二种写法的函数就没有变量提升机制,好像也可以用这个方式来解释,第二种写法等价于下面这样:

var d;

d();

d = function(){

  alert("1")

};

这样的话,执行d()的时候,d还没有被定义为函数,只是被声明了,所以会执行报错。(这样应该可以解释的通,不对的地方,请务必让我知道)

来看个复杂点的例子:

var a = 1;

function b() {        //变量提升机制:如这个例子所示,执行b()时

  console.log(a);   // function a(){}

  a = 10; //这可不是对外面的全局变量a定义哦

  console.log(a); //10(局部变量)

  var a = 11;

  console.log(a); //11(局部变量)

  return;

  function a(){

    alert("abc");

  }

}

b();

console.log(a); //1(全局变量)

上面的例子等价于下面这样:

var b = function b(){

  var a = function a(){

    alert("abc");

  }

  console.log(a);

  a = 10;

  console.log(a);

  a = 11;

  console.log(a);

  return;

}

var a;

a = 1;

b();

console.log(a);

不知道写的这点东西对大家有没有一点帮助呢?

时间: 2024-11-03 22:36:06

js提升机制(hoisting)的相关文章

JavaScript的作用域和提升机制

你知道下面的JavaScript代码执行时会输出什么吗? var foo = 1; function bar() { if (!foo) { var foo = 10; } alert(foo); } bar(); 答案是"10",吃惊吗?那么下面的可能会真的让你大吃一惊: var a = 1; function b() { a = 10; return; function a() {} } b(); alert(a); 这里浏览器会弹出"1".怎么回事?这似乎看起

JavaScript中的各种变量提升(Hoisting)

首先纠正下,文章标题里的 “变量提升” 名词是随大流叫法,“变量提升” 改为 “标识符提升” 更准确.因为变量一般指使用 var 声明的标识符,JS 里使用 function 声明的标识符也存在提升(Hoisting). JS 存在变量提升(Hoisting),这个的设计其实是低劣的,它允许变量不声明就可以访问,或声明在后使用在前.新手对于此则很迷惑,甚至许多使用JS多年老手也比较迷惑.但在 ES6 加入 let/const 后,变量Hoisting 就不存在了. 一. 变量未声明,直接使用 f

JS Scoping and Hoisting

参考了这篇文章 http://www.jb51.net/article/30719.htm var v='Hello World'; (function(){ console.log(v); })() 输出: Hello World 但是 var v='Hello World'; (function(){ console.log(v); var v = 'hi'; })() 输出: undefined 这里面隐藏了一个陷阱-----JavaScript中的变量提升(Hoisting).在JS中,

函数声明提升机制在浏览器中的bug

JavaScript 解释器中存在一种变量声明被提升(hoisting)的机制,也就是说变量(函数)的声明会被提升到作用域的最前面,即使写代码的时候是写在最后面,也还是会被提升至最前面. 但通过测试,发现该机制在浏览期间存在差异:

JavaScript 中的执行环境、作用域(scope)以及变量提升(hoisting)

先看下面一段代码: var a = 0; alert("1st alert : a = " + a); function fun(){ alert("2nd alert : a = " + a); var a = 1; setTimeout(function(){ alert("3rd alert : a = " + a); a = 2; },1000); a = 3; setTimeout(function(){ alert("4th

从浏览器多进程到JS单线程,JS运行机制最全面的一次梳理(转)

前言 见解有限,如有描述不当之处,请帮忙及时指出,如有错误,会及时修正. ----超长文+多图预警,需要花费不少时间.---- 如果看完本文后,还对进程线程傻傻分不清,不清楚浏览器多进程.浏览器内核多线程.JS单线程.JS运行机制的区别.那么请回复我,一定是我写的还不够清晰,我来改... ----正文开始---- 最近发现有不少介绍JS单线程运行机制的文章,但是发现很多都仅仅是介绍某一部分的知识,而且各个地方的说法还不统一,容易造成困惑. 因此准备梳理这块知识点,结合已有的认知,基于网上的大量参

JS预处理机制

IE中界面加载顺序为从上往下加载..同步加载..如 一个界面 70多个请求的情况下. 导致页面加载及其慢. JS预处理机制: 大概原理: 用XMLHTTP取得脚本的内容,再创建Script对象,另外注意编码保持一致,因为服务器和XML使用UTF8的编码传送数据.类似于预报加载这些js脚本文件.界面上尽量不要出现没有必要引用的js文件,减缓页面加载速度不说,还容易出现js错误.      实现方式: 1-3种方法是异步的,基本上都在一个主界面(需优化的界面上采取,动态写,改,生成一个script脚

Atitit. Java script 多重多重catch语句的实现and Javascript js 异常机制

Atitit. Java script 多重多重catch语句的实现and Javascript js 异常机制 1. 语法错误(ERROR)和运行期错误(Exception) 1 2. 错误类型判断 二种方法: 1 3. 我们常接触到的异常包括: 2 4. ------代码 2 5. 参考 4 1. 语法错误(ERROR)和运行期错误(Exception) Javascript提供了两种特殊的错误处理方式 BOM包含一个onerror事件处理函数,这个window对象与图像对象上都有 同时EC

node.js零基础详细教程(4):node.js事件机制、node异步IO操作

第四章 建议学习时间3小时  课程共10章 学习方式:详细阅读,并手动实现相关代码 学习目标:此教程将教会大家 安装Node.搭建服务器.express.mysql.mongodb.编写后台业务逻辑.编写接口,最后完成一个完整的项目后台,预计共10天课程. node.js事件机制 node.js是单线程,但是通过事件和回调支持并发,可以实现非常高的性能. node.js所有的API都是通过异步调用.第一堂课的时候,我们写过一个同步和异步的示例(如下),当初说到:同步代码先执行完成,然后才执行异步