GithubHelp home page GithubHelp logo

mynote's People

Contributors

hualinlin avatar

Watchers

 avatar  avatar

mynote's Issues

javascript变量提升

函数和变量的声明总是会被解析器悄悄地被“提升”到方法体的最顶部

上面是javascript变量提升的概念。为了更好地理解“变量提升”,我们先来看一段代码:

(function (){
console.log(foo);
var foo = "Javascript";
})();
控制台输出:undefined 为什么输出了undefined,而没有报错呢?

原来javascript是函数作用域,解析器会在函数开头处自动去声明局部变量,局部变量都会被放在函数的入口处定义,所以上面的代码实际会被解释成:

(function (){
var foo;
console.log(foo);
foo = "Javascript";
})();
另外,需要注意Javascript中函数的两种声明方式存在的坑:

function fn(){} //函数声明式
var fn = function(){}; //函数表达式
对于函数声明式,解析器会确保在所有代码执行之前声明已经被解析。而对于函数表达式,与定义其它基本类型变量一样,逐句执行并解析。

我们再来举个栗子:

/* 函数声明式 */
(function(){
fn();
function fn() {
console.log('来自函数声明式fn');
}
})();

/* 函数表达式 */
(function(){
fn();
var fn = function() {
console.log('来自函数表达式fn');
}
})();
控制台依次输出:

来自函数声明式fn
fn is not a function
可以看到,当使用函数声明的形式来定义函数时,可将调用语句写在函数声明之前,而后者,则会报错。

所以在Javascript中,变量的声明会被提升,而变量的赋值则不会。而函数的声明与变量的声明是不一样的,函数的函数体也会被一起提升,但请使用函数声明的形式才能提升。

js闭包

一、变量的作用域
要理解闭包,首先必须理解Javascript特殊的变量作用域。
变量的作用域无非就是两种:全局变量和局部变量。
Javascript语言的特殊之处,就在于函数内部可以直接读取全局变量。
var n=100; function shownum(){ alert(n); } shownum(); // 100
另一方面,在函数外部自然无法读取函数内的局部变量。
function shownum(){ var n=999; } alert(n); // Uncaught ReferenceError: n is not defined
这里有一个地方需要注意,函数内部声明变量的时候,一定要使用var命令。如果不用的话,你实际上声明了一个全局变量!
function shownum(){ n=999; } shownum(); alert(n); // 999
二、什么是闭包
闭包主要涉及到js的几个其他的特性:作用域链,垃圾(内存)回收机制,函数嵌套,等等.
在理解闭包以前.最好能先理解一下作用域链的含义,简单来说,作用域链就是函数在定义的时候创建的,用于寻找使用到的变量的值的一个索引,而他内部的规则是,把函数自身的本地变量放在最前面,把自身的父级函数中的变量放在其次,把再高一级函数中的变量放在更后面,以此类推直至全局对象为止.当函数中需要查询一个变量的值的时候,js解释器会去作用域链去查找,从最前面的本地变量中先找,如果没有找到对应的变量,则到下一级的链上找,一旦找到了变量,则不再继续.如果找到最后也没找到需要的变量,则解释器返回undefined.
了解了作用域链,我们再来看看js的内存回收机制,一般来说,一个函数在执行开始的时候,会给其中定义的变量划分内存空间保存,以备后面的语句所用,等到函数执行完毕返回了,这些变量就被认为是无用的了.对应的内存空间也就被回收了.下次再执行此函数的时候,所有的变量又回到最初的状态,重新赋值使用.但是如果这个函数内部又嵌套了另一个函数,而这个函数是有可能在外部被调用到的.并且这个内部函数又使用了外部函数的某些变量的话.这种内存回收机制就会出现问题.如果在外部函数返回后,又直接调用了内部函数,那么内部函数就无法读取到他所需要的外部函数中变量的值了.所以js解释器在遇到函数定义的时候,会自动把函数和他可能使用的变量(包括本地变量和父级和祖先级函数的变量(自由变量))一起保存起来.也就是构建一个闭包,这些变量将不会被内存回收器所回收,只有当内部的函数不可能被调用以后(例如被删除了,或者没有了指针),才会销毁这个闭包,而没有任何一个闭包引用的变量才会被下一次内存回收启动时所回收.
有权访问另一个函数作用域内变量的函数都是闭包。
闭包就是能够读取其他函数内部变量的函数.

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.