Value Types(值类型、元值)
- Number
- String
- Boolean
- Symbol
- undefined
- null
Reference Types(引用值)
- Object
- Function
- Array
let x = 10;
let y = x;
x = 20;
//x 20
//y 10
如果我们使用一个引用类型或对象
let x = { value: 10 };
let y = x;
x.value = 20;
//x { value: 20 }
//y { value: 20 }
通过这两个例子,我们可以看出区别。
当我们使用对象的时候,对象不存储在变量里,对象存储在内存里的一个其他的地方,然后对象在内存中的地址存储在变量里(如变量x其实存储的是对象{ value: 10 }在内存中的地址),所以当我们拷贝x到y的时候,是这个内存地址被复制过去了。因此,x和y实际上是指向的同一个内存地址,我们不管是从x还是y去修改这个对象的时候,这种改变都将立即在另一个变量中体现出来。
结论:值类型复制值,对象和引用类型复制引用
另一个例子:
let number = 10;
function increase(number) {
number++;
}
increase(number);
console.log(number); //10
我们可以看到输出的是10,但我们不是+1了吗?
其实,当我们调用increase函数并传入number变量的时候,这个值被复制到函数的本地参数number里面,所以这个number变量与外面的number变量是完全无关的,increase函数运行结束,函数内的numer变量就不在作用域中了。所以输出还是为10。
现在我们把它转换为一个引用类型对象。
let obj= { value:10 };
function increase(obj) {
obj.value++;
}
increase(obj);
console.log(obj); //{ value:11 }
从输出我们可以看到,obj的值被改变了,这样的原因是,当我们调用increase函数并且传入obj这个对象,这个对象以引用的方式传递,所以在这个例子中,我们操作的不是两个独立的个体,我们操作的是两个不同变量所指向的同一个对象。
JavaScript中可以动态地添加或删除属性:
function Circle(radius) {
this.raadius = radius;
this.draw = function() {
console.log('draw');
}
}
const circle = new Circle(10);
//新增属性
circle.location = { x: 1 }
const propertyName = 'center location';
circle[propertyName] = { x: 1};
//删除属性
delete circle['location'];//这里我们同样可以使用'.'操作符和'[]'操作符
我们可以看到,点操作符写法比方括号简单点,但是方括号在实际场景中也是很有用的,例如我们想要动态地访问一个属性名,或者我们使用的属性名称不符合语法规则的时候(例如包含-或者空格),就可以使用方括号来访问。
网友评论