数据类型
1.基本数据类型和引用类型
基本数据类型包含 number, string, boolean, undefined, 引用类型包含object 和 function.
它们之间的区别在于:
- 引用类型的值可以动态的增加属性和方法,而基本类型不行。(基本类型的包装类型属于引用类型)
var a = "hello world"; // string为基本类型,没有属性和方法,在调用方法时,实际上是转换成了包装类型(object)
var b = {}; // b为object类型,可以自由的添加属性和方法
b.type = "";
b.add = function() {};
- 基本类型复制变量值时,会创建一个新值,而引用类型不会创建新对象,只是简单复制了引用的地址
var a = 1;
var b = a; //可以认为a,b两个变量指向两个基本类型的值,此时它们的值相等,都为1
a = 2; // a变量指向的值变成了另一个基本类型的值,b不变化
console.log(b); // 输出1
var obj1 = {age : 1}; // 在堆内存中创建了一个对象,obj1的值存放了这个对象的地址
var obj2 = obj1; // 可以认为将obj1中存放对象的地址告诉了obj2
obj1.age = 2; // .操作为访问对象的属性或方法,赋值操作将对象的age属性值更改为2
console.log(obj2.age); // 读取对象的age属性,此刻为2
2.各类数据类型的值
- undefined
var x; //仅声明了变量x,并没有赋值,此时类型为undefined
x; // 特别注意,没有var表示声明变量,而直接使用,则默认为缺省window,此刻可认为 window.x = undefined
- number
var x1 = 123;
var x2 = new Number("123abc"); // x2为object, 实际值为NaN
var x3 = parseInt("123abc"); // x3的值为123
var x4 = parseFloat("0.23acv"); // x4的值为0.23
- string
var x = "hello world";
var x = 'hello world'; // 单引号和双引号均表示字符串,这与java不同
var x = ne'w String(); // x为object对象, "123".length,就是将基本类型转换成了包装类型
- boolean
var x = true; //
var x = 1 && 2; // 1为number类型,会隐式转换成boolean类型
var x = new Boolean(true); // Boolean为包装类,x 为对象类型
- object
var x = null; // 对null进行typeof操作,结果为object
var x = {};
var x = new Object(); // new关键字是执行类的构造函数,并返回该类的一个实例对象
- function
//String, Object, Array, Date等等都是类,都是function类型
function A() {}; // 定义了一个function A,也可以称之为类A
var doAdd = new Function("iNum", "alert(iNum + 20)");
doAdd(10); // 注意这里,new 返回的实例不是对象,而是一个Function(类)
补充: object类型和function类型的区别
- function类型的变量可以通过new的形式返回该方法(类)的一个实例
var x = function A() {return 1}; // 若是全局环境下定义函数,则函数将会作为window的一个属性
var obj = new x(); // 注意obj不为1,构造函数内的return在new关键字上是无效的
- function运行,只能通过对象object调用,或者通过函数的方法 call调用
function test(){console.log(111)};
test(); // 此处调用函数默认缺省了this,完整的应该为this.test();
(function test(){console.log(111)})(); // 此处为函数直接量的写法
var obj = {};
test.call(obj);
3. 数据类型之间的转换
- 在逻辑运算(与或非)和if条件判断和new Boolean()时,非boolean类型的值会转换成boolean类型的值
// 转换规则为
如果是number类型,0为false,非0为true
如果是string类型,空字符串""为false,其余为true
如果是object类型,null为false,其余为true
如果是undefined类型,一律为false
- 在字符串连接操作 +运算和new String()时,非string类型的值会转换成string类型的值
//转换规则为
如果有toString发放, 则调用toString方法
如果是undefined类型或者是null,返回"undefined"或者"null"
- 在用 new Number()时,非number类型的值,会转换成number类型的值
//转换规则为
如果是boolean类型,true变为1,false变为0
如果是undefined, 变为NaN
如果是null, 变为0
如果是string, 空字符串变为0,其余按字符串字面最前匹配转换,如不能转换则为NaN
如果是object,先调用valueOf(),按上述规则转换,如果是NaN,再调用toString,再按上述规则转换
4. 类型检测
- typeof
对数据类型进行检测,返回"undefined","string","number","boolean","object","function" - instanceof
对object类型的对象进行类型检测
var obj = {};
var arr = [];
function a(){}
var a = new a();
console.log(obj instanceof Object) // true
console.log(arr instanceof Array) // true
console.log(a instanceof a) // true
变量及执行环境
1.全局变量、属性变量、局部变量(包含方法实参)的定义
- 全局变量又可以认为是 window 对象的属性,其可以在全局执行环境利用var定义,或者在函数执行环境不使用var定义
var x = 12; // 全局执行环境下,利用var定义变量,会变为window的属性
function A(){ // 全局执行环境下,定义方法,也会变为window的属性
y = 24; // 函数执行环境下,不用var来声明变量,也会变为window的属性
}
console.log(window); // window增加了三个属性,x、A以及y
(function B(){})();//特别值得一提的是,函数直接量的写法使得B形成一个闭包,外部环境是无法访问的
B(); // B为闭包,在全局环境下无法访问,会出现 undefined提示
// 函数直接量可以如下理解
function () {
function B(){}; // 在函数执行环境下,定义了B方法,B属于局部变量,而不是全局变量
B(); // 在函数执行环境下,执行了B方法
}
- 属性变量的定义,可以直接通过.来定义,或者在创建对象时声明
var obj = {name : "lwz9103", age : 21}; // 为obj对象定义了name属性和age属性
obj.xyz = 123; // 为obj对象定义了xyz属性
- 局部变量只能在函数执行环境下定义,函数实参也可以看作是局部变量
function test(x, y) {
var txt = "nihao"; // 在函数执行环境下用var定义局部变量 txt
return x + y
};
test(1, 2); // 方法执行时,定义了方法实参 x,y
// 函数执行时实参定义的过程可以这么理解
function test(x, y) {
arguments = [1, 2]; // 将传入参数列表放入arguments对象,类似java的可变参数列表
var x = 1;
var y = 2;
}
2.执行环境及作用域链
-
变量对象(保证了执行环境能对环境中定义的变量和函数进行访问)
变量对象是执行环境用来保存在此环境下定义的变量或者函数的一个特殊对象,无法被开发者访问
-
全局执行环境和函数执行环境
全局环境是最外围的执行环境,在html中