JavaScript基础

一 JavaScript 简介1 JavaScript基本介绍1 JavaScript 简称JS,是一种动态的弱类型脚本解释型语言,和HTML,CSS并成为三大WEB核心技术,得到了几乎所有主流浏览器的支持2 JavaScript 历史1994年,网景Netscape公司成立并发布了Netscape navigator浏览器,占据了很大的时长份额,网景意识到WEB需要动态,需要一种技术来实现1995年9月网景浏览器2发布测试版本发布了livescript,随即在12月的测试版就更名为JavaScript,同时期,微软推出IE并支持JScript,VBScript。1997年,网景,微软,SUN,borland公司和其他组织在ECMA确定了ECMAscript语言标准,JS则是ECMAscript的标准实现之一。由于IE的捆绑销售行为,网景的单一浏览器时长萎缩,从1990年的90%下降到2006年的1%,1999年网景被AOL收购,收购不就,netspace公开了浏览器代码,并创建了Mozilla组织,Mozilla组织使用Gelo引擎重写浏览器,当然Mozilla将Geko引擎发布了Firefox浏览器2003年5月,网景被解散AOL于2007年宣布停止支持Netscape浏览器3 网景的技术HTTP cookie ,解决HTTP无状态JavaScriptssl协议jar 格式文件,将Java的class文件打包,并加上签名2012年4月9日,微软以10亿5千6百万购买800向美国在线的专利或专利授权,并收购了SSL,cookie等专利。4 ESES,ECMAScript是由ECMA国际(前身为欧洲计算机制造协会,英文名称是European Computer Manufactures Association)通过ECMA-262标准化的脚本程序设计语言,该语言被广泛应用于互联网JavaScript是商品名,目前商标权在Oracle公司手中,ES是标准名。根据ES标准,有很多实现引擎,其中包括JavaScript或JScript,他们都是ECMA-262标准的实现和扩展。1997年,制定了首个ECMA-2621999年12月,EC3,支持更强大的正则表达式ES4 太过激进,最终被放弃2009年,ES5发布,得到广泛支持,支持严格模式,支持Json2015年,ES6发布,引入非常多的新的语言特性,还兼容旧版本的特性,ES6之前按照版本号命名,从ES6开始使用年份作为版本号,ES6 及ECMAscript 2015.5 之前浏览器中兼容问题运行HTML,CSS,JS技术都在发展,标准版本很多,浏览器内嵌的引擎实现不太一致,甚至有不按照标准实现,或者减少实现,或者改变实现,或者增加的功能,如IE,就导致了开发人员负担,很难做到一套代码可以兼容的跑在多种浏览器中,甚至不能跑在同一种浏览器的不同版本中。6 V8 引擎就在浏览器IE一家独大时,Firefox和Chrome开始变强2008年9月2日,Google的Chrome浏览器发布,一并发布的js引擎,就是V8引擎,V8使用BSD协议开源V8引擎支持C++开发,将JavaScript编译成了机器码,而不是字节码,还是用很多优化方式提高性能,因此,V8引擎速度很快。V8 引擎还可以独立运行,可以嵌入到其他任何C++程序中。V8 引擎的诞生,使得服务器端运行JS称为了方便的事情。7 Nodejsnodejs是服务器端运行JavaScript的开源的,跨平台的运行环境nodejs原始作者瑞安达尔于2009年发布,使用了V8引擎,并采用事件驱动,非阻塞异步IO模型2010年,npm软件包管理器诞生,通过它,可以方便的发布,分析nodejs的库和源代码。nodejs4.0引入了ES6的语言特性。8 安装组件需要安装nodejs和visual studio code相关下载nodejsvisual studio code插件NodeExec和汉化包安装重新启动软件即可生效,二 JavaScript基础1 注释,常量,变量1 注释和C 、Java一样//单行注释/*注释*/多行注释,也可以使用在语句中注: 使用快捷键F8运行代码,其代码必须是已经保存的文件,不能是空,F8可能和有道词典快捷键冲突,建议在此运行期间不运行有道词典。2 常量和变量1 标识符标识符必须是字母,下滑线,美元符号和数字,但必须是字母,下划线,美元符号开头,依然不能是数字开头标识符区分大小写2 标识符的声明var 声明一个变量let 声明一个块作用域中的局部变量const 声明一个常量JS中的变量声明和初始化时可以分开的常量的存放位置和变量是不在一起的console.log(a) // 后面声明的变量,前面可以使用,但没意义var  a    //只是声明,并未赋值,其类型是undefined,let b   //声明为块变量console.log(1,a,b) //打印a=1  //变量赋值,不规范化操作,不推荐,在严格模式下回导致异常。在赋值之前不能引用,因为未为进行声明,其赋值的结果是全局作用域b='123'console.log(2,a,b)const  c=100  //定义常量console.log(c)var d=10 //规范声明并初始化console.log(3,d)c=200  //修改常量值,不可修改,因为其是常量console.log(4,c)结果如下常量和变量的选择如果明确知道一个标识符定以后便不再改变,应该尽量声明成const常量,减少被修改的风险,减少bug。3 函数对作用域的控制function  test(){var  x=10;  //声明并初始化xy=20;  //声明vi能够初始化yconsole.log(x,y)}test()console.log(x,y)  //此处在函数中,其所有参数皆不能冲破作用域// x=100// console.log(x)结果如下函数本身天生就是一个作用域4 提升作用域其实就是将声明定义到最前面罢了,及就是先调用,再定义console.log(a)console.log(b)console.log(c)console.log(d)console.log(e)var a=200;  // 提升作用域,只有var定义变量的方式可以提升作用域var  b;const  c=300; //此处不能提升作用域let d;e=300;结果如下2 数据类型1 基本数据类型介绍序号名称说明1number数值型,包括整数类型和浮点型2boolean布尔型,true和false3string字符串4null只有一个值null5undefined变量声明未赋值的,对象未定义的属性6symbolES6新引入的类型7object类型是以上基本类型的复合类型,是容器ES是动态语言,弱类型语言虽然先声明了变量,但是变量可以重新赋值成任何类型2 类型转换1 字符串类型转换console.log(a=1+'test',typeof(a))  //  typeof:打印类型console.log(a=false+'test',typeof(a))  //和布尔类型运算console.log(a=null+'test',typeof(a))  //和null比较console.log(a=true+'test',typeof(a))console.log(a=undefined+'test',typeof(a))  //和数字结果如下2 数字类型转换console.log(a=1+false,typeof(a))console.log(a=1+true,typeof(a))console.log(a=1+null,typeof(a))console.log(a=1+undefined,typeof(a))结果如下3 布尔类型转换相关console.log(a=false+undefined,typeof(a))console.log(a=true+undefined,typeof(a))console.log(a=false+null,typeof(a))console.log(a=true+null,typeof(a))console.log(a=true &  '',typeof(a))  //位运算console.log(a=undefined  &&  true,typeof(a))  //与运算4 短路True是透明的,false则直接就是短路,返回直接就是false,类型是布尔。true主要是看后面的情况console.log(a=false  && null,typeof(a))  //如果前面是false,则返回结果是false,且类型是布尔类型console.log(a=false  &&  'zhangbing',typeof(a))console.log(a=true  && '32534534',typeof(a))  //如果前面是true,则以后面为准console.log(a=true  && '' ,typeof(a))5 总结:弱类型,不需要强制转换NaN,Not a Number,转换数字失败遇到字符串,加括号就是拼接字符串,所有非字符串隐式转换为字符串如果没有字符串,加号把其他所有类型都当数字处理,非数字类型隐式转换成数字,undefined特殊,因为它都没有定义值,网站监控所有其是一个特殊的数字Nan。如果运算符是逻辑运算符,短路符,则返回就是短路时的类型,没有隐式转换除非你十分明确,否则不要依赖隐式类型转换,写代码时,往往为了程序的健壮性,建议显式转换3 字符串定义及操作1 定义将一个值一单引号或双引号引用后便形成了字符串let a="a\"aaaaaa"  // 可使用转义符号let b='adadsaasd'  //单引号定义let c="asfsdfsadfsdf'sdfsdfsdfsdf'"  //混合定义let d=`'abcd'`  //反引号定义let e=`x= ${a}  y=${b}`  //插值,类似于Java中的替换和python中的formatconsole.log(a,b,c,d)console.log(e)结果如下2 转义字符字符说明\0Null 字节\b退格符\f换页符\n换行符\r回车符\tTab(制表符)\v垂直制表符'单引号"双引号|反斜杠字符()\XXX由从0到377最多三个八进制数XXX表示的Latin-1字符\xXX由从00和FF的两位十六进制数字XX表示的Latin-1字符\uXXXX由4位十六进制数字XXXX表示的Unicode字符,例如,\u00A9是版权符号的Unicode序列,见Unicode escape sequence\u{xxxxxx}Unicode代码点(code point)转义字符3 字符串操作支持索引,切片,查询,替换和链接console.log('adasddasdasd'.indexOf(1))  //查找位置,若不存在,则返回-1console.log('abced'.indexOf('c')) //获取对应位置console.log('12345'.charAt(4))  //索引获取元素console.log('1234'.concat('666'))  // 元素追加const  a='123456'  //定义一个常量console.log(a[3])  //通过索引获取元素console.log(a.toUpperCase())  //大写转换console.log(a.slice(1,3))  //切片,左闭右开 1,2处的元素console.log(a.slice(-3,-1))   //45const  url=' www.baidu.com  'console.log(url.split('.'))  //字符串分割console.log(url.startsWith('www'))  //匹配字符串起始,返回false或trueconsole.log(url.substr(3,6))  //从索引为3开始6个字符console.log(url.substr(3,6))  //从索引为3开始到索引为6结束console.log(url.replace('com','edu'))  //字符串一替换console.log(url.trim())  //取出两边的空白字符4 数值类型number进制符描述0bxxx/0Bxxx二进制0oxxx八进制0xxxx十六进制在JS中,数据均为双精度浮点型范围只能在-(2^53-1)和2^53-1之间,整数类型也不例外,数字类型还有三种符号值:+Infinity(正无穷),-Infinity(负无穷)和Nan(not-a-number非数字)二进制0b0010,0B100.八进制0755,注意0855,将被认作是十进制,因为8不在八进制中,ES6中最好使用0o 前缀表示八进制十六进制0xAA,0xff指数表示1E3(1000),2e-2(0.02)常量属性var biggestNum=Number.MAX_VALUE; //最大值var smallestNum=Number.MIN_VALUE; //最小的大于0的数var infiniteNum=Number.POSITIVE_INFINITY;var negInfiniteNum=Number.NEGATIVE_INFINITY;var notANum=Number.NaN;数字方法方法描述Number.paraseFloat()把字符串参数解析成浮点数,和全局方法parseFloat()作用一样Number.parseLnt()把字符串解析成特定基数对应的整数类型数字,和全局方法parseInt()作用一致Number.isFinite()判断传递的值是否为有限数字Number.isInteger()判断传递的值是否为整数Number.isNaN()判断传递的值是否是NaN内置数学对象MathMath提供了绝对值,对数指数运算,三角函数运算,最大值,最小值,随机数,开方等运算函数,提供了P|值console.log(typeof(parseInt('1234123423423')),'134234')  //转换为数值类型console.log(isNaN(10))  //判断是否为NaNconsole.log(isFinite(10/3))console.log(Math.abs(-1))  //绝对值console.log(Math.random()*1000)  //生成随机数三 运算符1 算数运算符符号描述+加-减*乘/除%余++i单目运算符先加后赋值i++单目运算符先赋值后加--i单目运算符先减后赋值i--单目运算符先赋值后减单目运算符,自增和自减只针对一个参数的运算符++ 和 --i++ 表示先用,后加,其加的值为1++i 表示先加,后用,其加的值也是1总之,谁在左,谁先执行反之--也是亦然。let i=0;a=i++  //此处是先用后加,因此其a的值应该是0,之后加1console.log(a)b=++i;  //此处是先加后用,此处的b的值应该是i为1的基础是加1,及为2console.log(b)c=i++;  //此处是先用,及c为2console.log(c)结果如下其中单目运算符的优先级高于双目运算符。相关习题let i=0;a=(++i+i+++i+++i)//其中单目优先级高,则可拆解为 ++i   +   i++    +   i++   +i//++i结果为1 ,i++结果i为1  i++ 结果i为2  i的结果为3 最终为1+1+2+3=7console.log(a)结果如下此题主要考虑两个点1 单目运算符优先级高于双目运算符2 加号+是双目运算符,两边的表达式必须先计算好2 比较运算符符号描述>大于<小于>=大于等于<=小于等于!=不等于,宽松模式进行类型转换==宽松模式等于,及就是进行类型转换!==严格模式不等于,及不进行类型转换===恒等,及全等,不进行类型转换console.log('1'==1) //此处为宽松模式,进行类型转换,此处为trueconsole.log('1'===1) //此处为严格模式,此处返回为Falseconsole.log('200'>300)  //此处为true,进行了类型转换console.log('2a'<200)  //此处为false,此处的2a是不能转换为数字的,因此不能参与比较,因此其返回值为falseconsole.log(Number.MAX_VALUE>10000)  //和最大比较,返回为trueconsole.log(Number.MIN_VALUE < 0.00001) //和最小比较,范围为trueconsole.log(Number.MAX_VALUE>Number.MIN_VALUE) //最大和最小比较,返回为true结果如下3 逻辑运算符Column 1Column 2&&逻辑与||逻辑或!逻辑非这些运算符和其他高级语言相同。支持短路。4 位运算符方法描述&位与|位或^异或~取反<<左移>>右移5 三元运算符条件表达式?真值:假值,邓建与简单的if ...else 结构console.log(('3'>30)?'真':'假')console.log((4<5)?'假':'真')6 逗号操作符JS 运行多个表达式写在一起的情况console.log(a,b,c)var  a=100,b=200,c=300  //提升作用域,会定义三个元素结果如下7 运算符优先级8 其他名称说明Instanceof判断是否属于指定类型typeof返回类型字符串deletedelete操作符,删除一个对象(an object)或者一个对象的属性(an object's property) 或者一个数组中的某一个键值(an element at a specified index in an array)。in如果指定的属性在对象内,则返回trueinstanceof 要求必须明确使用类型定义变量,就是对象必须是new关键字声明创建的,它可以用于继承关系的判断typeof 就是返回对象的类型字符串delete删除对象,属性,数组元素a=new  String('abcd')b=new  Number(123)console.log(a instanceof  String)console.log(b instanceof  Number)console.log(typeof(a))console.log(typeof(b))console.log(typeof(100))console.log('--------------delete-----------')x=42var y=43let  z=60myobj=new Number();myobj.h=4  //增加属性console.log(delete  x);  //隐式声明使用delete能够删除成功console.log(delete y);  //var声明的不能删除console.log(delete z); //let声明的依然不能删除console.log(delete myobj.PI) //不能删除预定义的对象,console.log(delete myobj.h) // 自定义的属性变量是可以删除的console.log(delete myobj)  //自定义的对象可以删除,因为其是隐式声明,因此可以删除console.log('+++++++++++++++++++')var  trees = new Array('redwoord','bay','cendar','cak','maple')for (var  i=0;i<trees.length;i++)console.log(trees[i])console.log('====================')delete trees[3];//删除其中的元素,其数组不会少,只会在当前索引对应的数据变为undefinedfor (var  i=0;i<trees.length;i++)console.log(trees[i])console.log('-------------object----------------')let mycar ={make:'Honda',model:'Accord',year: 2019};console.log('make' in mycar);  //trueconsole.log('model' in mycar);  //true结果如下四 JavaScript控制语句1 条件判断语句1 if 判断语句if  (cond1)  {}else if  (cond2) {}else if (cond3) {}else {}条件为false的等效falseundefinednull0NaN空字符串其他的将均被视为True,如空列表。if ([]){let d=4;//定义为块变量,其不能穿透ifvar  e=5;  //var 定义,能够穿透iff=6;  //定义,能够穿透if (true)  {console.log(d);console.log(e);console.log(f);g=10;var h=11;let t=13;//定义为块变量,其不能穿透if}}console.log(h,g,f)console.log(t)结果如下2 switch...case 分支语句switch  ()  {case  label_1:statements_1[break;]case  label_2:statements_2[break;]...default:statements_def[break;]}let a=3switch  (a) {case 1:console.log(1)break;case 2:console.log(2)break;case 3:console.log(3)break;default:console.log(4)break;}结果如下switch的穿透效果,直到碰见break为止。let a=3switch  (a) {case 1:console.log(1)case 2:console.log(2)case 3:console.log(3)default:console.log(4)}结果如下2 循环1 for 循环//C风格for循环for  ([initial];[condition];[increment]){statement}arr=[10,20,30]for (let  x=0;x<arr.length;x++){console.log('i',arr[x])}console.log('+++++++++++++++++')for (let j=0;j<arr.length;j++,j++) {  //注意,此处是逗号(i++,i++)console.log('j',arr[j])}// for (z=0;z<arr.length;) { // 此处是死循环,因为没有增加条件//     console.log(arr[z])// }for  (let a=0,b=200;a<arr.length;a++,b++) {   // 多条件操作console.log(a,arr[a],b);}for  ( let z  in arr)  { //此处获取到的是索引console.log(z,arr[z])}for  (let  w  of  arr)  {   //此处获取到的是值console.log(w)}let obj={'a':1,'b':2,'c':3}for  (let x  in  obj) {  //使用for循环处理对key的访问console.log('obj',x)}// for  (let y  of   obj)  {  //此处不能实现,因为其不能迭代对象//     console.log(y)// }结果如下注意:for in 循环返回的是索引或者key,需要间接访问到值。数组反正返回的是索引,C风格for循环操作较为便利对象使用for in 可以遍历其key,但不能使用for of 迭代对象,原因是of后面必须是一个迭代器,可类比python中的for in。3 while循环和do...while 循环while 循环一般适用于死循环,while循环是先判断,do...while循环是先执行,后判断。while  (condition){statement}do {statement}while(condition)先进入循环,然后判断,为真就继续循环let x=10;while  (x--){console.log(x)}结果如下let x=10;do  {console.log(x)}while(x--)结果如下3 break 和 continuebreak 结束当前循环,直接退出这个循环体continue 中断当前循环,直接进入下一次循环,同一个循环中的某一个跳过练习打印9*9乘法口诀for  (i=1;i<10;i++) {line=" "for (j=1;j<=i;j++){line += `${j}*${i} = ${i*j}  `if  (i==j)console.log(line);}}五 函数1 函数基础1 基础函数函数: 函数也是对象格式如下function  函数名(参数列表) {函数体;return  返回值;}示例如下function  add(x,y){return x+y;}console.log(add(4,5))结果如下2 函数表达式使用表达式来定义函数,表达式中的函数名可以省略,如果这个函数名不省略,也只能用于该函数的内部。1 基础函数表达式const add =function  _add(x,y) {return x+y;}console.log(_add(4,5))结果如下2 递归调用const add =function _add(x) {if (x==1){return  x;}return  _add(x-1)+x  //递归调用,该函数只能在其内部被调用}console.log(add(10))结果如下3 匿名函数const add =function (x,y) {  //匿名函数return x+y;}console.log(add(4,5))4 函数和函数表达式console.log(show)function show(){  //函数可以提升作用域console.log('show')}console.log(add)var add=function(){  //函数表达式则不能提升作用域return  1;}结果如下5 总结函数,匿名函数,函数表达式的差异函数和匿名函数,本质上都是一样的,都是函数对象,只不过函数有自己的标识符--函数名。匿名函数需要借助其他标识符而已。区别在于,函数会声明提升,函数表达式不会。2 高阶函数1 基础高阶函数:参数为函数或返回值为函数的函数称为高阶函数function   a(){console.log('a')return    function  b(){console.log('b')return  'b'  //函数必须有返回值,否则,返回为undefined}}console.log(a())  //调用外层函数console.log(a()()) //由于a返回值函数,因此可以使用括号来进行相关的调用操作结果如下2 计数器let counter=function() {let i=0;function  _fun(){return  ++i;}return  _fun}c=counter()console.log(c())console.log(c())console.log(c())console.log(c())结果如下3 练习实现map函数的功能,传入一个函数,传入一个值,输出一个值处理后的情况,如输入1,2,3,4,输出为1 4 9 16 及平方const  map1= function (fn,arr){newarry=[];for  (i  in  arr){newarry[i]=fn(arr[i]);}return  newarry;}const  sq = function(x){return  x*x;}console.log(map1(sq,[1,2,3,4]))3 箭头函数箭头函数就是匿名函数,它是一种更加精简的格式箭头函数参数如果一个函数没有参数,则使用()如果只有一个参数,参数列表可以省略小括号多个参数不能省略小括号,且使用逗号间隔箭头函数返回值如果函数体部分有多行,就需要使用{},如果有返回值则使用return。如果只有一行语句,可以同时省略大括号和return只有一条return语句,不能省略大括号,有return必须有大括号如果只有一条非return语句,加上大括号,函数无返回值将上述实例中的函数修改为箭头函数const  map1=  (fn,arr)  => {newarry=[];for  (i  in  arr){newarry[i]=fn(arr[i]);}return  newarry;}const  sq = (x)  =>  x*x;console.log(map1(sq,[1,2,3,4]))结果如下const  map1=  (fn,arr)  => {newarry=[];for  (i  in  arr){newarry[i]=fn(arr[i]);}return  newarry;}let  new1  = map1((function  (x) {return x*x}),[1,2,3,4])  //函数let new2=map1((x)=> {return x*x},[1,2,3,4] ) //去除function ,将后面的变为(x) => {return x}形式let new3  =map1((x)=> x*x,[1,2,3,4])  //若只有一个返回值,则可以省略{},但{} 和return是同时存在,因此可以写成如下let new4  =map1( x => x*x,[1,2,3,4])  //如果只有一个参数,则可以省略()console.log(new1)console.log(new2)console.log(new3)console.log(new4)结果如下4 函数参数1 基本参数传递const  add = (x,y)  => x+y;console.log('add',add(4,5))const  add1 = (x,y=5)  => x+y;  //支持默认参数console.log('add1',add1(4))const  add2 = (x=6,y) => x+y;console.log('add2',add2(1))  //此处默认会将x=6代替为x=1,而y的值为undefined其传入的值为add2(1,undefined)console.log('add2',add2(1,10))console.log('add2',add2(y=10,z=20))  //此处的结果为30,其不关心形式参数,此处为add2(10,20)console.log('add2',add2(a=1000,b=3000,c=4000))  //多传递参数没错,只匹配前面的结果如下JS 基本参数总结1 JS 中并没有python中的关键字传参2 JS 只是再做参数位置的对应3 JS 并不限制默认参数的位置4 JS 多传递参数没影响,其只是做位置的匹配操作2 可变参数(rest parameters 剩余参数)const  add =  (...args) => {  // 可变参数 ,默认结果为列表result=0;console.log(args);for  (let  x  in args)  {result  += args[x];}return  result;}console.log(add(1,2,3,4,5))3 实参解构和python 类似,JS提供了参数解构,依然使用了...符号来解构。const add  =(...args)  => {console.log(args)}add(1,2,3,4)l1=[1,2,3,4]add(l1)//参数解构console.log(...l1)add(...l1)结果如下4 arguments对象函数的所有参数都会被保存在一个arguments的键值对字典对象中。(function   (p1,...args) {console.log(p1);console.log(args);console.log('---------------');console.log(arguments,typeof(arguments));for  (let x  of arguments)console.log(x);})('abcd',1,2,3,4,5)  //此处是调用操作结果如下全局对象console.log(arguments)结果如下在函数外,其指的是全局的,在函数内,其是函数中的参数5 表达式基本表达式和python差不多function  *  inc(){  //使用* 来定义生成器let  i=0;while  (1)yield  (++i);}g=inc()  //实例化生成器console.log(g.next().value,g.next())  //执行生成器调用console.log(g.next().value)console.log(g.next().value)console.log(g.next().value,g.next())结果如下每次调用next()方法返回一个对象,这个对象包含两个属性: value和done,value属性表示本次yield表达式的返回值,done属性为布尔值,done是false表示后续还有yield语句执行,如果执行完成或者return后,none为true。function  *  inc(){let  i=0;while  (true)  {yield  ++i;if (i>3)return i;}}g= inc()console.log(g.next())console.log(g.next())console.log(g.next())console.log(g.next())console.log(g.next())结果如下6 语句块1 概述JS 使用大括号构成语句块ES6 之前语句块是没有作用域的,从ES6开始支持块作用域,let只能在块作用域中可见。2 基础代码function  hello(){let a=1;var b=2;c=3}let d=100if (1){let d=4; //局部和下一级有效,除非被覆盖掉var e=5f=6if (true) {console.log(d)console.log(e)console.log(f)console.log('____________________')g=10  //只要不是函数,都没问题var h=11  //只要是函数,都没问题}}//console.log(a)  //不可见//console.log(b)  //不可见//console.log(c)  //不可见console.log(d)  //不可见  let 突破不了块作用域,但外界共享console.log(e) //var可见console.log(f)  //隐式声明,可见console.log(g) //可见console.log(h)  //可见结果如下3 总结块作用域只对let有效,对var和隐式声明等特性无效函数中var 和 let 都突破不了块作用域向下是穿透的,除非覆盖问题

(0)

相关推荐

  • JavaScript基本语法(全)

    JavaScript JavaScript 是世界上最流行的语言之一,是一种运行在客户端的脚本语言 (Script 是脚本的意思) 脚本语言:不需要编译,运行过程中由 js 解释器( js 引擎)逐行 ...

  • [书籍精读]《你不知道的JavaScript(下卷)》精读笔记分享

    写在前面 书籍介绍:JavaScript这门语言简单易用,很容易上手,但其语言机制复杂微妙,即使是经验丰富的JavaScript开发人员,如果没有认真学习的话也无法真正理解.本套书直面当前JavaSc ...

  • JavaScript基础总结(一)

    值类型(基本类型):字符串(String).数字(Number).布尔(Boolean).对空(Null).未定义(Undefined).Symbol.注:Symbol 是 ES6 引入了一种新的原始 ...

  • Nice!JavaScript基础语法知识都在这儿了

    好好学习,天天向上 本文已收录至我的Github仓库DayDayUP:github.com/RobodLee/DayDayUP,欢迎Star ⭐⭐⭐⭐⭐转载请注明出处!⭐⭐⭐⭐⭐ 链接:https:/ ...

  • 「学习笔记」JavaScript基础

    前言 最近一直在跟着黑马教程学习JavaScript内容,遂把这一阶段的学习内容整理成笔记,巩固所学知识,同时也会参考一些博客,书籍上的内容,查漏补缺,给自己充充电

  • JavaScript

    简介 JavaScript是一门动态弱类型的解释型编程语言.是可插入 HTML 页面的编程代码,插入 HTML 页面后,可由所有的现代浏览器执行.从而增强页面动态效果,实现页面与用户之间的实时动态的交 ...

  • JavaScript表达式和运算符 —— 基础语法(4)

    JavaScript基础语法(4) 运算符 运算符用于将一 个或者多个值变成结果值. 使用运算符的值称为操作数,运算符和操作数的组合称为表达式 JS中的运算符可以分成下面几类: 算术运算符 逻辑运算符 ...

  • 全栈必备JavaScript基础

    1995年,诞生了JavaScript语言,那一年,我刚刚从大学毕业.在今年RedMonk 推出的2017 年第一季度编程语言排行榜中,JavaScript 排第一,Java 第二,Python 反超 ...

  • 小马哥-2020零基础JavaScript基础入门全套教程

    ┃  ┃  ┃  ┣━12-44 hasOwnProperty方法.mp4 ┃  ┃  ┃  ┣━9-5 作用域变量查找的机制(重要).mp4( i+ @) s# M6 w% S, w; M ┃  ┃ ...

  • JavaScript基础知识点总结

    //逗比小憨憨 /*第一章 *HTML引用js方法: *1,外部引用:HTML外部引用js:<script src='js/day1.js'></script> *2,内部引用 ...

  • JavaScript基础ES5/ES6常用数组方法汇总

    一.Array数组常用方法 1.栈方法(先进后出) push():在数组的最后一项后追加值(参数:可以为多个值或数组) 返回:数组的长度,改变了原数组 var a=[1,2,3] a.push(9); ...

  • JavaScript基础-07-DOM

    JavaScript基础-07-DOM

  • JavaScript基础-06-正则表达式

    JavaScript基础-06-正则表达式