什么是阿里巴巴的合伙人制度? 当前位置:首页>什么是阿里巴巴的合伙人制度?>正文

什么是阿里巴巴的合伙人制度?

发布时间:2019-03-21

原标题:a

阴阳道:“颠倒乾坤一经使出,原本在外的,便成了内,原本在内的,却又成了外,这不是一般道理么?你若将桃核当作是外,那桃肉便是内,这不是十分简单么?”

论多引力空间——理论假说

李大刚一听这个,便急忙点点头:“这个法子行,冒充鬼子辎重车队混进江阴炮台里去,端掉他们的仓库!”
就在叶扬苦思冥想,该用什么方法让的这凤凰醒过来的时候,他的心头突然一动,似乎想到了一个很好很好的方法。

幽怜还没有这样的本事让一个普通人直接拥有光之巨人的能量,她不过是利用大古体内的能量制造出一个连接大古和体内的能量的变身器而已,因此对于幽怜来说并不怎么难。

先来两个问题

很多时候,在直觉上,我们都会认为JS代码在执行时都是自上而下一行一行执行的,但是实际上,有一种情况会导致这个假设是错误的。

a = 2;
var a;
console.log(a);

按照传统眼光,console.log(a)输出的应该是undefined,因为var a在a = 2之后。但是,输出的是2。

再看第二段代码:

console.log(a);
var a = 2;

有人会想到第一段代码,然后回答undefined。还有人会认为a在使用前未被声明,因此抛出ReferenceError异常。遗憾的是,结果是undefined。

为什么呢?

从编译器的角度看问题

JS在编译阶段,编译器的一部分工作就是找到所有声明,并用合适的作用域将他们关联起来。对于一般人来说var a = 2仅仅是一个声明,但是,JS编译器会将该段代码拆为两段,即:var a和a = 2。var a这个定义声明会在编译阶段执行,而a = 2这个赋值声明会在原地等待传统意义上的从上到下的执行。

所以,在编译器的角度来看,第一段代码实际上是这样的:

var a;  // 编译阶段执行
a = 2;
console.log(a);

所以,输出的是2。

类似的,第二个代码片段实际上是这样执行的:

var a;
console.log(a);
a = 2;

这样的话,很明显,输出的应该是undefined,因为只对a进行了定义声明,没有对a进行赋值声明。

从上面这两个例子可以看出,变量声明会从它们在代码中出现的位置被移动到当前作用域的最上方进行执行,这个过程叫做提升

函数提升

下面,再来看一段代码

foo();

function foo () {
    console.log(a);
    var a = 2;
}

在这个例子中,输出undefined而不会报错,因为,函数变量也能提升。即,实际上像如下的情况运行。

function foo () {
    var a;
    console.log(a);
    a = 2;
}

foo();

说到这里,你是不是认为提升很简单,只要把变量都放到当前作用域最上方执行就好了?

下面,我来说一种意外情况:函数表达式的提升情况。

函数表达式的提升情况

foo();

var foo = function bar () {
    console.log(a);
    var a = 2;
}

你是不是想说,这个例子不是和之前的那个差不多吗?输出的当然是undefined呀。但是,结果是,不输出,因为JS报了TypeError错误!

因为,函数表达式不会进行提升!

该例子的实际运行情况是这样的:

var foo;
foo();
foo = function bar () {
    var a;
    console.log(a);
    a = 2;
}

由于执行时,在作用域中找得到foo(该作用域最上方声明了foo),所以不会报ReferenceError错误,但是,foo此时没有进行赋值(如果foo是一个函数声明而不是函数表达式,那么就会赋值),也就是说实际上foo()是对一个值为undefined的变量进行函数调用,所以,理所应当抛出TypeError异常。

值得一提的是,即使是具名的函数表达式,名称标识符在赋值之前也无法在所在作用域中使用,即:

foo();  // TypeError
bar();  // ReferenceError

var foo = function bar () {}

函数优先

函数声明和变量声明都会被提升,但是有一个值得注意的细节,那就是,函数会首先提升,然后才是变量!

看下面这一段代码:

foo();
var foo;
function foo () {
    console.log(1);
}
foo = function () {
    console.log(2);
}

这一段代码会输出1,原因就在于,函数优先。

这一段代码可以转换为以下形式:

function foo () {
    console.log(1);
}
var foo;    // 重复声明,被忽略
foo();      // 输出1
foo = function () {
    console.log(2);
}

如果,在代码的结尾再执行一次foo函数,此时,输出的是1。

function foo () {
    console.log(1);
}
var foo;    // 重复声明,被忽略
foo();      // 输出1
foo = function () {
    console.log(2);
}
foo();      // 输出2

因为,尽管重复的声明会被忽略了,但是后面的函数还是可以覆盖前面的函数。

明白了这个道理,你就可以理解下面这个问题了:

foo();
var a = true;
if (a) {
    function foo () {
        console.log("a");
    }
} else {
    function foo () {
        console.log("b");
    }
}

你猜这道题输出的结果是什么?是b!为什么?因为foo进行了两次的声明,但是,后一次函数覆盖了前一次的函数。所以调用foo时,永远调用的都是console.log("b")。

总结

1.所有声明(变量和函数)都会被移动到各自作用域的最顶端,这个过程被称为提升

2.函数表达式等各种赋值操作并不会被提升

3.函数优先原则

4.尽量避免产生提升问题

参考资料:You Dont"t Know JS: SCope & Closures

编辑:宗安

发布:2019-03-21 09:18:33

当前文章:http://aluminumalloyformwork.com/fv1dg.html

【心理咨询】从心理学角度解析梦境 如何应对宝宝的第一个叛逆期! 生命轮回的真相 情绪稳定是一种巨大的能力 爱情越久越不能忍受恋人缺点? 他用背影默默告诉你:不必追 2016·315·新消费我做主 家用瓷砖选大板砖怎么样?有什么品牌可以推荐?

50559 48693 26985 25024 19008 92888 80510 45592 99939 87269 40296 18186 21997 74053 63457 54877 89368 78257 24142 39764

责任编辑:密王伯安