JS基本引用类型

JS的语法简单,如果你有 C++ 或者是 Java 等其他面向对象语言的基础,那么再来学习 Js 可以说是小菜一碟。

这篇文章主要讲解的是 JS 的一些基础引用类型(类似于 Java中的类的概念,但是 JS 中并没有类这一说法,我们称之为引用类型).主要包含以下几个方面:

  • Object类型
  • Array类型
  • 包装类型(主要有 StringNumberBoolean 类型)
  • Function类型
  • Date类型
  • RegExp类型 (后面详细介绍)

Object类型

一些基本的类型都是 Object 类型,比如我们创建的任一个基本的对象,都属于 Object 型对象,一个数组对象也是一个 Object 对象,所以在使用 typeof 操作符的时候检测是不是 Array 对象使用 typeof就不行了,例如:

var arr = [1, 2, 3, 4, 5];
console.log(typeof arr); //输出是Object,不能检测出具体的引用类型

所以就出现了另一个操作符: instanceof, 使用方法是 object instanceof constructor,其中 object 是某个实例对象,constructor 是某个构造函数。

var arr = [1, 2, 3, 4, 5];
console.log(arr instanceof Array); //输出true

1.创建对象
创建对象有两种方法: 构造函数(new操作符)字面量表示

构造函数创建对象

var person = new Object();
person.name = "悟空";
person.age = "18";
console.log(person); //输出:Object { name: "悟空", age: "18" }

使用字面量方法创建对象

var person {
    name: "悟空",
    age : 18 //主要这里不加逗号
};
console.log(person); //输出:Object { name: "悟空", age: "18" }

一般使用的是第二种方法:对象字面量的方法来创建对象,给人一种封装的感觉。也是向函数传递大量可选参数的首选方式。

2.访问对象属性和方法
访问对象的属性时一般有两种方法:点表示法方括号加属性名

console.log(person.name); //点表示法
console.log(person.age);

console.log(person["name"]);//方括号法
console.log(person["age"]);

Array类型

数组类型。每一项都可以存储任意类型的值。
Array类型封装了大量的接口方法供用户使用,比如有:栈方法、队列方法、排序方法、操作方法、位置方法、迭代方法等。
1.创建数组对象

使用Array()构造函数创建对象:

var arr = new Array();//创建一个空数组对象
var arr = new Array(10);//创建一个10个项目的对象
var arr = new Array(1, 2, 3, 4, 5);//创建具有指定项的数组对象

使用字面量的方法创建对象

var arr = [];//创建的是空数组对象
var arr = [1, 2, 3, 4, 5];//创建指定的对象
var colors = ["red", "green", "blue"];

一般也是选用字面量的方法创建对象。

数组可以存放任意类型的值

var arr = [1, 2, "red", "green", "blue", true, false, [1, "color", true], {name: "悟空", age: 18}]
//该数组存放了数字、字符串、布尔值、数组和对象

2.访问数组元素
访问数组元素使用的是索引(和其他语言一样)

var arr = [1, 2, "red", "green", "blue", true, false, [1, "color", true], {name: "悟空", age: 18}]

console.log(arr[0]); //输出:1
console.log(arr[2]);//输出:red
console.log(arr[7]);//输出:数组[1, "color", true]
console.log(arr[8]);//输出:对象{name: "悟空", age: 18}

3.栈方法

栈方法就是使用类似于数据结构中的栈来操作数组。
使用的方法是: push()pop()
push() : 在数组的末尾添加一个元素,返回数组中添加后的个数。
pop() : 弹出数组的末尾元素,返回弹出的元素。

var colors = ["red", "green", "blue"];
var len = colors.push("white");
console.log(len);//输出:4
console.log(colors);//输出: 数组对象["red", "green", "blue", "white"]
var e = colors.pop();
console.log(e);//输出:white
console.log(colors);//输出:数组对象["red", "green", "blue"]

4.队列方法

队列方法就是使得数组的操作类似数据结构中的队列操作。
使用的方法是: push()shift()
push() : 在数组的末尾添加一个元素,返回数组中添加后的个数。和栈方法中的 push() 方法一样。
shift : 弹出数组的第一个元素,返回弹出的元素。

var colors = ["red", "green", "blue"];
var len = colors.push("white");
console.log(len);//输出:4
console.log(colors);//输出: 数组对象["red", "green", "blue", "white"]
var e = colors.shift();
console.log(e);//输出: red
console.log(colors);//输出:数组对象["green", "blue", "white"]

5.位置方法

位置方法用于查找某一元素在数组中的索引位置。
方法是: indexOflastIndexOf
indexOf : 从前往后找,即返回第一次找到的位置;
lastIndexOf : 从后往前找,即返回最后一次找到的位置。

var arr = ["a", "b", "c", "d", "b"];
var index = arr.indexOf("a");
var index2 = arr.indexOf("b");
var lindex3 = arr.lastIndexOf("b");
console.log(index);//输出:0
console.log(index2);//输出:1
console.log(index3);//输出:4

6.其他操作方法

其他操作方法指的是类似于字符串的常用操作,拼接数组操作和截取部分位置数组操作。
方法主要有:concatslicesplice

concat拼接数组

var arr1 = [1, 2, 3];
var arr2 = ["red", "green", "blue"];
var arr3 = arr1.concat(arr2);
console.log(arr3);//输出:Array(6) [ 1, 2, 3, "red", "green", "blue" ]

或者也可以用于直接添加一个或多个元素,也相当于拼串:

var arr1 = [1, 2, 3];
var arr2 = arr1.concat("red", true);
console.log(arr2);//输出:Array(5) [ 1, 2, 3, "red", true ]

slice截取数组
使用 slice 方法可以用来截取数组。
该方法可以接受一个或两个参数:

  • 若为一个参数,表示截取从该参数开始到整个数组结束;
  • 若为两个参数,表示截取的是从第一个参数的元素开始到第二个参数之前的元素之间的所有元素。返回值都是截取后的数组。

splice删除元素或者添加元素
splice 是数组中功能最强大方法。可用来删除元素也可用来添加元素。

  • 如果有两个参数,则代表删除元素,意味着保留的开始及要保留的元素个数;
  • 如果第二个参数等于0,表示删除0个元素,如果后边有其他值,则代表的是添加元素,第一个位置代表的是在指定的位置添加。

注意:该方法的返回值是被删除的元素的新组成的数组

使用 slice 删除元素:

var colors = ["red", "green", "blue"];
var c1 = colors.splice(1, 2);
console.log(colors);//输出: Array [ "green", "blue" ]
console.log(c1);//输出: [ "green", "blue" ]

使用 slice 在指定的位置添加元素:

var colors = ["red", "green", "blue"];
colors.splice(1, 0, "white", "black");
console.log(cols);//输出:Array(4) [ "red", "white", "black", "blue" ]

7.排序算法

JS 封装了对数组进行排序的API。
使用的方法有: reverse()sort()

  • reverse() : 数组逆序排列;
  • sort() : 默认是按照从小到大进行排序,但是对字符串数组有点需要注意的地方。对字符串是按照字符编码逐个字符进行比较。
  • “200” < “3”, 因为是字符串比较,所以是逐个字符比,‘2’ < ‘3’,所以 “200” < “3”,所以一般我们传入一个函数,叫做比值函数

reverse()方法

var colors = ["red", "green", "blue"];
var nums = [1, 2, 3, 4, 5];
colors.reverse();
nums.reverse();
console.log(colors);//输出: Array(3) [ "blue", "green", "red" ]
console.log(nums);//输出: Array(5) [ 5, 4, 3, 2, 1 ]

默认的sort()方法

var colors = ["red", "green", "blue"];
var numStr = ["100", "2", "3", "250", "99"];
colors.sort();
numStr.sort();
console.log(colors);//输出 : Array(3) [ "blue", "green", "red" ]
console.log(numStr);//输出 : Array(5) [ "100", "2", "250", "3", "99" ]
//很明显是对于数值型的字符串,排序并不正确

在sort()中自定义比值函数
比值函数的目的是定义另一种排序顺序。

比值函数应该返回一个负,零或正值,这取决于参数:

function(a, b) { return a - b; }

sort() 函数比较两个值时,会将值发送到比较函数,并根据所返回的值(负、零或正值)对这些值进行排序。

Date类型

ECMAScript 中的 Date 类型是在早期的 Java.util.Date 类的基础上构建的。

1.创建对象

  • 不加任何参数创建对象,表示的是当前时间对象。
var date = new Date();
console.log(date);//输出:Date Fri Mar 27 2020 21:33:13 GMT+0800 (中国标准时间),这是我写博客的时间。
  • 传入参数,根据参数创建响应的日期时间对象。
    接受一个字符串参数,该字符串有多种写法:
//字符串的第一种写法
var date = new Date("03/27 2020 21:38:00");
console.log(date);//输出:Date Fri Mar 27 2020 21:38:00 GMT+0800 (中国标准时间)
//字符串的第二种写法
//"英文星期几 英文月名 日 年 时:分:秒 时区"
var date2 = new Date(Friday March 27 2020 21:42:0 GMT+0800);
console.log(date2);
//输出:Date Fri Mar 27 2020 21:42:00 GMT+0800 (中国标准时间)

2.常用的方法

  • getDate() : 返回一个月的某一天(1~31)
  • getDay() : 返回一个星期的某一天(0~6),0是周日,6是周六
  • getMonth() : 返回月份,注意是(0~11)
  • getFullYear() : 返回年份
  • getHours : 返回小时
  • getMinutes : 返回分钟
  • getSeconds : 返回秒数
  • getTime() : 返回时间戳,自从1970年1月1日至今的毫秒数
var date = new Date("03/27 2020 21:52:00");
console.log(date.getDate());//输出:27
console.log(date.getDay());//输出:5
console.log(date.getMonth());//输出:2
console.log(date.getFullYear());//输出:2020
console.log(date.getHours());//输出:21
console.log(date.getMinutes());//输出:52
console.log(date.getSeconds());//输出:0
console.log(date.getTime());//输出:1585317120000

Date类型掌握这些基本的方法就可以了,这不是重点。

Function类型

JS 中万物皆是对象,基本的变量是对象,Date类型的实例是对象。所以函数也可以看做是对象。
1.创建对象

既然函数可以看做是对象,所以就可以使用 new 操作符来创建 Function 对象。

var fun = new Function("console.log('HelloWorld!')");
fun(); //输出:HelloWorld!

一般不使用 new ,而是使用一下两种方法:

function fun(paremeter...) {
   
} 

或者是创建一个匿名函数然后赋值给一个变量:

var fun = function(paremeter...) {

}

最后一种方法最常用。

2.函数的参数
在函数的内部有两个特殊的对象: argumentsthis

其中 arguments 是一个类数组对象,但并不是数组,它包含着传入函数中的所有参数。

既然是对象,就会有相应的属性和方法。

  • 类数组的属性:
  • length : 返回实际传入的实参的数量;
  • callee : 该属性返回的是当前函数对象。
  • 可以使用索引获得相应的参数。
var fun = function(a, b) {
   console.log(arguments.length);
}
fun(1, 23);//输出:2
fun(1);//输出:1
fun(1, 2, 3);//输出:3
//虽然函数定义的是需要两个参数,但是可以传多个实参或者更少实参
var fun = function(a, b) {
   console.log(arguments.callee == fun);
}
fun(1,2); //输出:true。
//也就是说,aruguments.callee就是fun对象。

3.函数的属性和方法
既然函数是对象,所以函数也有属性和方法。

属性有两个:lengthprototype

  • length : 该属性表示函数希望接收的参数的个数(也就是形参的个数,与上述的 arguments 对象并不一样)。如下面的粒子所示:
function sayName(name) {
   console.log(name);
}

function sum(num1, num2) {
   return num1 + num2;
}

function sayHi() {
   console.log("Hi");
}

console.log(sayName.length);//输出:1
console.log(sum.length);//输出:2
console.log(sayHi.length);//输出:0
  • prototype : 该属性是保存它们实例方法的真正所在。换句话说,实际上, toString()valueOf() 等方法实际上都保存在 prototype 名下。

每个函数对象都包含两个非继承而来的方法:call()apply()。这两个方法的用途都是在特定的作用域内调用函数,实际上等于设置函数体内的 this 值。

  • 两个函数的区别
    首先这两个函数的作用相同,都是用来改变函数的作用域。只看不过是形参不同。

  • apply() : 该方法接受两个参数,一个参数是指定运行的作用域,另一是参数数组。其中第二个参数可以是 Array 的实例,也可以是 arguments 对象。例如:

    function sum(num1, num2) {
     return num1 + num2;
    }
    function callSum1(num1, num2) {
       return sum.apply(this, arguments);
    }
    function callSum2(num1, num2) {
       return sum.apply(this, [num1, num2]);
    }
    
  • call() 方法和 apply() 的不同之处在于没有第二个参数,只需要指定函数的作用域(也就是第一个参数)。

  • 两个函数的真正用武之地在于扩充函数的作用域。例如:

    windows.color = "red";
    var obj = {
       color: "blue"
    };
    function sayColor() {
       console.log(this.color);
    }
    sayColor.call(this);//输出:red
    sayColor.call(window);//输出:red.因为this == window
    sayColor.call(obj); //输出:blue
    

基本的包装类型

首先要明白基本的包装类型的作用。
在JS中有五种基本的数据类型,分别是 nullundefinedNumberStringBoolean 类型;

既然是基本类型,为什么字符串会有属性和方法呢?比如 length 属性,比如 index() 方法。

其实这就是包装类,每当读取一个基本的数据类型的时候就会创建一个对应的基本包装类型的对象。又称为临时对象(类似于Java中的装箱和拆箱,也就是说,NumberStringBoolean 这三个类型的变量都可以看做是对象进行操作,所以具有了属性和方法)。

var str = "Hello World!" //这是一个String类型变量
//中间的过程中实际上解析器把它包装成了一个String类型的对象。
console.log(str.length);//所以具有属性和方法,但是使用方法结束后,就又变成了一个string变量
console.log(typeof str);//输出:string

而使用 new 操作符创建一个对象的时候:

//真正的创建一个String对象,该对象在环境中始终存在
var str = new String("Hello World!");
console.log(str.length); //跟上面的一样使用
console.log(typeof str); //输出:Object

所以一般我们不适用包装类创建对象,因为即使是一个变量,解析器在适当的时候回自动的会我们进行包装( Java 中叫装箱 ), 我们就可以使用属性和方法了。使用完成后就会立即拆掉包装( Java 中叫拆箱 )。

String类型

基本的包装类有三个 BooleanNumberString,使用最多的就是 String 类型了。因为我们经常使用其属性和方法。
1.字符方法
可以获取字符串在指定位置处的字符或字符编码。

方法是:charAtcharCodeAt

  • charAt :以单字符字符串的形式返回指定位置的字符。注:返回的仍然是字符串,因为JS中没有字符类型;
  • charCodeAt : 该方法返回的就不是字符了,而是字符的编码。

这两个方法我们一般不使用,因为和数组一样,我们可以使用索引的方法进行访问。形如: str[index]

var strValue = "Hello World!"
console.log(strValue.charAt(1));//输出: "e"
console.log(strValue.charCodeAt(1));//输出: "101",是e的编码
//直接使用索引访问
console.log(strValue[1]);//输出: "e",类似于数组

2.位置方法
类似于( 就是 )数组中的 index()lastIndexOf()。返回某一个字符在字符串中的索引位置。

var str2 = "hello world!";
console.log(str2.index("o"));//输出: 5
console.log(str2.lastIndexOf("o"));//输出: 7

和数组的索引不同的是,字符串中可以指定第二个参数,也就是开始查找的位置。例如:

var str2 = "hello world!";
console.log(str2.indexOf("o", 6)); //输出: 7

3.大小写转换方法
将字符串中的所有字符全部变换成大写或者是小写都是可以通过方法实现。
转换为大写: toUpperCase();
转换为小写: toLowerCase()

var str2 = "Hello World!";
console.log(str2.toUpperCase());//输出: "HELLO WORLD!"
console.log(str2.toLowerCase());//输出: "hello world!"
console.log(str2);//输出: "Hello World!",说明该方法不影响原字符串。

4.拼串和截串
操作方法主要有:concat()slice()substr()substring().

1.concat()方法
concat方法用于连接字符串。

和数组的 concat() 方法一致。

该方法不常使用,因为拼串直接使用 “+” 即可。
2.slice()方法
slice() 方法用于截取子串。可以接受一个或者是两个参数。返回的截取的子串。

和数组的 slice 方法一样。

var str = "hello world!";
console.log(str.slice(6));//输出:world!
console.log(str.slice(0, 5);//输出:hello

3.substr()方法
substr()slice() 方法都是用来截取子串,还有后面的那个 substring() 方法。

substr() 方法的参数和 slice() 方法的第二个参数不同,除此之外都一样。第二个参数不是位置,而是需要截取的字符串的长度。

var str = "hello world!";
console.log(str.substr(6));//输出:world!
console.log(str.substr(0, 3);//输出:hel

Number类型

Number 类型是与数字值对应的引用类型

要创建 Number 对象,需要使用 Number 构造函数。

var numberObject = new Number(10);
console.log(numberObject);//输出:Number { 10 }

但是一般不这样使用。
因为解析器会自动进行包装成数值对象。因此就可以使用属性和方法。

数值对象方法
数值包装成对象后就具有了一些操作方法。
常用的方法有: toString()toFixed()toExponential()toPrecesion()。基本上都是对数字的格式化( 精度 ) 的方法。
1.totring()方法
见名知意,几乎所有的对象都有这个方法,将数值转换成字符串。

var num = new Number(12);//一般不这样创建对象,因为解析器的自动装包功能
var num2 = 12;//这样创建一个数值变量,可以当做对象使用
console.log(num2.toString());//输出: 12

2.toFixed()方法
toFixed 方法的参数有一个。
参数代表的是数值后面显示几位小数。

var num2 = 12;//这样创建一个数值变量,可以当做对象使用
console.log(num2.toFixed(2));//输出:12.00
var num3 = 3.14159;
console.log(num3.toFixed(3));//输出:3.142,会自动的四舍五入

3.totoExponential()方法
toExponential() 方法返回指数表示法。

接受一个参数,也是用来指定小数位数。

var num4 = 100;
console.log(num4.toExponential(1));//输出:1.0e2;

4.toPrecision()方法
上面的 toExponential()方法会将100返回1.0e2,但是在一般情况下,这么小的数字我们不需要使用指数表示法。

toPrecision() 方法是可以自己选取最合适的表示的方法。该方法可能会返回固定大小,也可能会返回指数形式,具体规则看哪种格式合适。

该方法接受一个参数,即表示数值的所有数字的位数( 不包括指数部分 )。

var num = 99;
console.log(num.toPrecision(1));//输出:1e2
console.log(num.toPrecision(2));//输出:99
console.log(num.toPrecision(3));//输出:99.0

Boolean类型

Boolean 类型是基本的包装类之一。所以也可以看做是对象。
使用 new 操作符创建的对象 或者是声明的 Boolean 类型的基本的变量也可以包装成对象。

但是一般更不会使用。因为根本就没有什么方法属性可以使用。只用来当做变量即可。

但要记得可以把三种基本数据类型(NumberStringBoolean )的变量看作对象(临时对象),这是包装类的基本特性。

至此,整个JS中的引用类型总结的差不多了。但是还有正则表达式没有写。
后面会继续说明。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章