数据
JavaScript 变量均为对象。当您声明一个变量时,就创建了一个新的对象。
1.JavaScript 数据类型
值类型(基本类型):字符串(String)、数字(Number)、布尔(Boolean)、对空(Null)、未定义(Undefined)、Symbol。
引用数据类型:对象(Object)、数组(Array)、函数(Function)。
注:Symbol 是 ES6 引入了一种新的原始数据类型,表示独一无二的值。
2.JavaScript 拥有动态类型
JavaScript 拥有动态类型。这意味着相同的变量可用作不同的类型:
3.JavaScript 数组
数组的三种创建方式
- 创建名为 cars 的数组:
var cars=new Array();
cars[0]="Saab";
cars[1]="Volvo";
cars[2]="BMW";
- 简写为
var cars=new Array("Saab","Volvo","BMW");
- 不适用new创建数组
var cars=["Saab","Volvo","BMW"];
1.使用关键词 “new” 来声明变量的类型
var carname=new String;
var x= new Number;
var y= new Boolean;
var cars= new Array;
var person= new Object;
2. 第一种是构造函数式,即通过new运算符调用构造函数Function来创建函数;第二种不是实例化,只是调用函数把返回值赋给变量。
3.使用new的话如果函数没有return会返回一个对象。不使用new如果函数没有return会返回undefined。
4.就算变量定义的是数组格式,typeof 返回的数据类型还是 object :
var cars=new Array();
cars[0]=“Saab”;
cars[1]=“Volvo”;
cars[2]=“BMW”;
document.write(typeof cars); // object
判断对象是否为数组的两种方法
- 使用 isArray 方法
var cars=new Array();
cars[0]="Saab";
cars[1]="Volvo";
cars[2]="BMW";
// 判断是否支持该方法
if (Array.isArray) {
if(Array.isArray(cars)) {
document.write("该对象是一个数组。") ;
}
}
- 使用 instanceof 操作符
var cars=new Array();
cars[0]="Saab";
cars[1]="Volvo";
cars[2]="BMW";
if (cars instanceof Array) {
document.write("该对象是一个数组。") ;
}
4.JavaScript 对象
两种创建对象的方式
第一种
function Demo(){
var obj=new Object();
obj.name="张思";
obj.age=12;
obj.firstF=function(){
}
obj.secondF=function(){
}
return obj;
}
var one=Demo();
// 调用输出
document.write(one.age);
第二种
function Demo(){
this.name="张思";
this.age=12;
this.firstF=function(){
}
this.secondF=function(){
}
}
var one=new Demo
// 调用输出
document.write(one.age);
第一种在构造函数时使用new来构造新对象,第二种在构造变量时使用new创建新对象
对象的两种寻址方式:
name=person.lastname;
name=person["lastname"];
对象方法
对象的方法定义了一个函数,并作为对象的属性存储。
对象方法通过添加 () 调用 (作为一个函数)。
<script>
var person = {
firstName: "John",
lastName : "Doe",
id : 5566,
fullName : function()
{
return this.firstName + " " + this.lastName;
}
};
document.getElementById("demo1").innerHTML = "不加括号输出函数表达式:" + person.fullName;
document.getElementById("demo2").innerHTML = "加括号输出函数执行结果:" + person.fullName();
</script>
输出结果:
不加括号输出函数表达式:function() { return this.firstName + " " + this.lastName; }
加括号输出函数执行结果:John Doe
javaScript对象中属性具有唯一性(这里的属性包括方法),如果有两个重复的属性,则以最后赋值为准。
JavaScript 对象是键值对的容器,“键”必须为字符串,“值”可以是 JavaScript 中除 null 和 undefined 以外的任意数据类型。
“nickname” : null //非法
5.Undefined 和 Null
Value = undefined
在计算机程序中,经常会声明无值的变量。未使用值来声明的变量,其值实际上是 undefined。
在执行过以下语句后,变量 carname 的值将是 undefined:
var carname;
Undefined 这个值表示变量不含有值,可以通过将变量的值设置为 null 来清空变量。
cars=null;
6.重新声明 JavaScript 变量
如果重新声明 JavaScript 变量,该变量的值不会丢失:
在以下两条语句执行后,变量 carname 的值依然是 “Volvo”:
var carname="Volvo";
var carname;
7.基本类型变量和对象变量的内部存储
- 基本类型的变量是存放在栈内存(Stack)里的
var a,b;
a = "zyj";
b = a;
console.log(a); // zyj
console.log(b); // zyj
a = "呵呵"; // 改变 a 的值,并不影响 b 的值
console.log(a); // 呵呵
console.log(b); // zyj
图解如下:栈内存中包括了变量的标识符和变量的值。
- 引用类型的值是保存在堆内存(Heap)中的对象(Object)
var a = {name:"percy"};
var b;
b = a;
a.name = "zyj";
console.log(b.name); // zyj
b.age = 22;
console.log(a.age); // 22
var c = {
name: "zyj",
age: 22
};
图解如下:栈内存中保存了变量标识符和指向堆内存中该对象的指针,堆内存中保存了对象的内容
8.数据类型转换
- 利用 toString() 方法可以把数值转换为字符串。
<script>
var a=100;
var c=a.toString();
alert(typeof(c)); //typeof()方法验证转换后的数据类型
</script>
字符串也是序列,所以可以通过序列的排序编号进行取值。
字符串这种序列跟列表结构是有区别的,它是不可以修改和排序的。
- 使用 parseInt() 和 parseFloat() 方法可以把字符串转换为数值。
<script>
var str="123.30";
var a=parseInt(str); //parseInt()方法把字符串转换为整数,parseFloat()方法把字符串转换为浮点数
var b=parseFloat(str);
</script>
- 要把任何值转换为布尔型数据,在值的前面增加两个 !! 感叹号即可。
9. 类型检测的方法
typeof 123 // 'number'
typeof 'abc' // 'string'
typeof undefined // 'undefined'
typeof true // 'boolean'
typeof Math.abs // 'functuon'
null === null // true
[] instanceof Array // true
{} instanceof Object // true
new Map instanceof Map // true
new Set instanceof Set // true
10.相等与恒等
相等判断也是 JavaScript 的坑之一。
// 相等 | 值相等
'1' == 1 // true
// 恒等 | 值并且类型相等
'1' === 1 // false
// 这看起来没什么问题,但是 undefined == null == '' == 0 == [] == {} == false // 居然等于 true
// 所以,在 JavaScript 中尽量使用 === 恒等进行判断。
11.包装对象
三种原始类型的值——数值、字符串、布尔值——在一定条件下,也会自动转为对象,也就是原始类型的“包装对象”。
目的:首先是使得 JavaScript 的对象涵盖所有的值,其次使得原始类型的值可以方便地调用某些方法(比如typeof,length)。
typeof v1 // "object"
typeof v2 // "object"
typeof v3 // "object"
v1 === 123 // false
v2 === 'abc' // false
v3 === true // false
- Number、String和Boolean如果不作为构造函数调用(即调用时不加new),常常用于将任意类型的值转为数值、字符串和布尔值。
Number(123) // 123
String('abc') // "abc"
Boolean(true) // true
- 包装对象的实例可以使用Object对象提供的原生方法,主要是valueOf方法和toString方法。
valueOf():返回包装对象实例对应的原始类型的值。
new Number(123).valueOf() // 123
new String('abc').valueOf() // "abc"
new Boolean(true).valueOf() // true
toString():返回对应的字符串形式。
new Number(123).toString() // "123"
new String('abc').toString() // "abc"
new Boolean(true).toString() // "true"
- 原始类型与实例对象的自动转换
原始类型的值,可以自动当作包装对象调用,即调用各种包装对象的属性和方法。这时,JavaScript 引擎会自动将原始类型的值转为包装对象实例,在使用后立刻销毁实例。
var str = 'abc';
str.length // 3
//abc是一个字符串,本身不是对象,不能调用length属性。JavaScript 引擎自动将其转为包装对象
//在这个对象上调用length属性。调用结束后,这个临时对象就会被销毁。
//这就叫原始类型与实例对象的自动转换。
// 等同于
var strObj = new String(str)
// String {
// 0: "a", 1: "b", 2: "c", length: 3, [[PrimitiveValue]]: "abc"
// }
strObj.length // 3
自动转换生成的包装对象是只读的,无法修改。所以,字符串无法添加新属性。
var s = 'Hello World';
s.x = 123;
s.x // undefined
- 自定义方法
String.prototype.double = function () {
return this.valueOf() + this.valueOf();
};
'abc'.double()
// abcabc
Number.prototype.double = function () {
return this.valueOf() + this.valueOf();
};
(123).double()
// 246
12.布尔对象
Boolean对象是 JavaScript 的三个包装对象之一。作为构造函数,它主要用于生成布尔值的包装对象实例。
var b = new Boolean(true);
typeof b // "object"
b.valueOf() // true
注意,false对应的包装对象实例,布尔运算结果也是true。
if (new Boolean(false)) {
console.log('true');
} // true
if (new Boolean(false).valueOf()) {
console.log('true');
} // 无输出
Boolean对象除了可以作为构造函数,还可以单独使用,将任意值转为布尔值。这时Boolean就是一个单纯的工具方法。
Boolean(undefined) // false
Boolean(null) // false
Boolean(0) // false
Boolean('') // false
Boolean(NaN) // false
Boolean(1) // true
Boolean('false') // true
Boolean([]) // true
Boolean({}) // true
Boolean(function () {}) // true
Boolean(/foo/) // true
使用双重的否运算符(!)也可以将任意值转为对应的布尔值。
!!undefined // false
!!null // false
!!0 // false
!!'' // false
!!NaN // false
!!1 // true
!!'false' // true
!![] // true
!!{} // true
!!function(){} // true
!!/foo/ // true
对于一些特殊值,Boolean对象前面加不加new,会得到完全相反的结果,必须小心。
if (Boolean(false)) {
console.log('true');
} // 无输出
if (new Boolean(false)) {
console.log('true');
} // true
if (Boolean(null)) {
console.log('true');
} // 无输出
if (new Boolean(null)) {
console.log('true');
} // true
13.JavaScript 变量的生存期
JavaScript 变量的生命期从它们被声明的时间开始。
局部变量会在函数运行以后被删除。
全局变量会在页面关闭后被删除。
14.向未声明的 JavaScript 变量分配值
如果您把值赋给尚未声明的变量,该变量将被自动作为 window 的一个属性。
carname="Volvo";
将声明 window 的一个属性 carname。
非严格模式下给未声明变量赋值创建的全局变量,是全局对象的可配置属性,可以删除。
var var1 = 1; // 不可配置全局属性
var2 = 2; // 没有使用 var 声明,可配置全局属性
console.log(this.var1); // 1
console.log(window.var1); // 1
delete var1; // false 无法删除
console.log(var1); //1
delete var2;
console.log(delete var2); // true
console.log(var2); // 已经删除 报错变量未定义