js 函数和变量的提升
js 函数和变量的提升
1. 函数的作用域:
js中 ,函数的作用域为函数,而不是大括号。
var hei = 123;
if(true){
hei = 456;
}
console.log(hei);// 456;
var hei = 123;
if(true){
(function(){ var hei = 456;})();
}
console.log(hei); // 123
函数内部可以用用函数外部的变量,而函数外部的不可以用函数内部的变量(可以用闭包实现效果,随后总结)。
(function(){ var hei = 456;})(); 为函数自执行函数;有三种:
1) (function(){})();
2) (function(){}());
3) !function(){}();
2. 变量的提升:
var a = 1;
var b = 100;
function z(){
console.log(b); //100 //为什么b没有输出undefined ,这是因为后面没有var b = 99; 而是 b = 99;所以没有提升,他是一个全局变量。函数外也可以用。
console.log(a); //undefined
var a = 10; //所谓提升,就是将var a; 提升到函数体的第一句。就导致了 第二句输出undefined
console.log(a); //10
a = 4;
b = 99; // 如果变成var b = 99;函数外就不能用了 外面的输出就变成了 100. 前面的输出就变成了undefined,因为变量提升。
console.log(a); //4
console.log(b); //99
}
z();
console.log(b); //99
if(false){
var i = 10;
}
console.log(i); //为什是undefined ,也是变量提升。
3.函数提升
首先要明确两点:
<1> 只有函数声明才会进行函数提升
<2> 函数提升会将函数体一起提升上去,这点与变量提升有所不同
下面来证明函数表达式不能进行函数提升:
~function() {
alert(typeof next); // undefined
~function next() {
alert(typeof next); // function
}()
}()
函数前面加个~的目的是将函数声明变成函数表达式,实际上也可以加其它运算符,比如+,-,!等,总之这个函数声明被变成了函数表达式。
从打印结果来看第一个alert出的是undefined,说明next根本没有发生函数提升。
下面来接着验证:
a();// 123
var a = function(){
console.log(321);
}
a();// 321
function a(){
console.log(123);
}
从结果可以看出,先打印出来的反而是放在后面的a(),上面代码的等价表示如下: var a = function a(){
console.log(123);
}
a();
a = function(){
console.log(321);
}
a(); 都可以证明表达式不提升,而函数提升。 4.那么如果当变量提升与函数提升同时发生的时候,哪个的优先级更高呢?我们来做个实验:
console.log(ggg); // function ggg(){}
var ggg = 222;
function ggg(){};
console.log(ggg); // 222
console.log(ggg); // function ggg(){}
function ggg(){};
var ggg = 111;
console.log(ggg); //111
function ggg(){};
var ggg;
console.log(ggg); // function ggg(){}
由对上述代码的分析:可以总结出如下规律:(大神博客的总结,看了之后果然清楚了很多)
1)变量声明提升:变量申明在进入执行上下文就完成了。
只要变量在代码中进行了声明,无论它在哪个位置上进行声明, js引擎都会将它的声明放在范围作用域的顶部;
2)函数声明提升:执行代码之前会先读取函数声明,意味着可以把函数申明放在调用它的语句后面。
只要函数在代码中进行了声明,无论它在哪个位置上进行声明, js引擎都会将它的声明放在范围作用域的顶部;
3)变量or函数声明:函数声明会覆盖变量声明,但不会覆盖变量赋值。
同一个名称标识a,即有变量声明var a,又有函数声明function a() {},不管二者声明的顺序,函数声明会覆盖变量声明,也就是说,此时a的值是声明的函数function a() {}。注意:如果在变量声明的同时初始化a,或是之后对a进行赋值,此时a的值变量的值。eg: var a; var c = 1; a = 1; function a() { return true; } console.log(a); //1
**********************************************
接下来会有些 头疼 想了好长好长时间 /(ㄒoㄒ)/~~ var zzz = 222;
function zzz(){
console.log(111);
}
console.log(zzz); // 111
**********************************************
var zzz;
function zzz(){
console.log(111);
}
console.log(zzz); // function zzz(){console.log(111);}
console.log(zzz()); //111 , undefined
************************************************
B = 100;
function B(){
B = 2;
console.log(B);
}
B(); // B is not a function 由于函数提升,所以带着函数体在 B = 100;之前所以B是一个变量,不是函数
************************************************
B = 100;
var B = function(){
B = 2;
console.log(B);
}
B(); //2 由于表达式不提升,所以输出B = 2; 然后我好奇为什么B不输出自己本身的函数,所以把B = 2;改成了 x = 2;然后输出了 function(){ x = 2; console.log(B);}
****************************************************
在大神的博客上看到的小习题:
var a = 1;
function b() {
console.log(a);
a = 10;
function a() {}
}
b();// ?
console.log(a);// ?
我的答案: undefined ,1
运行后的结果: function a(){} ,1 //我的天啊 ,又忘记考虑b函数里a函数的提升了并且覆盖了没赋值的a a = 10;
(function a(){
a = 1;
console.log(a);// ?
})(); 我的答案: 1
运行后结果: function a(){ a = 1; console.log(a);} // 这里自执行函数,首先他是一个表达式,他不会提升,同时声明函数和变量,以函数为主,返回函数
******************************************************
function a(i) {
console.log(i);// ?
var i = 1;
console.log(i);// ?
};
a(10);
我的答案: 10 , 1
运行后结果: 10 , 1 呵呵呵 我终于对一个了。
js 函数和变量的提升的更多相关文章
- JS函数和变量
JS函数和变量 函数: 函数是由事件或者当它被调用时执行的可重复使用的代码块. 是一个独立的代码块,实现特定功能模块. 函数他不进行调用触发的话,不会自己主动执行. 像ATM机一样,不去取钱的话不会 ...
- js函数和变量的执行顺序【易错】
js函数和变量的声明与执行顺序 一.函数执行顺序 1.正常顺序 function f(){ alert(2); } f(); //alert 2 所有浏览器都能测试通过. 2.倒序调用 f(); // ...
- js函数、变量提升(hoisting)
其实我只是想复习下变量提升的,然后看到了函数提升,然后再看到了函数声明.函数表达式. 有必要怀着敬仰之心提及园子里的TOM大叔的解密命名函数表达式,不愧是大叔,好好地脑补了下基础知识. 在ECMASc ...
- js函数和变量的声明与执行顺序
一.函数执行顺序 1.正常顺序 function f(){ alert(2); } f(); //alert 2 所有浏览器都能测试通过. 2.倒序调用 f(); //alert 2 function ...
- JS函数和变量名称冲突
在JS中如果函数名与变量名冲突,JS是怎么执行的? <script> console.log(sum);//function sum(){} function sum(){} var su ...
- [转]js 判断js函数、变量是否存在
本文转自:http://blog.csdn.net/liang4571231/article/details/4042519 在进行js编程时,总会出现可能一些函数或者变量未定义而被引用,导致报错的情 ...
- js函数与变量同名
console.log(a); var a = 3; function a(){} 输出的结果是:[Function: a] 注意一下几点就能知道原因了! 1)函数声明会置顶2)变量声明也会置顶3)函 ...
- js 判断js函数、变量是否存在 JS保存和删除cookie操作,判断cookie是否存在的方法
//是否存在指定函数 function isExitsFunction(funcName) { try { if (typeof(eval(funcName)) == " ...
- JS函数、变量作用域
函数参数 函数的()中指定一个或多个形参(形式参数),多个形参之间用,号隔开,声明形参相当于在函数内部声明了对应的变量,但不赋值.在调用时在()中指定实参 调用时解析器不会检查实参类型.数量,实参可 ...
随机推荐
- 《BI那点儿事》运用标准计分和离差——分析三国超一流统帅综合实力排名 绝对客观,数据说话
数据分析基础概念:标准计分: 1.无论作为变量的满分为几分,其标准计分的平均数势必为0,而其标准差势必为1.2.无论作为变量的单位是什么,其标准计分的平均数势必为0,而其标准差势必为1.公式为: 离差 ...
- (原创)Windows和Linux间共享文件
方法一: Windows创建目录sharedir,修改共享属性,对everyone开放读写权限. Linux下运行命令:# mount -t cifs //192.168.8.55/sharedir ...
- fifter常见的运用场景
没配置过滤器 package servlet; import java.io.IOException; import javax.servlet.ServletException; import ja ...
- VLAN
VLAN VLAN技术要点主要有两点: 1.支持VLAN的交换机的内部交换原理: 2.设备之间(交换机之间,交换机与路由器之间,交换机与主机之间)交互时,VLAN TAG的添加和移除. VLAN通信 ...
- MultiDex到底有多坑
google为什么要引入MultiDex? dex指令是用16位寄存器来保存dex中的方法数,所以限制了在apk 中最大的方法数为65535,当超过这个最大值在编译的时候会报 方法数超标的错误. 如何 ...
- HTML中的target(_self,_blank)用法总结
HTML中的target(_self,_blank)用法总结 最近一个项目,多次遇到target='_self', target='_blank'的用法, 再次总结一下: 1.<a>标签 ...
- Hibernate实现向数据库插入一条数据全过程(Study By Example)
1.数据库(直接在cmd下进入数据库操作亦可) (1)启动Navicat for MySQL (2)打开连接,创建一个数据库,名为testdb (3)新建表user1,表结构如图所示 2.数据库池 ( ...
- spring mvc拦截器和<mvc:annotation-driven />的详解
MVC的拦截器 经本人在Spring mvc中对方案1和方案2的测试表明,并没有拦截静态资源,所以可以放心使用方案1和方案2,方案3可以放弃,并且可以放心使用<mvc:annotation-dr ...
- Android开发--Intent的应用
1.概述 Intent负责对应用中一次操作的动作,动作涉及的数据,附加的数据进行描述,起到媒介的作用.通过Intent对象指定一个activity,利用startActivity或 startActi ...
- mysql 删除重复数据保留一条
验证:mysql 5.6版本 方法一: delete a from table a left join( select (id) from table group by studentName,cla ...