关闭

Js中概念理解(一)

113人阅读 评论(0) 收藏 举报

Js中概念理解(一)

Js 中 核心概念

变量提升


Js中var声明的作用域,从声明处向前后两个方向扩展,知道触及函数边界才停止,作用域很广,一进入函数Js引擎就会马上找到它并创建出来,这就是所谓的 “变量提升”。Js引擎会将所有var声明和function函数声明提升到函数内的最高处。

用ES6的let关键字声明变量不存在 变量提升的特性,所以在let声明变量之前,使用变量会报错。

立即调用函数表达式(iife)


本质:立即执行函数表达式

顾名思义,立即执行函数可以让你的函数创建后立即执行。常用形式如下:

1、(function(){})();

2、(function(){}());

只有函数表达式后加上括号,函数才会立即执行,函数声明即便后加括号也不会立即执行。

js中,括号内只允许表达式,当js引擎解析代码是,先遇到(),再遇到function时就会主动将()里的匿名函数识别为函数表达式,而非函数声明。

(function(a){ console.log(a); //输出123,使用()运算符})(123);

(function(a){ console.log(a); //输出1234,使用()运算符}(1234));

!function(a){ console.log(a); //输出12345,使用!运算符}(12345);

+function(a){ console.log(a); //输出123456,使用+运算符}(123456);

-function(a){ console.log(a); //输出1234567,使用-运算符}(1234567);var fn=function(a){ console.log(a); //输出12345678,使用=运算符}(12345678)

匿名函数前加 ! + - = , 都可以起到将匿名函数转换为函数表达式,后加括号即可立即执行,这些运算符消除了js引擎识别函数表达式和函数声明的歧义,告诉js引擎这是一个可运算的函数表达式,而非函数声明。 常规做法是加括号实现立即执行,其他运算符会和函数返回值运算

立即执行函数的作用:

js中没有私有域的概念,声明变量如果同名存在相互覆盖的情况,使用立即执行函数(iife)目的就是模仿一个私有作用域,立即执行的匿名函数相当于一个容器,内部可以访问外部的变量,但是外部不可以访问内部的变量,所以还可称为“匿名包装器”。

详解立即执行函数

函数声明 和 函数表达式


  • 函数声明:

    function fnname(){...};function 关键字声明一个函数,再指定一个函数名,既函数声明。

  • 匿名函数

    function(){...},使用function声明一个函数,但未指定函数名,所以叫匿名函数,匿名函数属于函数表达式,匿名函数作用很多,赋予一个变量则创建函数,赋予一个事件则成为事件处理程序或创建闭包。

  • 函数表达式

    var fnname=function(){...} 使用function声明一个函数,但未指定函数名,然后将匿名函数赋予一个变量,叫函数表达式。

  • 函数声明和函数表达式区别

    // 函数声明提升fnName(); // 正常,因为函数声明被提升,所以函数调用可以在声明之前function fnName(){

    ...

    }

    fnName(); // 错误,函数调用必须在函数表达式之后var fnName=function(){

    ...

    }

    var fnName=function(){

    alert('hello world!');

    }();// 函数表达式加(),js引擎解析到此处时,函数立即执行function fnname(){

    alert('hello world');

    }();// 不会报错,但js引擎只会解析函数声明,忽略后面的(),函数声明不会被调用function(){

    alert('hello world');

    }();// 语法错误,虽然匿名函数属于函数表达式范畴,但未执行赋值操作,// 所以js引擎将function关键字解析为函数声明,报错:要求需要一个函数名

    • javascript引擎在解析javascript代码时,函数声明会函数声明提升,当前执行环境(作用域)上的函数声明,而函数表达式必须等到js引擎执行到它所在行时,才会从上而下一行一行地解析函数表达式。

    • 函数表达式后面可以加上(),立即调用该函数,函数声明不可以,函数声明不可以,只能以fnName()形式调用。

块级作用域


ES5只有全局作用域和函数作用域,没有块级作用域,这会带来如下问题: 内层变量覆盖外层变量

var tmp=new Date();function f(){

alert(tmp); if(false){ var tmp='hello world';

}

}

f();// 输出:// undefined

分析:

原因在于“变量提升”,内部的var tmp='hello world';变量提升,覆盖了f()函数作用域,进而覆盖了外部的tmp变量,而且alert时还没有执行到var tmp='hello world;'所以会输出undefined.

var s = 'hello';for (var i = 0; i < s.length; i++) { console.log(s[i]);

}console.log(i); // 5

i变量提升,循环结束后并未消失,成为全局变量,或有违程序设计初衷。

暂时性死区


代码块内,使用let命令声明变量之前,该变量是不可用的,语法上成为暂时性死区

注意 由于暂时性死区的存在,typeof就不再是一个百分之百安全的操作。

本文为头条号作者发布,不代表今日头条立场。

0
0

猜你在找
【直播】机器学习&数据挖掘7周实训--韦玮
【套餐】系统集成项目管理工程师顺利通关--徐朋
【直播】3小时掌握Docker最佳实战-徐西宁
【套餐】机器学习系列套餐(算法+实战)--唐宇迪
【直播】计算机视觉原理及实战--屈教授
【套餐】微信订阅号+服务号Java版 v2.0--翟东平
【直播】机器学习之矩阵--黄博士
【套餐】微信订阅号+服务号Java版 v2.0--翟东平
【直播】机器学习之凸优化--马博士
【套餐】Javascript 设计模式实战--曾亮
查看评论
* 以上用户言论只代表其个人观点,不代表CSDN网站的观点或立场
    个人资料
    • 访问:467893次
    • 积分:7220
    • 等级:
    • 排名:第3077名
    • 原创:25篇
    • 转载:1631篇
    • 译文:0篇
    • 评论:82条
    最新评论