首页 > 代码库 > js基础--javascript基础概念之变量与作用域

js基础--javascript基础概念之变量与作用域

js基础--javascript基础概念之变量、作用域

javascript按照ECMA-262 的定义,变量与其他语言变量有所不同。js变量时松散的,不需要事先定义变量类型的。这使得他只是一个保存特定值的一个名称。变量与其数据类型可以在脚本的生命周期内改变。

还有明白几点:

JavaScript的变量作用域是基于其特有的作用域链的,JavaScript没有块级作用域。


基本类型和引用类型的值

ECMAScript 的变量有两种不同的数据类型;分别是 基本数据类型值 和 引用类型值 : 


基本数据类型值

是指简单的数据段,

如 string number boolean undefined null 等都是简单是数据类型



引用类型值

是指由多个值构成的对象

object 是引用数据类型




动态的属性

定义基本类型的值和引用类型的值方式是类似的。创建一个变量并未变量赋值,但是赋了不同类型值之后,这个变量的意义就发生了巨大的变化。如:

var str = ‘hello‘;//自动形成String类型
var obj = new Object();//Object 类型


定义了两个类型的变量。一个是简单类型的,一个是object类型的值。当你进行以下操作时:


str.name = ‘kin‘;
obj.name = ‘kin‘;
alert(str.name);//undefined
alert(obj.name);//kin



通过给刚定义的变量添加属性。给string 类型的变量添加属性时并没有发生错误。但是访问是确实是未定义的状态。而引用类型的正常访问。这说明了只能够给引用类型的变量添加动态的属性。


关于变量声明

js声明变量有两个方法;一种是隐式声明,显式声明

var str = ‘hello‘;//显式声明
hid = ‘hello‘;//隐式声明


在外围作用域中,使用var关键字声明的显式变量被js引擎认为是全局变量。而在函数内使用var 定义的显式变量被认为是函数的局部变量。

事实上使用var定义的变量都是局部变量,在乎于作用域的问题。在外围作用域,被视为全局变量。在函数作用域 被视为局部变量。

当你访问一个没有赋值的变量是  js会报错,但是你给一个没有定义的变量赋值:

hid = ‘hello‘;


js会认为你在进行隐式声明一个变量。


隐式和显式定义变量会有什么不同呢?

显式定义后的变量不能够操作delect  如:

var str = ‘hello‘;
hid = ‘hi‘;
alert(delete str);//false
alert(delete hid);//true
alert(str);//hello
alert(hid);//undefined



全局变量和局部变量

在js解析器开始执行时,会在执行环境里建一个全局对象。在全局对象里面所定义的变量都是全局变量。因此,在顶层的代码里我们可以使用this window 等对象去访问这些变量:

var str = ‘string‘;
alert(this.str);//string
alert(window.str);//string
function fun(){
alert(window.str);//string
alert(this.str);//string
}
fun();


使用this  和 window 关键字可以对全局变量进行访问。可以直接访问


var Num = 100;//定义全局变量
function R_Num(){
alert(Num);//在函数作用域中访问全局变量
}
R_Num();



复制变量


在js中  如果你要复制变量。非常简单如:

var  str = ‘string’;
var  str1 = str;//此时 str1 等到了和str 一样的值;


在str 中保存的是字符串 string  定义str1 时使用str 来初始化。因此,str1 中也保存了str 相同的值。而str1 中的值是完全独立的,换句话说  就算你把str 删除 对str1 是没有任何影响的。可以说str1 是str 的一个副本。


例图:


标示符
strstring



复制之后:开辟了一块新的空间保存str1

标示符
strstring
str1 string



复制引用类型的变量。实质上是复制引用类型的指针。如

var  obj = new  Object(); 
var  obj2 = obj;


wKioL1PGgFbj4JLEAAExYtNRVbQ363.jpg


他们指向同一个引用类型。



传递参数


前面说道 js中传递到函数去的值都是保存的一个arguments 对象中去的。 所以,当有传递变量时同样涉及到把一个变量赋值到另外一个变量中去,如:

var num = 100;
function addTen(num){
return num = num+100;//函数中改变了num变量。
}
alert(addTen(num));//200
alert(num);//100


在函数内将num值改变了。

但是当回到外围作用域使用alert(num)时值依然是原来的值没有变化。说明当传递参数给函数时参数只是将num 复制传递到函数体内  函数中使用的只是外围作用域中num的副本。所以,在函数内部num改变都不会影响到函数外的num。

当传递的值是引用类型时。

如:

var obj = {
name:‘kin‘,
age:‘20‘
};
function changeName(obj){
return obj.name = ‘chen‘;
}
var newName = changeName(obj);
alert(newName);//chen
alert(obj.name);//chen


引用类型的值完全发生了变化  外围作用域中obj 的 name属性从原本的kin 改变成了chen 原因是传递给函数的值是这个引用类型的指针,函数根据这个指针改变了相应的obj属性。因此,obj的属性从根本上被改变了。