基本类型和引用类型的值

  • ECMAscript变量包含 基本类型值和引用类型值
  • 基本类型值值的是基本数据类型:Undefined, Null, Boolean, Number, String
  • 引用类型值是保存在内存空间中的对象,与其他JavaScript不允许直接访问内存中的位置,即不能直接操作对象的内存空间,在操作对象时,实际上是在操作对象的引用而不是实际的对象;为此,引用类型的值是按引用访问的
  • 在很多语言中,字符串以对象 的形式来表示,因此被认为是引用类型的,ECMAScript放弃了这一传统

动态的属性

  • 引用类型的值可以为其添加属性和方法,也可以改变和删除属性和方法
  • 基本类型值不行
var person = new Object();person.name = "Nicholas";alert(person.name);        // "Nicholas"var person = "Nicholas";person.age = 27;alert(person.age);        // undefined

复制变量值

  • 在从一个变量复制向另一个变量复制值时,基本类型值和引用类型值存在不同
  • 基本类型值会在变量对象上创建一个新值,然后把该值复制到为新变量分配的位置上,两个变量可以参与任何操作而不会互相影响
  • 引用类型也会复制一个副本放到新变量中,但这个副本实际上是一个指针,这个指针指向存储在堆中的一个对象,复制操作结束后,两个变量实际上将引用同一个对象,因此改变其中一个变量,就会影响另一个变量
var obj1 = new Object();var obj2 = obj1;obj1.name = "Nicholas";alert(obj2.name);        // "Nicholas"

传递参数

  • ECMAscript中所有函数的参数都是按值传递的,即把函数外部的值复制给函数内部的参数,就和把值从一个变量复制到另一个变量一样
  • 在向参数传递基本类型的值时,被传递的值会被复制给一个局部变量(即为命名参数,或者用ECMAScript的概念来说,就是函数的arguments对象中的一个元素)
  • 在向参数传递引用类型的值时,会把这个值在内存中的地址复制给一个局部变量,因此这个局部变量的变化会反映在函数外部
  • 可以把ECMAScript的参数想象成局部变量
// 参数num是函数的局部变量// 调用这个函数时,变量count作为参数被传递给函数,是将count的值20复制给参数num// 在函数内部,参数num的值加上了10,但不会影响函数外部的count变量,count和num互不影响function addTen(num) {    num += 10;    return num;}var count = 20;var result = addTen(count);alert(count);        // 20, 没有变化alert(result);       // 30
// 以下为个人理解,原著表述不清楚不能直观理解// 传递给参数obj的实际上是指向person对象内存地址(指针),是将地址复制了一个副本赋值给了参数obj// 当在函数内部为obj添加name属性后,函数内部根据地址操作了内存中的相应对象,函数外部的person也将有反映// 因为person指向的对象在堆内存中只有一个,而且是全局对象function setName(obj) {    obj.name = "Nicholas";}var person = new Object();setName(person);alert(person.name);        // "Nicholas"// 下列代码,直觉认为会alert出"Greg",但却是"Nicholas"// 因为传递给参数obj的只是指针的副本,当函数内重新给obj赋值的时候,实际上是将一个新的Object对象的指针赋给obj// 此时操作obj影响的是新的Object对象,而person对象不受影响// obj指向的新Object对象在函数执行完后会立即销毁function setName(obj) {    obj.name = "Nicholas";    obj = new Object();    obj.name = "Greg";}var person = new Object();setName(person);alert(person.name);        // "Nicholas"