Heim > Web-Frontend > js-Tutorial > Hauptteil

JS 基本类型与引用类型值

Guanhui
Freigeben: 2020-05-28 10:30:44
nach vorne
1751 人浏览过

JS 基本类型与引用类型值

引入概念:基本类型和引用类型

1、可以感受到,JS 的变量及其松散,那么,正是 JS 变量松散 的本质,决定了:JS 变量名只是 一个在特定的时间用于保存特定值的一个名字 而已,也就是说,变量的值及其数据类型可以在脚本的生命周期内改变 ,尽管这个功能看起来有趣、强大,但是 JS 变量实际上是比较复杂。

2、ECMAScirpt 变量有两种不同的数据类型:基本类型 和 引用类型,另外还有其他的叫法,比如:原始类型和对象类型、拥有方法的类型和不能拥有方法的类型 等/0

3、将一个值赋值给变量时,解析器 必须确定这个值是基本类型值还是引用类型值

基本类型 指的是简单的数据段,而 引用类型 指的是可能由多个值构成的对象

基本类型:undefined、null、string、number、boolean、symbo(ES6)

引用类型:Object、Array、RegExp、Date、Function

两种类型的区别

存储:

基本类型的值是存放在 栈区 的,即内存中的栈内存

假如有以下变量:

var name = 'jozo';
var city = 'guangzhou';
var age = 22;
Nach dem Login kopieren

那么他们的存储结构如下:(栈区包括了变量的标识符和值)

微信截图_20200528102449.png

引用类型的值是同时保存在 栈内存和堆内存 的

假如有以下对象:

var person1 = {name:'jozo'};
var person2 = {name:'xiaom'};
var person3 = {name:'xiaoq'};
Nach dem Login kopieren

那么他们的存储结构如下:

微信截图_20200528102504.png

访问:

基本类型的值是 按值访问 的,因为可以操作保存在变量中的实际的值。

引用类型的值是 按引用访问 的,因为引用类型的值是保存在内存中的对象,而与其他语言不同的是,JavaScript 不允许直接访问内存中的位置,即不可以直接操作对象的内存空间,那么,在操作对象时,实际上是在操作对象的引用而不是实际的对象。

动态的属性:

对于引用类型的值,很明显,我们可以为其 添加、改变、删除 属性和方法:

var person = new Object();
person.name = "Ozzie";
console.log(person.name);    //"Ozzie"
Nach dem Login kopieren

上述过程中,我们创建了一个对象并为其添加了一个属性,如果对象不被销毁或者这个属性不被删除,那么这个属性将一直存在

但是,我们不可以给基本类型的值添加方法和属性

var name = "Ozzie";
name.age = 19;
consoe.log(name.age);    //undefined
Nach dem Login kopieren

尽管这样操作不会报错,但是仍然会被默默地挂掉

比较:

基本类型的比较是 值的比较 :

例如:

var a = 1;

var b = true;

console.log(a == b); //true

引用类型的比较是 引用的比较 :

例如:

var person1 = {};
var person2 = {};
console.log(person1 == person2);    //false
Nach dem Login kopieren

上文提到过,引用类型时按引用访问的,换句话说就是比较两个对象的堆内存中的地址是否相同,很明显,并不是同一个内存位置:

微信截图_20200528102516.png

复制变量值:

将一个基本类型的值复制给另一个变量,那么,会在新变量上创建一个新值,然后再把该值复制到为新变量分配的位置上:

例如:

var a = 10;
var b = a;
a++;
console.log(a);    // 11
console.log(b);    // 10
Nach dem Login kopieren

a 与 b 是完全独立的,该值只是 a 中的值的一个副本。

基本类型在赋值操作后,两个变量是相互不受影响的:

微信截图_20200528102526.png

那么,复制引用类型的值时,同样也会将一份存储在对象中的值复制到新变量的空间中,不同的是,这个值的副本实际上是一个 指针,指向的是存储在堆中的对象。也就是说,复制结束后,这两个变量将引用同一个对象。

例如:

var a = {}; // a保存了一个空对象的实例
var b = a;  // a和b都指向了这个空对象
a.name = 'jozo';
console.log(a.name); // 'jozo'
console.log(b.name); // 'jozo'
Nach dem Login kopieren

改变其中一个变量就会影响到另一个变量

微信截图_20200528102537.png

传递参数:

请记住,尽管在访问变量时有着按值访问和按引用访问这两种方式,但 ECMAScript 中所有的函数的参数都是按值传递的,即参数只能按值传递,也就是说,把函数外部的值复制给函数内部的参数,就类似于变量之间的值复制一样

基本类型的值的传递如同基本类型的变量的复制,被传递的值会被赋值给一个局部变量(即命名参数,用 ECMAScript 中的概念说,就是 arguments 对象中的一个元素),此处不再赘述…

但是向参数传递引用类型的值时,复制给局部变量的是 内存中的地址,因此这个局部变量的变化会被反映在函数的外部。

例如:

function setName(obj){
      obj.name = "Ozzie";
}
var person = new Object();
setName(person);
console.log(person.name);    //"Ozzie"
Nach dem Login kopieren

我们可以看到,在函数内部,obj 和 person 引用的是同一个对象,换句话说,即使这个变量是按值传递的,obj 也会按引用来访问同一个对象,因为 person 指向的对象在堆内存中只有一个,而且是全局对象。

很多人会 错误地认为:参数是按引用传递的,因为在局部作用域中修改的参数会在全局作用域中反映出来,OK,那么我们再看一个例子:

function setName(obj){
      obj.name = "Ozzie";
      obj = new Object();
      obj.name = "Nicholas"
}
var person = new Object();
setName(person);
console.log(person.name);    //Ozzie
Nach dem Login kopieren

如果是按引用传递参数的,那么显然 person 对象就会在函数内部自动修改 name 属性为 Nicholas,但结果仍然是 Ozzie,这说明,即使在函数内部修改了参数的值,但原始的引用仍然保持不变,实际上,在函数内部重写 obj 时,这个变量的引用就是一个局部对象了,而这个局部对象在函数执行完毕后立即被销毁。

推荐教程:《PHP教程

以上是JS 基本类型与引用类型值的详细内容。更多信息请关注PHP中文网其他相关文章!

Verwandte Etiketten:
js
Quelle:learnku.com
Erklärung dieser Website
Der Inhalt dieses Artikels wird freiwillig von Internetnutzern beigesteuert und das Urheberrecht liegt beim ursprünglichen Autor. Diese Website übernimmt keine entsprechende rechtliche Verantwortung. Wenn Sie Inhalte finden, bei denen der Verdacht eines Plagiats oder einer Rechtsverletzung besteht, wenden Sie sich bitte an admin@php.cn
Neueste Artikel des Autors
Beliebte Tutorials
Mehr>
Neueste Downloads
Mehr>
Web-Effekte
Quellcode der Website
Website-Materialien
Frontend-Vorlage
Über uns Haftungsausschluss Sitemap
Chinesische PHP-Website:Online-PHP-Schulung für das Gemeinwohl,Helfen Sie PHP-Lernenden, sich schnell weiterzuentwickeln!