JavaScript学习----------数据类型

js的数据类型

js的数据类型分为两种:值类型和引用类型

内存分为栈和堆。当定义一个变量时,把变量放在栈里边,当变量的值为值类型时,变量的值也直接放在栈里;如果变量是引用类型,那么对象放在堆内存里,对象的地址放在栈里。

所有的值类型都是拷贝的。所有的引用类型都是引用的。var a = 5;var b =a; 这两个表达式的意思是把a的值复制给b。而var a = [] var b = a;   是把a的地址复制给了b

堆内存中的对象,有一个引用计数,引用计数是干嘛的呢,要实现一个GC(垃圾收集),堆内存里面内存的回收。堆内存里的对象的引用计数为0,那么我就回收内存,时间是不确定的,有可能堆内存达到一定使用门槛,有可能是定期回收。

循环引用有可能产生内存泄漏:var arr1 = [];  var arr2 = [];  arr1[0] = arr2;   arr2[0] = arr1.

原始类型:

(1) Number:

123、0.123、1.23e3、-99、

NaN(表示 不是一个number。记住它与任何数都不等,包括它自己。判断isNaN())

Infinity(表示无限大)

Number.MAX_VALUE、 Number.MIN_VALUE

Number.POSITIVE_INFINITY(POSITIVE表示正的意思  infinity表示无限)------》输出infinity

Number.MAX_VALUE*1.1-----》输出infinity

判断是否为infinity用方法:isFinite(变量)---》如果是infinity,返回false;如果不是,则返回true。

Number.infinity+1  ---->NaN(当你直接把infinity拿出来做计算的时候,下边得到的就不是infinity了。)

(2) 字符串:

多行字符串:用反引号来表示:

`asd
dsa
dsa`

模板字符串:也用反引号来表示:`nihao ${变量}`

字符串的方法:

concat():合并。

toUpperCase():把一个字符串全部变为大写:

var name = 'hubo';
console.log(name.toUpperCase());

toLowerCase():把一个字符串转成小写:

var name = 'HUBO';
console.log(name.toLowerCase());

indexOf():会搜索字符串出现的位置,没有找到返回-1:

name.indexOf('u')

charAt(index):返回对应的字符

substring():返回指定区间的子串

split():str.split(''): 把字符串每个字符都返回,返回成一个数组。

(3)布尔值:

(4)null:

 null == null   --->  true

(5)underfined:

undefined == undefined --> true

undefined == null ---> true

undefined === null ---> false

引用类型:

(1) 数组:

数组的定义:

var arr1 = [1,2,3,4];

var arr2 = new Array(1,2,3,4); 

var arr3 = new Array(4);     1和2是等价的,3是生成一个长度是4的数组

如何清空一个数组:

修改array.length会直接改变数组,arr.length = 0.

arr.splice(0)

arr = []

如何给一个数组去重:

arr.filter(function(x,y){

return arr.indexOf(x)  == y;

});

for(var i = 0;i<arr.length;i++){
if(arr1.indexOf(arr[i]) == '-1'){
arr1.push(arr[i])
}
}

arr.sort();
for(var i = 0;i<arr.length;i++){
if(arr1.length == 0 || arr1[arr1.length-1] != arr[i]){
arr1.push(arr[i]);
}
}

如何判断是否是数组?

console.log(arr.constructor.name)

数组的方法很多:

indexOf():

slice()和字符串的substring类似。返回一个数组。可以利用slice快速复制一个数组。

push()和pop();  push()向数组的末尾添加若干元素。pop()则把最后一个元素删除掉。----------------------栈

unshift()和shift():unshift往数组的头部添加若干元素。shift从头部删掉一个元素。

sort():排序

reverse():翻转数组,掉个个。

splice():修改数组,是真的改变原数组,从原数组中删掉,并且改变数组的长度。位置和元素都拿走。

delete arr[4]:删掉元素,但是元素长度没变,删掉的那个位置变成了空。只拿走了元素,位置没拿走。 

concat():把当前的数组和另一个连接起来。返回了一个新数组。

join():把元素用指定的字符串连接起来。

用数组可以做成栈和队列 。栈:后进先出。 队列:先进先出。都是用上面的函数。

(2) 对象:

要检查某对象是否拥有某一属性:用in操作符。in判断属性时,这个属性不一定是此对象的,有可能是此对象继承的。要判断一个属性是对象自己本身的而非继承得到的,可以用hasOwnProperty().

'name' in xiaoming     -> true

xiaoming.hasOwnProperty('name')   ->true

要删除某对象某一属性:delete

delete obj.a

构造函数:

function Person(name,age,gender){

  this.name = name;

  this.age = age;

  this.gender = gender;

}

var obj1 = new Person('hubo',22,'male');

包装类:Boolean()、String()、Number()

var a = 'str' 

a.length = 2   

不报错的原因是隐式类型转换:

var a = 'str' 

var aTmp = new String(a)

aTmp.length = 2

所以a不报错。

(3) 函数:

函数是一个引用类型的对象。

函数声明:function f(){}

函数表达式:(function f (){})

      var a = function(){};

         ff(a,function(){},b);

函数表达式和函数声明的不同是:函数声明,系统里会有函数名;函数声明,系统里没有函数名。

var f = function(x){

  if(x<=1){

    return 1;

  }else{

    return x*arguments.callee(x-1);

  }

};

f(5);  -------------callee  就是代表调用自己,当函数没有名字时,这么调用。

立即执行函数:

var a = function(){

  console.log('asd');

}();

或者

var a = (function(){

  console.log('asd');

})();

嵌套函数:

函数的调用:

function add(x,y){

  return x+y;

}

add(1,2)

this.add(1,2)

add.call(this,1,2)

add.apply(this,[1,2])

es6新引入的数据类型:

(1)map:

引入的原因,因为js中对象的键必须是字符串,不可以是其他类型变量。

map是一组键值对结果,具有极快的查找速度

var map = new Map([['mike',95],['lisa',100],['lilei',12],['yeye',123]]);初始化map需要一个二维数组。

(2)set:

是一组key的集合,但不存储value,要创建一个set,需要提供一个array作为输入。或者直接创建一个空set。

var set = new Set();

var set = new Set([1,23,34]);

(3)iterable:

为了统一集合类型,es6引入了新的iterable类型,array、map、set都属于iterable类型,具有iterable类型的集合可以使用for......of来循环遍历。

类型转换:

1.转化成数字:

隐式类型转换:string + number -> string

         string - number -> number

显示类型转换:

(1) Number():我就是把本质上是数的变量给你做转换,其他的我给你NaN

Number(null) = 0

Number(undefined) = NaN

Number('1.5') = 1.5

Number('1.5.3') = NaN

Number(' ') = 0

(2)parseInt():

parseInt('1234')  ---> 1234

parseInt('1234aaa') -----> 1234

parseInt('a123') -----> NaN

parseInt('') ----> NaN

parseInt(false) ----> NaN

parseInt(undefined) ----> NaN

parseInt(null) ----> NaN

(3)parseFloat():和parseInt几乎无区别。可以解析小数点。

(4)isNaN()函数:原理是调用的Number()函数。

2.转化成字符串:

隐式:

var s = ''+null  ----> null

显示:

String() :

String(null)   ----> null

toString():

var num = 80;

var s1 = num.toString();   ---->80

80.toString()            null.toString()          undefined.toString() -----> 不可以        但是 true.toString()  ---->   可以

3.转化成布尔:

隐式:

var s = !0;

var s = !12

显示:

boolean():

循环:

(1) for循环;是根据数组的length来进行输出。不输出map的键。

(2) for in循环:它可以把一个对象的所有属性依次循环出来。因为数组也是对象,所以也可以把数组的索引循环出来.把数组里的所有非稀疏节点的key输出出来(也就是非empty)。

for(var key in o){

  console.log(key)

}

(3) 具有iterable类型的集合可以使用for...of来循环遍历。  for...in   和  for ...of 的区别是什么?   for...of只循环集合本身(和for一样),直接输出值。for...in会把不是集合本身的属性也循环出来。

(4) 更好的方式是用iterable内置的forEach()方法(返回的是数字和非稀疏的value)。它接受一个函数,每次迭代就自动回调该函数。

a.forEach(function (element, index, array) {
// element: 指向当前元素的值
// index: 指向当前索引
// array: 指向Array对象本身
console.log(element + ', index = ' + index);
});

猜你喜欢

转载自www.cnblogs.com/theLifeOfHubo/p/9782832.html