js变量和作用域

 

 基本集类型的值和引用类型的值

     5种基本数据类型:Undefined、Null、Boolean、Number和String,这5种基本数据类型是按值访问的,因为可以操作保存在变量中的实际的值。

动态属性:

我们创建了一个对象并将值保存在了person中,然后为这个值添加属性。对象不销毁则这个值一直存在。

var person = new Object();
person.name = "Nicholas";
alert(person.name);  //"Nicholas"

 但是我们不能给基本数据类型添加属性,比如:

var name = "Nicholas";
name.age = 27;
alert(name.age);    //undefined

复制变量:

 从一个变量向另一个变量复制基本数据类型时,会在变量上创建一个新的对象。他们的值是不会相互影响的。例如:

var num1 = 5;
var num2 = num1;
num1 = 10;
alert(num1);    //10
alert(num2);    //5

 从一个变量向另一个变量复制引用类型时,这个值实际上是一个指针,两个变量实际上引用的同一个对象。例如:

var obj1 = new Object();
var obj2 = obj1;
obj1.name = ”Nicholas“;
alert(obj2.name);    //"Nicholas"
扫描二维码关注公众号,回复: 253124 查看本文章

参数传递:

在向参数传递基本数据类型的值时,被传递的值会被复制给一个内部变量(即命名参数,就是arguments对象的一个元素)。例如:

function addTen(num){
    num += 10;
    return num;
}
var count = 20;
var result = addTen(count);
alert(count);    //20
alert(result);    //30
 在向参数传递引用类型的值时,这个值的内存地址复制给一个内部变量。例如:
function setName(obj){
    obj.name = "Nicholas";
}
var person = new Object();
setName(person);
alert(person.name);    //Nicjolas
 以上代码创建了一个对象,person和obj引用了同一个对象。于是,当在函数内部为obj添加name属性时,外部的person也将改变;下面例子说明了参数是按值传递的,而不是按引用类型传递:
function setName(obj){
    obj.name = "Nicholas";
    obj = new Object();
    obj.name = "Greg";
}
var person = new Object();
setName(person);
alert(person.name);    //Nicjolas
 函数内部修改了参数的值,但原始引用让然保持不变。实际上,当函数内部重写obj时,这个变量引用的就是一个局部对象了,这个局部对象在函数执行完后立即被销毁。

类型检测:

要检测一个变量是不是基本数据类型,typeof操作符是最佳工具。

var s = "Nicholas";
var b = true;
var i = 22;
var u;
var n = null;
var o = new Object();

alert(typeof s);    //string
alert(typeof b);    //boolean
alert(typeof i);    //number
alert(typeof u);    //undefined
alert(typeof n);    //object
alert(typeof o);    //object
 检测引用类型的值时,ECMAScript提供了instanceof操作符,语法如下:
alert(person instanceof Object);    //true
alert(colors instanceof Array);     //true
 检测对象时始终返回true ,检测基本类型时返回false。

执行环境和作用域:

全局执行环境是最外层的一个执行环境,在Web浏览器中,全局执行环境是window对象。

var color = "blue";
function changeColor(){
    var anotherColor = "red";

    function swapColors(){
        var tempColor = anoterColor;
        anotherColor = color;
        color = tempColor;
        
        // 这里可以访问color、anotherColor和tempColor
    }
    // 这里可以访问color和anotherColor,但是不能访问tempColor
    swapColor();
}

// 这里只能访问color
changeColor();
 延长作用域链:

try-catch语句catch块 和 with语句。两个语句都会在作用域链的前端添加一个变量对象。

function buildUrl(){
    var qs = "?debug=true";

    with(location){    //接收location对象
        var url = href + qs;
    }

    return url;
}

try{
   ... 
}catch(e){
   alert(e);    //被抛出的错误对象 
}
 with语句中引用变量href时,实际上是location.href,(可以使用location对象里边的所有属性和方法)。

没有块级作用域:

例子:

if (true) {
     var color = "red";
}

alert(color);    // red
 for循环中的变量:
for (var i = 0; i < 10; i++) {
   doSomething(i);
}

alert(i);    // 10
 有for循环创建的变量i即使在循环结束后,依旧存在于循环外部的执行环境中;

变量声明:

// 使用var声明的变量
function add(num1, num2){
    var sum = num1 + num2;
    return sum;
}

var result = add(10, 20);
alert(result);    //30
alert(sum);      //这里会抛出错误

// 没有var声明的变量
function add(num1, num2){
    sum = num1 + num2;
    return sum;
}
var result = add(10, 20);
alert(result);    //30
alert(sum);    //30

 使用var声明变量会添加到最近的作用域中,否则将会添加到全局作用域中。

猜你喜欢

转载自y328771518.iteye.com/blog/2397129
今日推荐