【慕课网】JavaScript数据类型

主要根据慕课网《JavaScript深入浅出》和《JavaScript权威指南》记得笔记

1.六种数据类型

JavaScript一共有六种数据类型:
1.五种基本类型(原始类型):
number、string、Boolean、undefined、null;
2.一种复合类型(对象类型):
object;
注:其他复合类型都继承自Object类型,如Array、Date、RegExp、Function、etc;

2.隐式转换

# 两个值都是对象时,比较的是两个引用值在内存中是否是同一个对象,所以是false
[] == []  // false 

# 因为! 优先级比==高,所以我们先看 ![] , !是转变成布尔值,js中[]布尔值是true,所以![]为false,现在到判断==, 现在变成判断[]==false. 
# 这时候[]不会变成布尔值,即true,会按照js标准 []看成0.于是最终转变为0==false,答案就出来了true.
[] == ![]  // true  

[] == false // true

== 用于简单类型比较的话,会尝试转换类型。
== 用于复杂类型(例如数组), 是引用比较

var a = new Array(1,2);
var b = new Array(1,2);
console.log(a== b);  // false

关于NaN,可以理解成一个Number 的对象,你每次调用,都会重新创建一个对象。所以NaN每次都是不同的对象。

对象的比较:

var a = [1,2];
var b=  [1,2];
a == b; //false

new object() == new object() // false

对象和对象比较,是比较的引用,两个对象都是new出来的(新创建出来的),所以是不同的对象,不同的对象的引用是不同的,所以输出是false。
只有对象和基本类型进行比较的时候,才会将对象转变成基本类型,再作比较。两个对象比较的时候是不会转成基本类型的,如:

var a = new String('hi');
var b = new String('hi');

a == 'hi';//true (先转换成基本类型再比较)
b == 'hi';//true(先转换成基本类型再比较)

但是 a == b;// false  (比较的是引用)

附注:创建对象的时候,会先开辟一个内存空间,然后用一个变量指向这个内存空间,实际上这个变量的值是这个内存空间的引用,可以理解成一个地址,比如说:var a = {}; b = a; 那么a 和 b 引用的是同一个地址,因为{}的内存空间是同一个,所以你对a或者b进行数据修改,同时会影响两个的值,因为你实际上修改的是{}的值,本体都变了,引用当然会变,现在知道你问的引用时什么意思了吗,引用就是这个内存的地址。


字符串和数字如果进行的是加法运算,会把+当做字符串拼接,因此"37"+37=“3737”,而字符串和数字进行减法运算,则先把字符串转成int,praseInt(“37”)=37,如果字符串不能转成数字,那么转换结果为NaN,NaN和任何数进行运算都为NaN。同样"32"-false=32是把“32”转换为32,false转换为0。

所以根据上面可以巧用+/-规则转换类型:

字符串变成数字: “123”-0 = 123
数字变成字符串:123-“” = “123”

3.包装对象

var str = "string";
typeof str // string

var strObj = new String("string")
typeof strObj // object

str是string(基本类型),本身是没有方法的。

当尝试把基本类型的str当做对象一样访问时,例如:str.length;
解释器会创建一个临时的包装对象,伪代码:

[[tempObj]] = new String(str);
[[tempObj]].length; // 返回具体的length;
delete [[tempObj]]; // 销毁临时对象

重复访问str.length会重复创建这个临时对象。
所以str.t赋值可以成功,但是立即销毁,但再次访问str.t返回undefined,因为每次创建的临时包装对象都是不同的。


所谓“包装对象”,就是分别与数值、字符串、布尔值相对应的Number、String、Boolean三个原生对象。这三个原生对象可以把原始类型的值变成(包装成)对象。

var v1 = new Number(123);
var v2 = new String('abc');
var v3 = new Boolean(true);

上面代码中,基于原始类型的值,生成了三个对应的包装对象。

toString也是类似的情况,构造成包装对象:

a = (123).toString() //"123"
typeof a //"string"
a.t = 5 //5
alert(a.t) //undefined

4.类型检测

类型检测的作用:
1.保证代码的健壮性,js是弱类型语言,类型检测可以避免出现不必要的类型转换问题。
2.有助于更高质量的完成代码书写。
3.有助于功能逻辑的把控。

prototype是原型链中构造函数的一个自带属性,它是用来指向原型对象的,指向原型对象的作用是来共享这个原型对象中所有的属性和方法,为什么要这么做呢?
是因为创建每个新object对象,有时候需要给他加方法,比如object.name=”Bob“之类的,但是每次创建都很麻烦,所以就采用这种共享指向的方法。

1.类型检测
1)typeof(基本类型检测)
对所有基本类型的返回值
typeof Number  //“Number”
typeof String  //"string"
typeof Boolean //"boolean"
typeof null    //"object"
typeof undefined   //"undefined"
typeof object  //"object"
对函数类型的返回值
typeof function    //"function"
 
2)由于typeof只适用于判断基本类型,对object,Date,Array进行检测时只会统一返回“object”(很显然这不是我们想要的,我们想知道它的具体类型),这时就要用到instanceof了,instanceof在检测对象时会返回具体类型,如:
new array() instanceof Array //true
new Date() instanceof Date   //true
...
如果想用instanceof去检测基本类型只会统一返回false,另外由于instanceof是基于原型链的,所以有下列结果:
//定义父类
function Parent(){}
//定义子类
function Child(){}
//让子类继承父类
Child.prototype = new Parent();
//此时再new一个子类实例,使用instanceof
new Child() instanceof Child;    //true
new Child() instanceof Parent    //true
通过原型链索引,new的是子类实例,子类继承父类,所以子类实例既是子类类型又属于父类类型
PS:instanceof在跨iframe或者window时由于存在多个window对象,所以在使用instanceof检测时会返回false
 
3)object.prototype.toString
说实话- -,这个没用过,所以涨知识了
Object.prototype.toString.apply([]) //"[Object Array]"
Object .prototype.toString.apply(function(){});    //"[Object function]"
Object .prototype.toString.apply(null);    //"[Object null]'
...
PS:ie6/7/8下存在兼容性问题,在检测null时会返回object
 
4)constructor构造器
每个对象都有个constructor属性,它指向该对象的构造函数类型,不过该属性的值可以被改写的,所以用它的判断并不可靠
 
5)duck type
百度了为啥叫“鸭子类型”,有这样的话:“当看到一只鸟走起来像鸭子、游泳起来像鸭子、叫起来也像鸭子,那么这只鸟就可以被称为鸭子。”
大概意思就是说当某个对象具备某种类型的特征或者行为时就可以被判断为某种类型,不知道是不是“能力检测”那种意思- -

在这里插入图片描述


console.log(typeof(x));    // undefined           

console.log(typeof(10));   // number            
console.log(typeof('abc')); // string           
console.log(typeof(true));  // boolean
             
console.log(typeof(function () { }));  //function 

console.log(typeof([1, 'a', true]));  //object            
 console.log(typeof ({ a: 10, b: 20 }));  //object            
 console.log(typeof (null));  //object            
 console.log(typeof (new Number(10)));  //object      

以上代码列出了typeof输出的集中类型标识,其中上面的四种(undefined, number, string, boolean)属于简单的值类型,不是对象。剩下的几种情况——函数、数组、对象、null、new Number(10)都是对象。他们都是引用类型。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值