变数 基础

简单介绍一下变数在JS中的几个性质,之後的篇章会比较深入的讲解,这些性质背後的原因们


看变数的值,决定是数字、字串还是...

var a=1;
var b='2'
var c=function(){return 3}
var d=false

console.log(typeof a);  //number
console.log(typeof b);  //string
console.log(typeof c);  //function
console.log(typeof d);  //boolean

JS不像Java一样用int, String, boolean等关键字宣告变数。
JS的变数在ES6以前只有var,ES6以後也顶多新增了let, const,变数的typeof都需要等到赋值才能决定。

var a;
console.log(a);        //undefined
console.log(typeof a); //undefined

用var宣告变数,初始化为undefined。还没赋值前,无法判断该变数的type

小结论:变数的type,用变数的value判断


var变数的有效范围

有效范围讲的专业一点叫作用域(scope),var变数是遵照 function scope

甚麽是 有效范围 或 作用域

就是变数存在的地方。

有点像寄生物与宿主的关系,寄生物离开宿主多久就会死掉。
变数离开他的作用域,就会被垃圾回收机制给丢掉。灯灯灯灯灯灯灯灯灯,垃圾车来罗~

甚麽是「var变数遵照 function scope

讲人话就是:var关键字令出的变数,他的有效范围以function界定。

console.log('用var关键字 定义变数i')
console.log('--------------------------')

var i='全域变数';
console.log(`i=${i}`);  
//`i=${i}` 等价於 'i='+i 字串连接
// ` 反引号在~键上面 (我一开始还找不到,所以特别写这行)
console.log('--------------------------')

function fun(){
	var i='function内变数';
	console.log(`I'm in the function, i=${i}`)
};
fun(); 
console.log('--------------------------')
        
console.log(`I'm out of the function, i=${i}`);  
console.log('--------------------------')
        
console.log("I'm in the for loop")
for(var i=0;i<5;i++){
	console.log(`i=${i}`) 
}  //i=5离开for回圈
console.log('--------------------------')

console.log(`I'm out of the for loop, i=${i}`); 
用var关键字 定义变数i
--------------------------
i=全域变数
--------------------------
I'm in the function, i=function内变数
--------------------------
I'm out of the function, i=全域变数
--------------------------
I'm in the for loop
i=0
i=1
i=2
i=3
i=4
--------------------------
I'm out of the for loop, i=5

离开for loop後,我们再次呼叫变数i,得到的答案是:5。

原因是for loop 不是function,会影响到在全域var定义的变数i

呼叫自己没有定义的变数

var i='全域变数';
function outterFun(){
	function innerFun(){
			console.log(i)
	}
	return innerFun;
};

aNewFun=outterFun();       
aNewFun();   //全域变数
  • outterFun里面的inner function,找不到变数i → 往外向outterFun
    outterFun找不到变数i →向全域
  • 全域也没有,报错Uncaught ReferenceError: i is not defined

小结论:

  • var变数遵照 function scope
  • function内,叫得到外面的变数;function外,叫不到内变数

属性与变数有仝款某(有一样吗)?

首先先来厘清变数和属性,他们有以下几个关系:

  • 一般情况,变数放在一个object里面,那该变数就会叫object的属性

  • function虽然是一个object,但var变数的作用域(scope)是以function为界,

    所以function外,别想拿到function的内变数

  • function外,如果硬要存取内变数,可以把它从function return出来,变得与function本身同级。

  • function外,可以存取属性。
    没错,你没看错,function可以有属性,因为function是object嘛~~

function aFun(){
        let a='function内变数';
        return a;   //可以透过return,让function外,可以取出内变数
    }
aFun.a='function物件属性';
console.log(`aFun.a= ${aFun.a}`)    // aFun.a= function物件属性
console.log(`aFun return a= ${aFun()}`);   //aFun return a= function内变数

小结论:

  • 可被造访的object属性称为object变数
  • 在function外,不要想直接存取function的内变数,因为var变数遵照 function scope
  • 在function外,可以存取function的属性,或是被return出来的function内变数

提升(Hoisting)简单版

console.log(a);
fun();
console.log('----------')
function fun(){
	console.log(b)
	var b=2;
}
var a=1;

var变数提升:

  • 提到function或全域的顶部
  • 建立(实例化)变数+初始化undefined

function变数提升:

  • 提到function或全域的顶部
  • 整个function body一起提升
    (其实是预编译,没有一起提升,後面的文章会介绍,别急齁~)

在JS眼里,上面那一串的顺序会变成

var a;    //初始化undefined
function fun(){
	var b	 //初始化undefined
	console.log(b)
	b=2;
}

console.log(a);   //undefined
fun();            //undefined
console.log('----------')
a=1;
console.log(a);   //1

练个手感吧

var a='全域a'; 

console.log(`a=${a}`)
console.log(`a=${fun('实参')}`)
outerfun();
fun1();
          
function outerfun(){
	a='在outerfun中改a值'
	var a='outterfun a'
	for(var a=0;a<5;a++){
		console.log(`a=${a}`?)
		a='for loop里面的a'
		console.log(`a=${a}`)
	}
	console.log(`a=${a}`);
	function innerfun(){
		console.log(`a=${a}`);
	}
	innerfun();
}

function fun(a){
	return a;
}
function fun1(){
	a='在fun1中改a值'
}

console.log(`a=${a}`)

小提醒:变数前面没写var,要嘛是引用自己或是引用外层的变数,
要嘛就是新建全域变数,但这种不会提升

.

.

.

.

.

.

.

.

.

.

.

a=全域a
a=实参
a=0
a=for loop里面的a
a=NaN
a=NaN
a=在fun1中改a值
//模拟:for回圈里的a
var num='我是字串,我要先被加1,再被转成number'
num+=1                  //'我是字串,我要先被加1,再被转成number1'
num =Number(num)        //string转number
console.log(num)        //NaN
console.log(typeof num) //number

//模拟:判断是否离开for回圈
//句型:(判断句)?true执行:fales执行
console.log((NaN<5)?'yes':'no')  //no,离开for回圈

a在各个function scope中,被改值的过程

  • 全域的a:'全域a'
    →'在fun1中改a值'
  • fun的a:'实参'(参数值)
  • outterfun的a:'在outerfun中改a值'
    →'outterfun a'
    →a=0
    →'for loop里面的a'
    →NaN(字串加1,再转number)
  • innerfun的a:NaN(引用outerfun的)

<<:  DAY13 - [JS] 重新改写ToDoList

>>:  [Day 13] 资料产品生命周期管理-加工资料(二)

Day-28 Virtual Memory

Virtual Memory tags: IT铁人 跟上一篇有点关系的内容,我们会利用Disk来代替...

[Day24] Flutter - Application Login (part8)

前言 Hi, 我是鱼板伯爵这里我们要将Google登入与介面做连接,所以又要使用Bloc了,老样子按...

第16天~ListView

Spinne-下拉式选单 跟ListView很像但是比较小 ListView单选+或选到很多样 ac...

初学者跪着学JavaScript Day24 : 原型不会,但你还有class

一日客语:中文:蛋 客语:唇 ES6语法 是constructor function 一种语法糖 函...

Material UI in React [Day5] Theme ( Spacing & Breakpoints & z-index)

今天会接续昨天的部分继续讲解 Theme 的 Spacing,这部分其实很简单各位可以透过这里直接引...