JavaScript

深入了解javascript(二)

2017-04-06  本文已影响31人  南蓝NL

在上篇的深入了解javascript(一)当中留过一个问题

源代码是和结果这样的  

注意两张图片的区别。

因为test()函数内部a=100,没有var关键字,则变量a添加到全局环境(全局变量a=10变为吖00)当中,而this指向window对象,所以结果是100 100 100 这里和上面的区别就是test()函数内部用了一个var 关键字声明变量,那么这个变量就是被添加到最近的环境当中(局部环境),而this还是指向window对象,所以结果会是100 10 10 这段代码和上面两段代码都有点不一样,区别在于调用的方式不一样,用了一个构造函数的方式去调用,不是向上面两段代码的直接调用。this的指向发生改变,指向刚刚new出来的对象,不是window对象,所以结果是10  100 10,如果改成var a=100结果是100 undefined 10   如果是 a=100; 结果是 100 undefined 100

变量、作用域和内存的问题

1、js分为基本类型和引用类型,1)基本类型包括null、undefined、string、number、boolean,这些基本类型的值可以直接操作保存在变量中实际的值    2)而js不能直接操作对象的内存空间,实际操作的是对象的引用(地址),常见的引用类型object 、function、array、date、RegExp、Error

2、定义引用类型(对象,以下称为对象),创建的方法与基本类型一致,都是创建一个变量对象围棋赋值,但它们的区别是,对象有自己的属性和方法,如果对象不销毁的话,其属性将一直存在。比如 var person=new Object();  person.name="nanlan";     alert(person.name);

3、传递参数。ECMAscript当中所有函数的参数只能通过值传递,而其他的则有按值传递和引用传递。比如:

1)基本类型的值传递

function sum(num){

   num+=10;    return num;

}

var count=20;

var result=sum(count);

alert(count);       //20; 沒有变化        alert(result);  30

基本类型的按值传递参数相对来说比较简单,下面我们看看对象的参数传递

2)引用类型(对象)的值传递

function   setname(obj){

obj.name="nanlan";

}

var person = new Object();

person.name= "xiaoju";

setName(person);

alert(person.name);        //nanlan

特地敲了一遍

看到了没,基本类型和引用类型的区别,这是因为setName函数里面的obj和person指的是同一个对象(在堆内存当中),而且是全局对象。很多人会觉得局部作用域中修改参数在全部函数中体现出来,就是按引用传递,为了证明是按值传递的,我们再看看以下的例子

有些人会觉得答案是”xiaoju“,其实不是

如果person是按引用传递的,那么obj就会自动被修改指向新的属性会”xiaoju“,但是原始的值依然不变,这是因为函数内部重写obj,就是一个局部对象,而函数结束之后,局部对象就会被销毁

4、检测类型

typeof 变量名(基本类型)   ,我们还可以使用instanceof检测引用类型,但是引用类型的值都是object的实例,那还用instanceof干嘛用,其实我们并不是想知道他是是对象,而是想知道他是什么类型的对象,语法为 : 变量  instanceof array /object/RegExp等,意思就是某个变量是数组吗/对象吗。

在检测引用类型和Obejct的构造函数时,instanceof通常都会返回ture,但是如果是基本类型的话,则会返回false,因为基本类型不是对象

测试了一下

5、執行环境以及作用域

1)全局执行环境被认为是window对象,某个执行环境中的所有代码执行完毕后,该环境被销毁,保存在其中的所有变量和函数定义也随之销毁(全局变量等到这个应用程序结束之后或者浏览器关闭才会被销毁)

2)全局执行环境的变量对象始终都是作用域链中最后一个对象,举个例子来说

var color = ”blue“;

function  changecolor(){

  var another = "red";  

      function swapcolor(){

      var   tempcolor = anothercolor;

anothercolor = color;

color =tempcolor;

//这里可以访问 color、another、 tempcolor

    }

//这里可以访问 another、color

swapcolor();

}

//这里只能访问 color

changecolor();

以上的代码说明一个问题:外部的环境不能访问内部环境的函数和变量,但是内部环境可以访问外部环境(函数有时也会被当作变量来定义)

6、没有块级作用域

值得注意的是,在js当中,如果用if语句声明的变量将会添加到当前执行的环境(全局环境),比如说 if(ture){

var color = "blue";

},而在C、C++、Java当中if语句声明的变量会在if语句结束之后销毁

1)声明变量,var 声明的变量自动被添加到最接近的环境当中;在函数内部,最接近的环境就是局部环境;而在with语句当中,最接近的环境就是函数环境。如果初始化没有用var 关键字声明的话,则这个变量会被添加到全部变量当中

2)查询标识符,搜索的过程从作用域链的前端开始,向上逐级查询与给定名字匹配的标识符,如果在局部环境当中知道了该标识符,搜索过程停止;如果没有找到的话,则向上沿作用域链向上搜索一直到全局变量,如果还是没有,则没有定义

上一篇下一篇

猜你喜欢

热点阅读