javascript 变量/函数 提升

1.JavaScript hoisting(变量/函数 提升)

以下实验都是通过firefox的Console做的实验.

console.log(a);

ReferenceError: a is not defined

console.log(a);

但是,如果在后面加上变量的定义的话,结果将会变得不同.

console.log(a);

var a = 10;

undefined

之前变量没有定义的错误没了,取而代之的是告诉我们a的值是 ‘undefined‘.

先不管a的值缘何为 ‘undefined‘ 了,至少可以知道现a这个变量是定义了,因为之前报的‘ a is not defined‘的错误没有了。

这正是因为JavaScript 中的一个声明提升的特性起的作用。

JavaScript中可以提前使用在后面语句中声明的变量,这种特性叫被国外某网友(ben cherry)称为Hoisting (非官方术语) 。

我在<<javascript 模式>> 一书中看到该词被翻译为 "提升" ,指的的就是变量声明提前 .可以理解为将变量的声明提前了,所以在变量声明前使用变量不会报错。而且这一特性不仅限于变量名,对于函数的声明也是同样的效果。

第一次对函数foo()的调用同样报 ‘not defined‘ 错误。这是合情合理同时是合法的。因为从头到尾就没有定义这么一个叫作foo() 的东西。

ReferenceError: foo is not defined

foo()

之后将函数调用写在最前面,但函数的定义我们写在了之后。

foo();

function foo(){ console.log("I am foo"); }

I am foo

发现正常输出了我们想要的内容.

这里需要深入理解Hoisting这一特性。它的提前只是将声明提前,而对变量的赋值并没有跟着提前。

也就是为什么我们可以在第一句使用变量a但它的值却是 ‘undefined‘。 JavaScript里面声明了但还未赋值的变量其值默认便是 ‘undefined‘。

按照Hoisting来解释,最终生成的等价代码其实差不多应该就是这样的:

var a ;

console.log(a);

a = 1;

1.匿名函数无法在声明前调用

SyntaxError: missing ( before formal parameters

foo1();
var foo1 = function{
  console.log("I am foo1");
}

正如上面介绍的Hoisting特性,函数可以定义在调用之前也可以定义在调用之后:

但仅限于上述这种方式定义的函数。对于匿名函数上述规则不适用。

2. 参数变更影响到函数外部

当传递给函数的参数是一个数组或对象时,在函数体内对这个传入的参数的更改会影响到函数体外的原传入值。

一般说来,对参数的更改不会影响到原来变量的值,更改只在函数体内起作用,这个主要原因是javascript变量传递都是按值传递的.将变量的值进行复制,然后传入到函数内部处理.但是对于对象和数组则有所不同.

当传入的参数是数组、对象时,在函数体内对参数所做的更改会反映到原变量上。

function myFunc(theObject) {
	  theObject.make = "Toyota";
	}

	var mycar = {make: "Honda", model: "Accord", year: 1998},
	    x,
	    y;

	x = mycar.make;     // x gets the value "Honda"

	myFunc(mycar);
	y = mycar.make;     // y gets the value "Toyota"
	                    // (the make property was changed by the function)
	console.log(x );
	console.log(y);

可以看出,上面代码中已经把mycar 对象的make属性修改了.

当在函数体内对传入的数组或对象赋值时,这个更改不会反映到函数体外的原变量身上

下面是关于对象的例子:

	function myFunc1(theObject) {
	  theObject = {make: "Ford", model: "Focus", year: 2006};
	}

	var mycar = {make: "Honda", model: "Accord", year: 1998},
	    x,
	    y;

	x = mycar.make;     // x gets the value "Honda"

	myFunc1(mycar);
	y = mycar.make;     // y still gets the value "Honda"
	console.log(x);
	console.log(y);

按照上面函数内部的更改会反映到原变量的理论。但结果让人有点难以接受。

真的,我内心真的"此起彼伏"啊.

原因在于,当在函数体内使用赋值操作时,系统就创建了一个变量名为theObject的变量。这个theObject是函数内部的变量,对它进行赋值当然只在函数体内起作用,外面的myCar还是原来的myCar。

这一步与原来代码的操作差别仅在于在函数体内是对参数赋新值呢还是对参数的属性或数组的元素进行更改。

以上内容来自MDN 中关于javascript的文章.链接地址为:

https://developer.mozilla.org/en-US/docs/Web/JavaScript/Guide/Functions

Best wishes.

javascript 变量/函数 提升

时间: 2024-10-11 12:11:55

javascript 变量/函数 提升的相关文章

JavaScript 变量声明提升

JavaScript 变量声明提升 一.变量提升的部分只是变量的声明,赋值语句和可执行的代码逻辑还保持在原地不动 二.在基本的语句(或者说代码块)中(比如:if语句.for语句.while语句.switch语句.for...in语句等),不存在变量声明提升 三.函数声明会提升,但是函数表达式的函数体就不会提升 1 fun(); // hello 2 function fun(){ 3 console.log("hello"); 4 } 5 // -------------- 6 //

javascript变量声明提升

javascript变量声明提升(hoisting) javascript的变量声明具有hoisting机制,JavaScript引擎在执行的时候,会把所有变量的声明都提升到当前作用域的最前面. 先看一段代码 1 2 3 4 5 var v = "hello"; (function(){   console.log(v);   var v = "world"; })(); 这段代码运行的结果是什么呢?答案是:undefined这段代码说明了两个问题,第一,funct

Javascript中函数提升和变量提升

词法分析 词法分析方法: js运行前有一个类似编译的过程即词法分析,词法分析主要有三个步骤: 分析参数 再分析变量的声明 分析函数说明 具体步骤如下: 函数在运行的瞬间,生成一个活动对象(Active Object),简称AO 分析参数 函数接收形式参数,添加到AO的属性,并且这个时候值为undefine,例如AO.age=undefine 接收实参,添加到AO的属性,覆盖之前的undefine 分析变量声明,如var age;或var age=23; 如果上一步分析参数中AO还没有age属性,

Javascript模式——函数提升 (笔记)

函数提升: 对于所有的变量,无论函数体的何处进行声明,都会在后台被后台被提升到函数顶部.而对于函数同样适用,其原因在于函数只是分配给变量的对象.当使用函数声明时,函数定义也被提升,而不仅仅只是函数声明. function foo(){ alert('global foo'); } function bar (){ alert('global bar'); } function hoistMe(){ console.log(typeof foo); //function 变量foo以及实现都被提升

javascript变量声明提升(hoisting)

javascript的变量声明具有hoisting机制,JavaScript引擎在执行的时候,会把所有变量的声明都提升到当前作用域的最前面. 先看一段代码 1 2 3 4 5 var v = "hello"; (function(){   console.log(v);   var v = "world"; })(); 这段代码运行的结果是什么呢? 答案是:undefined 这段代码说明了两个问题, 第一,function作用域里的变量v遮盖了上层作用域变量v.代

javascript 变量(函数)声明 和 变量(函数)作用域

变量的声明 1.变量声明具有提升机制,Javascript在执行时,会把所有的声明都提升到当前作用域前面. 2.局部变量的优先级高于全局变量,或者说内围作用域的变量优先级高于外围的作用域 先看一下下面的例子:

javascript 变量的提升

下面是一个关于全局和局部作用域的问题 var a = 123; function f(){ alert(a); var a = 1; alert(a); } f(); 大家第一眼看到后都会认为第一次alert()弹出的结果是123,第二次的alert()的结果是1. 事实上不是这样的,第一次alert的结果是undefined,第二次的结果是1:

【转】javascript变量声明 及作用域

javascript变量声明提升(hoisting) javascript的变量声明具有hoisting机制,JavaScript引擎在执行的时候,会把所有变量的声明都提升到当前作用域的最前面. 先看一段代码 1 2 3 4 5 var v = "hello"; (function(){   console.log(v);   var v = "world"; })(); 这段代码运行的结果是什么呢?答案是:undefined这段代码说明了两个问题,第一,funct

javascript变量声明 及作用域

javascript变量声明提升(hoisting) http://openwares.net/js/javascript_declaration_hoisting.html 可能要FQ一下 javascript的变量声明具有hoisting机制,JavaScript引擎在执行的时候,会把所有变量的声明都提升到当前作用域的最前面. 先看一段代码 1 2 3 4 5 var v = "hello"; (function(){   console.log(v);   var v = &qu