新手总结,关于JavaScript中var a = b = c;的拆解

目录

  • 一、问题的起源
  • 二、解释问题的方式工具
    • 原理一:预解析
    • 原理二:隐式全局变量
    • 原理三:两个变量同时指向一个对象,那么对这个对象的修改是同步
  • 三、拆解var a = b = constant的声明与赋值
    • 1. 利用预解析拆解var a=b=constant的声明
    • 2. 利用隐式全局变量拆解var a=b=constant的var声明
    • 3. 利用方式三拆解var a = b =contant的赋值方式
    • 4. 最后拆解var a = b = contant的结构

一、问题的起源

我是一名刚入门学习web前端开发的新手,最近在学习JS,被一堆预解析的题目弄得一愣一愣的,为了解答迷惑,我经过搜索+调试,大致得到了一下结论。

二、解释问题的方式工具

原理一:预解析

先说说什么叫预解析
预解析,是指在正式执行js代码之前,进行的一些解析工作。他会在全局中寻找关键字var声明的变量和关键字function声明的函数。

CSDN文章:JavaScript预解析的一些理解

我们写一段代码加以理解:

console.log(a); //undefined
console.log(b); //undefined
console.log(f1); //函数代码段
console.log(x); //报错

var a = 1;
var b = {n:1};
x = 1;
function f1(){
	console.log("我被预解析了");
};

由a、b、f1可见,var和function的声明是被提前了,而赋值没有提前,其中f1函数中也有代码内容;再由x验证,赋值确实没被提前。

原理二:隐式全局变量

我们知道,JS语言中,在函数内var声明的为局部变量,之外的用var声明的变量都为全局变量。
其中有个特殊的叫隐式全局变量,即没有使用var声明直接赋值。

var a = 1; //全局变量
function f1(){
	var b = 1; //局部变量
	c = 1; //隐式全局变量
}
//在这里可以打印a和c,但不能打印b
delete c; //全局变量与隐式全局变量的不同之处在于隐式变量可以删除,而全局变量不行。

原理三:两个变量同时指向一个对象,那么对这个对象的修改是同步

CSDN文章:JS中连等赋值操作使用注意事项(a=b=c)

我们写两段代码加以理解:
我自己的理解我就不再码字出来了,都在调试的程序里的注释中。

// 若两个对象同时指向一个对象,那么对这个对象的修改是同步的.
console.log("f1============================");
function f1(){
	var a = {n:1};
	var b = a;
	b.n = 0;	// 这里即便改b.n为a.n, 打印结果也一样
	console.log(a);//Object {n:0}
	console.log(b);//Object {n:0}
}
f1(); //a、b指向同一个对象,可能是向C语言的指针一样指向同一个地址吧

//若干不指向同一个对象,那么修改其中一个不会影响另一个
console.log("f2============================");
function f2(){
	var a = {n:1};
	var b = {n:1};
	a.n = 0;
	console.log(a);//Object {n:0}
	console.log(b);//Object {n:1}
	//互不影响a和b的打印结果
}
f2(); //a、b指向不同对象

由此得到结论,两个变量同时指向一个对象,那么对这个对象的修改是同步。

三、拆解var a = b = constant的声明与赋值

1. 利用预解析拆解var a=b=constant的声明

这里我们利用预解析的原理进行判断,就是在var a=b=constant;语句之前打印a或b变量。

  1. 设想1:分别声明
console.log(a); //undefined
console.log(b); //undefined
var a;
var b;
  1. 设想2:只是声明了其中一个
console.log(a); //undefined
console.log(b); //报错
var a;
a = b =1 ;
  1. 验证
console.log(a); //1
console.log(b); //报错,说明没有用var定义b
var a = b = 1;

由此可见var a = b = constant; 中var只声明了a,没有声明c。

2. 利用隐式全局变量拆解var a=b=constant的var声明

 //按下按钮,错误
 //按下按钮,Object{n:1}
 //按下按钮,删除b,再按上方按钮则报错
 //按下按钮,错误
 //按下按钮,5
 //按下按钮,删除y,再按上方按钮则报错


由此可见var a = b = constant; 中var只声明了a,没有声明c。

3. 利用方式三拆解var a = b =contant的赋值方式

有三个赋值方式设想:

设想一,分别将contant赋值给a和b
a = contant;
b = contant;
//根据原理三,无论更改a或b,都不会影响另一个的打印结果。

设想二,先赋值给b再由b给a
b = contant;
a = b;
//根据原理三,更改a、b其中一个,另一个的打印结果也随之改变。

设想三,在设想二的基础上,a和b置换。
(其实根据前文的var a=b=c的声明方式结论,可以知道设想二成立。)

验证:

function f4(){
	var a = b = {n:1};
	a.n = 0;
	console.log(a); //Object {n:0}
	console.log(b); //Object {n:0},打印结果被影响
}
f4();

由上代码可以看出,a和b指向同一个对象,这说明设想二和三成立。

4. 最后拆解var a = b = contant的结构

由前文的1.2.3.可以知道,var a = b = contant
其声明方式:只声明前者a;
其赋值方式:先把contant赋值给b,再由b赋值给a。
最后利用隐式全局变量可以删除而,全部变量不可以删除,再来一段代码验算这个结论:

function f4(){
	var a = b = {n:1};
	a.n = 0;
	console.log(a); //Object {n:0}
	console.log(b); //Object {n:0}
	
	delete a;
	delete b;
	console.log(a); //Object {n:0},即无法删除
	console.log(b); //报错,即被删除
}
f4();

故var a = b =contant可拆解为

var a;
b = contant;
a = b;

你可能感兴趣的:(Web前端学习,连续赋值,javascript,拆解,var声明)