js基础-5-数据类型,作用域,优先级

一,数据类型及其判断

基本(值)类型
Number ----- 任意数值
String ----- 任意字符串
Boolean ---- true/false
undefined — undefined
null -------- null
** 对象(引用)类型**
Object ----- 任意对象
Array ------ 数组(特别的对象)
Function ----函数(特别的对象)
二,数据类型的判断
1>基本类型
1,typeof (a);返回数据类型的字符串表达
可以判断undefined/数值/字符串/布尔值/function
但是不能判断null与object, 与array(返回值都是object)
2,a instanceof Object ;判断对象的具体类型(a是不是Object的实例)
3,=== 可以判断undefined和null

//number
console.log(typeof NaN)
console.log(typeof 1)
//string
console.log(typeof 'NaN')
//underfined
console.log(typeof a)  //变量未定义,underfined
//boolean
console.log(typeof false)
//object
console.log(typeof [])   //这三种都是返回Object
console.log(typeof {
    
    })
console.log(typeof null)
//注意
console.log(typeof Object)   //function
console.log(typeof Array)
console.log(typeof Function)

二,for循环中的i值问题

for(var i=0;i<3;i++){
    
    
	setTimeout(function(){
    
    
		console.log(i)
	},1000*i)
}
//输出的结果会是三个3(第0秒,第1秒,第3秒)

这里的for操作是同步,而setTime是异步,放置在队列中等同步的for循环执行完毕之后才执行,而这里i是全局变量,已经变成3了。
把var换成let就可以,let声明多个 i ,i = 0,i = 1…每个 i 只对当前的区域有效。

三,for循环的理解

var x
for (var i=0,j=0;i<6,j<10;i++,j++){
    
    
	x=i+j
}
console.log(x)  //18

for循环的执行顺序是:初始条件–》条件判断(有一个满足则继续执行)–》语句体–》终止条件
所以说,最后的结果是18,for循环结束后的i和j的值都是10。

四,作用域和变量提升

1,函数内部会产生局部作用域,作用域内要查找变量时,顺着作用域由内向外查找。
2,每个作用域内通过var和function定义的数据存在变量提升,提升的优先级:前变量>函数>参数>(后变量)提升,但是变量最高有个前提是,它在调用前定义好。
3,而同一优先级别时,后写的会覆盖前面写的。
关于第一点:

	<script type="text/javascript">
	   var a=3
	   function fn(){
    
    
		   console.log(a)   
		   var a=4    //变量提升,相当于先定义,但是未赋值
	   }
	   fn()   //undefined
		</script>

关于第二,三点:

			function fn(bar){
    
    
				var bar=3   //变量优先级最高,如果有这行,则是3,但是,它必须写在调用之前,改成var bar就不行了,就会显示函数2
				console.log(bar)
				var bar=3    //优先级最低,如果只有它。则是var bar提升,underfined
				function bar(){
    
    
					return '函数1'
				}
				function bar(){
    
    
					return '函数2'
				}          //函数的优先级第二,并且两个函数优先级别一样,后写的覆盖之前的
			}
			fn(5)       //实参的优先级第三
			var foo=function(){
    
    
				console.log(444)
			}
			function foo(){
    
    
				consloe.log(2)
			}
			foo()  //444//在调用前就定义好,因为第二个是变量,优先级更高,不是同一优先级,就不考虑覆盖的问题
			foo()  //虽然是变量,但是它在调用之后才定义,不考虑,后一个函数用function定义,存在变量提升,故而是它
			var foo=function(){
    
    
				console.log(444)
			}
			function foo(){
    
    
				console.log(2)
			}

五,关于变量提升的总结

1,前变量>函数>参数>(后变量)提升,同一个作用域下,记住这个顺序就可以了。
2,只有在后续只有后变量提升的情况,才会去考虑把var a=1,拆分成var a,后续a=1的情况。其他时候不要拆分,用第一点理解。
第一种情况:

			function fn(bar){
    
    
				 var bar=3   
				console.log(bar)     //这里前变量出现,直接最高优先级,打印3
				var bar=5    
				function bar(){
    
    
					return '函数1'
				}
				function bar(){
    
    
					return '函数2'
				}    
				console.log(bar)   //前变量出现两次,它优先,于是不看函数,两个前变量优先级一样,后者覆盖前者,故打印5
				var bar=function(){
    
    
					return '函数3'
				}          
				console.log(bar)   //依旧是前变量出现,最后一个覆盖之前的前变量,打印函数3
			}
			fn(6)  

第二种情况:

			function fn(bar){
    
    
				//var bar=3
				console.log(bar)     //没有前变量出现,则函数优先级最高,后面的函数覆盖前面。打印函数2
				var bar=5    
				function bar(){
    
    
					return '函数1'
				}
				function bar(){
    
    
					return '函数2'
				}    
				console.log(bar)   //前变量出现一次,它优先,于是不看函数,两个前变量优先级一样,后者覆盖前者,故打印5
				var bar=function(){
    
    
					return '函数3'
				}          
				console.log(bar)   //依旧是前变量出现,最后一个覆盖之前的前变量
			}
			fn(6)  

第三种情况:

			function fn(bar){
    
    
				//var bar=3
				console.log(bar)     //没有前变量和函数,则参数优先级最高,打印参数6
				var bar=5    
				// function bar(){
    
    
				// 	return '函数1'
				// }
				// function bar(){
    
    
				// 	return '函数2'
				// }    
				console.log(bar)   //前变量出现一次,它优先,于是不看参数,故打印5
				var bar=function(){
    
    
					return '函数3'
				}          
				console.log(bar)   //依旧是前变量出现,最后一个覆盖之前的前变量
			}
			fn(6)   

第四种情况:

			function fn(){
    
    
				//var bar=3
				console.log(bar)     //没有前变量,则函数优先级最高,打印函数1
				var bar=5    
				function bar(){
    
    
					return '函数1'
				}
				// function bar(){
    
    
				// 	return '函数2'
				// }    
				console.log(bar)   //前变量出现一次,它优先,于是不看函数,故打印5
				var bar=function(){
    
    
					return '函数3'
				}          
				console.log(bar)   //依旧是前变量出现,最后一个覆盖之前的前变量,打印函数3
			}
			fn() 

第五种情况:

function fn(){
    
    
				//var bar=3
				console.log(bar)     //没有前变量和函数,也没有参数,则后变量提升,这时候才会去拆分var a,于是打印underfined
				var bar=5    
				// function bar(){
    
    
				// 	return '函数1'
				// }
				// function bar(){
    
    
				// 	return '函数2'
				// }    
				console.log(bar)   //前变量出现一次,它优先,于是不看函数,故打印5
				var bar=function(){
    
    
					return '函数3'
				}          
				console.log(bar)   //依旧是前变量出现,最后一个覆盖之前的前变量,打印函数3
			}
			fn()       

于是:

 var c = 1
  function c(c) {
    
    
    console.log(c)
  }
  c(2) // 报错c is not a function,因为有前变量存在,故c是1,不是函数。

六,var const let的区别

1.var定义的变量可以修改,如果不初始化会输出undefined,不会报错。
2,const定义的变量不可以修改,而且必须初始化。是块级作用域
3,let是块级作用域,函数内部使用let定义后,对函数外部无影响。
4,let 和 const 都是块级作用域,以{ }代码块作为作用域范围,只能在代码块里面使用
不存在变量提升,只能先声明后使用,否则会报错,在代码块内,声明变量之前,该变量都是不可用的,这个在语法上,叫做暂时性死区
在同一个代码块内,不允许重复声明
const声明的是一个只读的常量,在声明时就需要赋值,如果const声明的是一个对象,对象所包含的值是可以修改的,抽象点说就是,对象所指向的地址不能改变,而变量成员是可以修改的

猜你喜欢

转载自blog.csdn.net/weixin_42349568/article/details/108977048