在Javascript中简单数据类型分为5种。分别为 Undefined, Null,Boolean,Number,String.
var object = null;console.log(typeof object);//object实际上,Undefined派生自Null类型。所以,Ecma-262规范中,null==undefined //值为true.
字符串的特点: (1).单双引号报过都可。 (2).字符串不可变。 什么是字符串不可变?
var str1="hello"; //开辟一份新空间 var str2="world"; //开辟一份新空间 str1=str1+str2; //因为字符串的不可变特性,改变字符串会重新开辟一份新空间,以前的那一份在一段时间后被垃圾回收机制回收。 console.log(str1); 作为基本数据类型,字符串作为函数参数的时候是传值还是传引用呢?
如果传值:则必须复制一份新的字符串作为参数。字符串如果太长的话,很明显,浪费空间。 如果传引用: 字符串作为参数,如果值没有改变,则不需要开辟新的空间。 如果值改变,又因为字符串不可变的特性而会重新开辟新的空间。 所以,字符串在作为参数的时候是传引用而非传值。
注: 关于传值还是传引用,我们这里参照物均为变量本身。------详情请看第三部分。
复杂数据类型也就是我们常说的引用类型.引用类型是一种数据结构,其值也就是其所指向的对象。 ECMAScript提供了很多原生态的引用类型。
//第一种,使用构造函数。var object=new Object();object.name="xxxx";//第二种,使用字面量的创建方式,程序员更倾向于第二种var object={ name:"xxxx" }
(2) 对象的属性
Object数据类型的对象是采用松散的结构组织属性的。所谓的松散,就是我们所说的用键值对来保存对象。而键值对以hash表结构存储。
有关于对象以键值对存储的文章,详情见对象基于哈希存储(<Key,Value>之Key篇(1)。
Object类型的对象,属性可以分为两类:
a.数据属性
数据属性有四个描素其行为的特性。
var object = { name: '张三'};Object.definePRoperty(object, 'name', { configurable: false});delete object.name; //false
Object.defineProperty(object, 'name', { configurable: true}); //error:TypeError: can't redefine non-configurable property 'name'
var object = { name: '张三', age:18};Object.defineProperty(object, 'name', { configurable: false, enumerable: false});for (var property in object) { console.log(property); //age}
var object = { name: '张三', age: 18};Object.defineProperty(object, 'name', { configurable: false, enumerable: false, writable: false});object.name = '李四';console.log(object.name);//张三,name未被更改
var object = { name: '张三'};Object.defineProperty(object, 'age', { configurable: false, enumerable: false, writable: false, value: 18});console.log(object.age);//18
b.访问器属性:访问器属性不包含数据值,但其包含getter和setter函数。其也有四个特征值对其进行描述
var object = { name: '张三', age: 18};Object.defineProperty(object, 'isAdult', { configurable: false, enumerable: false, get: function () { if (this.age < 18) { return false; } else { return true; } }});console.log(object.isAdult);//true isAdult就是一个访问器属性
var object = { name: '张三', age: 18};Object.defineProperty(object, 'changeAge', { configurable: false, enumerable: false, set: function (value) { this.age = value; }});object.changeAge=17;console.log(object.age);//17
(3)对象的常用方法
//第一种 使用构造函数var mycars=new Array()mycars[0]="Saab"mycars[1]="Volvo"mycars[2]="BMW"或者 var mycars=new Array("Saab","Volvo","BMW")//第二种 使用数组字面量var colors=["red","blue","green"];(3)数组的属性 length:数组的 length 属性总是比数组中定义的最后一个元素的下标大 1,通过length 属性可设置或返回数组中元素的数目。
var array=[];array[100]=10;console.log(array.length);//101
array=[1,2,3,4,5];array.length=3;console.log(array);//1,2,3
var myDate=new Date(); //Date 对象自动使用当前的日期和时间作为其初始值。补充说明:对于时间 其月份总是从0开始算起,即月份表示 0---11.而其他的和我们正常所理解的是一致的。
3.传值和传引用
(1)问题的起源
其实这个问题来源于C和C++,因为C或C++里都有一个特殊的数据类型----指针,那时候所谓的传值和传引用是对指针来说的。那么针对指针来说,什么是传值,又什么是传引用呢?首先,指针作为一种数据类型,其本身肯定是占用一定的内存空间,而且,指针同时还要指向另一块内存空间。
如图所示:
针对指针来说,指针作为一种数据类型,指针的标识符也就是其在内存中所在的地址,指针的值就是其所指向的地址。也就是说,指针值是地址。那么一个指针在作为函数的参数的时候,传给参数的到底是指针的地址还是指针的值呢? ----这就是传值和传引用问题的起源.
(2)指针的传值和传引用 函数的参数,在函数被调用的时候,在其函数所开辟的那个栈中是占用一定的内存空间的,那么这块内存空间的值是什么呢?
首先,先肯定一点,形参的值来源肯定是实参。那么,实参给形参赋值的时候传的是什么呢?
(1)传的是结构体地址,那么就如图所示:
如果传的是结构体的地址,那么也就是指针的值赋值给形参。所以,这就是我们所谓的传值。由图中我们可以看出,如果是传值的话,那么作为形参的指针和作为实参的指针,指向的是同一个结构体。
(2)如果传的是指针的地址,那么指针的地址就会赋值给形参。结果,如图所示: 对于传引用来说,形参的值是指针的地址,那么每次对形参的改变,其实改变的都是指针所指向的地址。而如果向取得结构体的地址,也需要通过实参的地址。 (3)JS中只存在传值
首先需要明确一写概念,即引用和对象的概念。
引用:也就是我们所说的指针,其存在于栈中。
对象:也就是上图中我们所标记的结构体,其存在于堆中。
引用的值就是对象所在的地址。我们用一个例子说明:
var person = { name: '张三', age: 18};function setName(object) { object.name = '王五';}setName(person);console.log(person.name);//王五
依然用图来解释:
新闻热点
疑难解答