共计 2338 个字符,预计需要花费 6 分钟才能阅读完成。
数据类型
- ECMAScript 变量蕴含两种不同类型的值:根本类型值、援用类型值;
- 根本类型值:指的是保留在 栈内存中的简略数据段;
- 援用类型值:指的是那些保留在 堆内存中的对象,意思是,变量中保留的实际上只是一个指针,这个指针指向内存堆中理论的值;
两种拜访形式
- 根本类型值:按值拜访,操作的是他们理论保留的值;
- 援用类型值:按援用拜访,当查问时,咱们须要先从栈中读取内存地址,而后再顺藤摸瓜地找到保留在堆内存中的值;
两种类型复制
根本类型变量的复制:
从一个变量向一个变量复制时,会在栈中创立一个新值,而后把值复制到为新变量调配的地位上,扭转源数据不会影响到新的变量 (互不干涉);
援用类型变量的复制:
复制的是存储在栈中的指针 ,将指针复制到栈中为新变量调配的空间中,而这个指针正本和原指针执行存储在堆中的同一个对象,复制操作完结后,两个变量实际上将援用同一个对象;因而 扭转其中的一个,将影响另一个;
函数参数的传递
1、ECMA 中所有函数的参数都是按值传递的
在向参数传递根本类型的值时,被传递的值会被复制给一个 局部变量 ,在向参数传递援用类型的值时,会把这个值在内存的地址复制给一个 局部变量
根本数据类型传递参数
funciton addTen(num){
num+=10;
return num;
}
var count=20;
var result=addTen(count);
alert(count);//20
alert(resullt);//30
执行后果是:20 和 30。
在这段代码中,将变量 count
当做参数传递给了函数 addTen
,也就是相当于将变量count
的值复制给了函数 addTen
的参数。这时 addTen
的参数 num
能够看做是函数外部的一个变量。
在上段代码中,就相当于两个根本数据类型变量之间的值复制。而根本数据类型都有本人独立的内存地址,所以 num
和count
是没有任何关系的,他们只是值相等而已,函数执行结束后,count
的值并没有扭转。
而函数里面的 result
是被间接赋值的,所以 result
的值就是函数的后果 30。
援用类型传递参数
function setName(obj){obj.name="LSN";}
var person=new Object();
setName(person);
alert(person.name); // LSN
执行后果是:LSN。
在这段代码中,函数 setName
的作用是给 obj
对象增加了一个属性 name
,并给该属性赋值为 ”LSN”,因为obj
是援用类型,所以这里属于是将援用类型 person
赋值给了 obj
,也就是说person
和obj
援用了一个内存地址,所以当给 obj
新加了属性 name
时,在函数里面的 person
也跟着扭转,最初 person.name
的后果为 LSN。
援用类型传递参数到底传的是值还是援用
function setName(obj){
obj.name="ABC";
obj=new Object();
obj.name="BCD";
}
var person=new Object();
setName(person);
alert(person.name); // ABC
执行后果是:ABC。
实例 3 与实例 2 的区别是在函数中又加了 2 行代码,在给 obj
对象新加一个属性 name
并赋值后又将 obj
定义成了一个新的对象(new Object()
),定义新对象后又 name
赋上新的值“BCD”。
这个时候如果是按援用传递的话,那么最初 person
对象就会主动批改为指向其 name
属性为 ”BCD” 的新对象,但最初显示的却是“ABC”,这阐明即便在函数外部批改了参数的值,但原始的援用还放弃不变。
实际上,当在函数外部 obj=new Object()
时 这个新的 obj
就曾经成为函数外部的部分对象了,这个对象会在函数执行结束后主动销毁。
两种变量类型检测
- typeof 操作符是检测根本类型的最佳工具;
- 如果变量值是 nul 或者对象,typeof 将返回“object”;
- Instanceof 用于检测援用类型,能够检测到具体的,它是什么类型的实例;
- 如果变量是给定援用类型的实例,instanceof 操作符会返回 true;
补充:根本包装类型 (包装对象)
先看下以下代码:
var s1 = "helloworld";
var s2 = s1.substr(4);
下面咱们说到字符串是根本数据类型,不应该有办法,那为什么这里 s1
能够调用 substr()
呢?
ECMAScript 还提供了三个非凡的援用类型 Boolean
,String
,Number
。咱们称这三个非凡的援用类型为 根本包装类型 ,也叫 包装对象。
也就是说当读取 string
,boolean
和number
这三个根本数据类型的时候,后盾就会创立一个对应的根本包装类型对象,从而让咱们可能调用一些办法来操作这些数据.
所以当第二行代码拜访 s1
的时候,后盾会主动实现下列操作:
- 创立 String 类型的一个实例;
// var s1 = new String("helloworld");
- 在实例上调用指定办法;
// var s2 = s1.substr(4);
- 销毁这个实例;
// s1 = null;
正因为有第三步这个销毁的动作,所以根本数据类型不能够增加属性和办法,这也正是根本装包类型和援用类型次要区别:对象的生存期。
应用 new
操作符创立的援用类型的实例,在执行流来到以后作用域之前都是始终保留在内存中。主动创立的根本包装类型的对象,则只存在于一行代码的执行霎时,而后立刻被销毁。
作者:公子七
链接:https://www.jianshu.com/p/a32…
起源:简书
著作权归作者所有。商业转载请分割作者取得受权,非商业转载请注明出处。