Javascript之原始值与引用值,函数创建的三种方式
原始值与引用值
原始值
(1)原始值指的是 原始类型 的值,也叫 基本类型,例如 Number、Stirng、Boolean、Null、Underfined 。
(2)存储在栈(stack)中的简单数据段,也就是说,它们的值直接存储在变量访问的位置。
(3)在许多语言中,字符串都被看作引用类型,而非原始类型,因为字符串的长度是可变的。ECMAScript 打破了这一传统。
引用值
(1)引用值指的是 引用类型 的值,例如 Object、Function、Array、Date、RegExp 。
(2)存储在堆(heap)中的对象,也就是说,存储在变量处的值是一个指针(point),指向存储对象的内存处
原始值存储在栈中
原始变量及他们的值储存在栈中,当把一个原始变量传递给另一个原始变量时,是把一个栈房间的东西复制到另一个栈房间,且这两个原始变量互不影响。
引用值存储在堆中
引用值是把引用变量的名称储存在栈中,但是把其实际对象储存在堆中,且存在一个指针由变量名指向储存在堆中的实际对象,当把引用对象传递给另一个变量时,复制的其实是指向实际对象的指针,此时 两者指向的 是同一个数据,若通过方法改变其中一个变量的值,则访问另一个变量时,其值也会随之加以改变;但若不是通过方法 而是通过 重新赋值 此时 相当于 重新开了一个房间 该值的原指针改变 ,则另外一个 值 不会随他的改变而改变。
原始值和引用值的不同
- 赋值方式
- 值是否可变
- 比较方式不同
赋值方式和值是否可变
- 原始值是以值的拷贝方式赋值,值是不可变的。
- 引用值是以引用的拷贝方式赋值,值是可变的。
示例:
//原始值
var a=1;
var b=a;
a=2;
document.write(b); //1
//引用值
var arr1=[1];
var arr2=arr1;
arr1.push(2);
document.write(arr2); //1,2
说明
(1)原始值赋值 → 其实是将值拷贝一份并赋值给新的变量,这个值就是副本,他和原始值是互相独立的,改变其中一个值不会影响到其他的值。
(2)引用值赋值 → 当一个引用类型,例如一个对象,使用 = 将其赋值给另一个变量,实际上是其对象的地址引用赋值给新的变量,这两个变量都指向同一个地址引用,他们有相同的地址。所以若改变其中一个变量(的地址引用指向的对象),另一个变量(的地址引用指向的同一个对象)也将改变。
比较方式不同
- 原始值的比较是 值 的比较
- 引用值的比较是 引用 的比较
示例:
//原始值
var a=1;
var b=true;
console.log(a == b); //true
console.log(a === b); //false
//引用值
var boj1={};
var boj2={};
console.log(obj1 == obj2); //false
console.log(obj1 === obj2); //false
说明:
(1)原始值 a 和 b 的数据类型不同,但也可以进行值的比较。(在值比较之前,自动进行了数据类型的 隐式转换)
== → 只比较值
=== → 不仅比较值,还比较数据类型
(2)引用值 obj1 和 obj2 分别引用的是存放在堆内存中的两个不同的对象,所以 obj1 和 obj2 的值(地址引用)不一样。
函数创建的三种方式
创建函数的三种方式:
-
构造函数
-
函数声明
-
函数表达式
1.构造函数
//创建一个函数对象
//可以将要封装的代码以字符串的形式传递给构造函数
var fun = new Function("console.log('hello 这是我的第一个函数');");
//封装到函数中的代码不会立即执行
//函数中的代码会在函数调用的时候执行
//调用函数 语法:函数对象()
//当调用函数时,函数中封装的代码会按照顺序执行
fun();
fun();
fun();
2.函数声明
语法:
function 函数名([形参1,形参2. . .形参N])
{
语句. . .
}
示例:
function fun2(){
console.log("函数声明");
}
//调用函数
fun2();
3.函数表达式
语法:
var 函数名 = function([形参1,形参2. . .形参N])
{
语句. . .
}
示例:
var fun = Function()
{
"console.log('我是匿名函数中封装的代码');"
};
fun();