引用类型
Object类型
- 创建
创建Object实例有两种方式- 使用new操作符后跟Object构造函数
- 使用对象字面量表示法(不会调用构造函数)
var person = new Object(); //同 var person = {}; var person = new Object(); person.name = "Tom"; person.age = 18; var person = { name:"Tom", // 同 "name":"Tom", age:18 };
注
:对象字面量也是向函数传递大量可选参数的首先方式,如function displayInfo(args) { var output = ""; if (typeof args.name == "string"){ output += "Name: " + args.name + "\n"; } if (typeof args.age == "number"){ output += "Age: " + args.age + "\n"; } console.log(output); } displayInfo({ name : "Tom", age : 18 }); displayInfo({ name : "ming" });
- 访问
访问方式有两种- 点表示法
- 方括号表示法
console.log(person.name); console.log(person["name"]);
Array类型
ECMAScript数组同其他语言一样都是数据的有序列表,ECMAScript数组的每一项可以保存任何类型的数据,而且ECMAScript数组的大小是可以动态调整的,即可以随着数据的添加自动增长以容纳新增数据
- 创建
创建数组有两种方式- 使用Array构造函数
- 使用数组字面量表示法(不会调用构造函数)
var colors = new Array("red","blue","green"); var colors = ["red","blue","green"];
- 检测数组
为了避免多框架所带来的多个不同的执行环境所带来的差异,使用如下方法来检测数组if (Array.isArray(value)){ //对数组执行某些操作 }
- 打印字符串
var colors = ["red","blue","green"]; console.log(colors.toString()); console.log(colors); console.log(colors.valueOf());
- 栈方法
ECMAScript数组也提供了栈的方法-
push()
进栈 -
pop()
出栈
var colors = ["red","blue"]; colors.push("green"); var item = colors.pop(); console.log(item);//green console.log(colors.length);//2
-
- 队列方法
ECMAScript数组也提供了队列的方法-
push()
进队 -
shift()
出队
var colors = ["red","blue"]; colors.push("green"); var item = colors.shift(); console.log(item);//red console.log(colors.length);//2
-
- 反向队列
即在数组前端添加项,从数组末端移除项-
unshift()
在数组前端添加任意个项并返回长度 pop()
var colors = ["red","blue"]; colors.unshift("green"); console.log(colors);//[ 'green', 'red', 'blue' ] var item = colors.pop(); console.log(item);//blue console.log(colors.length);//2
-
- 排序
使用sort()
和reverse()
进行排序,reverse()
会反转数组的顺序,sort()
会重小到大进行排序,同时还可以自定义排序方式var students = [{name:"stu1",age:12},{name:"stu2",age:13},{name:"stu3",age:15},{name:"stu4",age:10}]; students.sort((value1, value2) => { if (value1.age < value2.age){ return -1; } else if (value1.age > value2.age){ return 1; }else { return 0; } }); students.sort(function (value1,value2) { if (value1.age < value2.age){ return -1; } else if (value1.age > value2.age){ return 1; }else { return 0; } }); console.log(students); //{ name: 'stu4', age: 10 },{ name: 'stu1', age: 12 },{ name: 'stu2', age: 13 },{ name: 'stu3', age: 15 }
- 操作方法
-
concat()
可以基于当前数组中的所有项创建一个新数组。
具体来说,这个方法会先创建当前数组一个副本,然后将接收到的参数添加到这个副本的末尾,最后返回新构建的数组var colors = ["red","green","blue"]; var colors2 = colors.concat("yellowd",["black","brown"]); console.log(colors); //[ 'red', 'green', 'blue' ] console.log(colors2); //[ 'red', 'green', 'blue', 'yellowd', 'black', 'brown' ]
-
slice()
能够基于当前数组的一个或多个创建一个数组
在只有一个参数的情况下,slice()
方法返回从该参数指定位置开始到当前数组末尾的所有项。所有有两个参数,该方法返回起始位置和结束位置之间的项-不包括结束位置的项var colors = ["red","green","blue","yellow","purple"]; //[ 'green', 'blue', 'yellow', 'purple' ] console.log(colors.slice(1)); // [ 'green', 'blue', 'yellow' ] console.log(colors.slice(1,4));
-
splice()
删除方法
可以删除任意数量的项,第一个参数为要删除的第一项的位置,第二个参数为要删除的项数
插入方法var colors = ["red","green","blue","yellow","purple"]; var removed = colors.splice(2,1); //[ 'blue' ] console.log(removed); //[ 'red', 'green', 'yellow', 'purple' ] console.log(colors);
可以向指定位置插入任意数量的项,需要提供三个参数:起始位置、0、要插入的项数
替换方法var colors = ["red","green","blue"]; colors.splice(1,0,"yellow");//返回null //[ 'red', 'yellow', 'green', 'blue' ] console.log(colors);
可以向指定位置插入任意数量的项,且同时删除任意数量的项。需要提供三个参数:起始位置、要删除的项数和要插入的任意数量的项var colors = ["red","green","blue"]; var removed = colors.splice(1,1,"yellow","black");//返回null //[ 'green' ] console.log(removed); // [ 'red', 'yellow', 'black', 'blue' ] console.log(colors);
-
- 位置方法
使用indexOf()
和lastIndexOf()
方法查找特定项在数组中的位置var colors = ["red","green","blue","yellow","purple"]; console.log(colors.indexOf("blue"));//2 console.log(colors.lastIndexOf("yellow"));//3
- 迭代方法
共有五种迭代方式
每个方法需要接收两个参数:要在每一项上运行的函数和(可选的)运行该函数的作用域对象——影响this值。传入这些方法中的函数会接收三个参数:数组项的值、该项在数组中的位置和数组对象本身。-
every()
对数组中的每一项运行给定函数,如果该函数对每一项都返回true,则返回true -
filter()
对数组中的每一项运行给定函数,返回该函数会返回true的项组成的数组 -
forEach()
对数组中的每一项运行给定函数,这个方法没有返回值 -
map()
对数组中的每一项运行给定函数,返回每次函数调用的结果组成的数组 -
some()
对数组中的每一项运行给定函数,如果该函数对任一项返回true,则返回true
var numbers = [1,2,3,4,5,4,3,2,1]; var result = numbers.every((value, index, array) => { return (value > 2); }); console.log(result);//false result = numbers.some((value, index, array) => { return (value > 2);//true }); console.log(result); result = numbers.filter((value, index, array) => { return (value > 2); }); //[ 3, 4, 5, 4, 3 ] console.log(result); result = numbers.map((value, index, array) => { return (value * 2); }); // [ 2, 4, 6, 8, 10, 8, 6, 4, 2 ] console.log(result);
-
- 归并方法
reduce()
和reduceRight()
这两个方法都会迭代数组的所有项,然后构建一个最终返回的值。reduce()从第一项开始向后遍历,reduceRight()从最后一项开始向前遍历
这两个方法都接收两个参数:1个在每一项上调用的函数和(可选的)作为归并基础的初始值。传入的函数接收4个参数:前一个值、当前值、项的索引和数组对象,这个函数返回的任何值都会作为第一个参数自动传给下一项。var numbers = [1,2,3,4,5]; var sum = numbers.reduceRight((previousValue, currentValue, currentIndex, array) => { return previousValue+currentValue; }); console.log(sum);//15
Function类型
函数实际上是对象,每个函数都是Function类型的实例,而且都与其他引用类型一样具有属性和方法。
//函数声明
function sum(num1,num2) {
return num1+num2;
}
console.log(sum(1,2));//3
//函数表达式
var sum = function (num1,num2) {
return num1+num2;
}
console.log(sum(1,2));//3
var sum = new Function("num1","num2","return num1+num2");
console.log(sum(1,2));//3
由于函数名仅仅是指向函数的指针,因此函数名与包含对象指针的其他变量没有什么不同。换句话说,一个函数可能会有多个名字
function sum(num1,num2) {
return num1+num2;
}
console.log(sum(1,2));
var sum1 = sum;
console.log(sum1(1,2));
sum = null;
console.log(sum1(1,2));
-
函数声明与函数表达式
实际上,解析器在向执行环境中加载数据时,对函数声明和函数表达式并非一视同仁。
解析器会率先读取函数声明,并使其在执行任何代码之前可用(可以访问)
至于函数表达式,则必须等到解析器执行到它所在的代码行,才会真正被解释执行console.log(sum(1,2)); function sum(num1,num2) { return num1+num2; }
以上代码可以完全运行
console.log(sum(1,2)); var sum = function (num1,num2) { return num1+num2; }
以上代码不能运行
-
函数的内部属性
在函数内部,有两个特殊的对象:arguments
和this
。-
arguments
虽然arguments
的主要用途是保存函数参数,但这个对象还有一个名叫callee
的属性,该属性是一个指针,指向拥有这个arguments
对象的函数function factorial(num) { if (num<=1){ return 1; } return num * factorial(num-1); } console.log(factorial(5));//120 //解耦 function factorial(num) { if (num<=1){ return 1; } return num * arguments.callee(num-1); } console.log(factorial(5));//120
-
this
this
引用的是函数执行的环境对象——或者也可以说是this值(当前网页的全局作用域中调用函数时,this对象引用的就是window) -
caller
这个属性中保存着调用当前函数的函数的引用,如果是在全局作用域中调用当前函数,他的值为nullfunction outer() { inner(); } function inner() { console.log(arguments.callee.caller); //同 console.log(inner.caller); } outer();
-
-
函数属性和方法
函数也有属性和方法。每个函数都包含两个属性:length
和prototype
-
length
length
属性表示函数希望接收的命名参数的个数function f1() { } function f2(arg) { } function f3(arg1,arg2) { } console.log(f1.length);//0 console.log(f2.length);//1 console.log(f3.length);//2
-
prototype
是保存它们所有实例方法的真正所在
每个函数都包含两个非继承而来的方法
apply()
和call()
这两个方法的用途都是在特定的作用域中调用函数,实际上等于设置函数体内this对象的值-
apply()
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]); } console.log(callSum1(10,20));//30 console.log(callSum2(10,20));//30
-
call()
call()
与apply()
基本相同,call()
的第一个没有变化,变化的是其余参数都直接传递给函数function callSum(num1,num2) { return sum.call(this,num1,num2); } console.log(callSum(10,20));//30
注
:call()
与apply()
真正强大的地方是能够扩展函数赖以运行的作用域window.color="red"; var o = {color:"blue"}; function sayColor() { console.log(this.color); } sayColor.call(this);//red sayColor.call(window);//red sayColor.call(o);//blue
使用
call()
与apply()
来扩充作用域的最大好处,就是对象不需要与方法有任何耦合关系。-
bind()
这个方法会创建一个函数的实例,其this值会被绑定到传给bind()
函数的值color = "red"; var o = {color : "blue"}; function sayColor() { console.log(this.color); } var objectSayColor = sayColor.bind(o); objectSayColor();//blue
-
基本包装类型
为了方便便于操作基本类型值,ECMAScript还提供了3个特殊的引用类型:Boolean、Number、String。这些类型与其他引用类型相似,但同时也具有与各自的基本类型相应的特殊行为。实际上,每当读取一个基本类型值的时候,后台就会创建一个对应的基本包装类型的对象,从而让我们能够调用一些方法来操作这些数据。
var s1 = "some text";
var s2 = s1.substring(2);
当第二行代码访问s1时,访问过程处于一种读取模式,也就是要从内存中读取这个字符串的值,而在读取模式中访问字符串时,后台都会自动完成下列处理
- 创建String类型的一个实例
- 在实例上调用指定的方法
- 销毁这个实例
相当于解释器完成了如下代码
var s1 = new String("some text");
var s2 = s1.substring(2);
s1 = null;
注
:引用类型与基本包装类型的主要区别就是对象的生存期。使用new操作符创建的引用类型的实例,在执行流离开当前作用域之前都一直保存在内存中。而自动创建的基本包装类型的对象,则只存在于一行代码的执行瞬间,然后立即被销毁
- Number
Number类型也重写了valueOf()
、toLocaleString()
和toString()
方法
重写后的valueOf()
方法返回对象表示的基本类型的数值,另外两个方法则返回字符串形式的数值-
toString()
可以传递一个表示基数的参数,告诉它返回进制数值的字符串形式var num = 10; console.log(num.toString());//10 console.log(num.toString(2));//1010 console.log(num.toString(8));//12 console.log(num.toString(10));//10 console.log(num.toString(16));//a
-
toFixed()
该方法会按照指定的小数位返回数值的字符串表示var num = 10; console.log(num.toFixed(2));//10.00
-
toExponential()
该方法返回以指数表示法表示的数值的字符串形式var num = 10; console.log(num.toExponential(1));//1.0e+1
-
toPrecision()
该方法可能会返回固定大小(fixed)格式,也有可能返回指数(exponential)格式var num = 99; console.log(num.toPrecision(1));//1e+2 console.log(num.toPrecision(2));//99 console.log(num.toPrecision(3));//99.0
-
- String类型
String类型是字符串的对象包装类型,可以按照如下方式创建var str1 = "hello world"; var str2 = new String("hello world");
-
length
属性
该属性用于表示字符串中包含多个字符串 - 字符方法
两个用于访问字符串中特定字符的方法是charAt()
和charCodeAt()
。这两个方法都接收一个参数,基于0的字符位置var str = "hello world"; console.log(str.charAt(1));//e console.log(str.charCodeAt(1));//101
- 字符串操作方法
-
concat()
用于将一个或多个字符串拼接起来,返回拼接得到的新字符串var str = "hello".concat(" world","!","!"); console.log(str);//hello world!!
slice()
、substr()
和substring()
。这三个方法都会返回被操作字符串的一个子字符串-
slice()
第一个参数指定字符串开始的位置,第二个参数指定子字符串最后一个字符后面的位置var str = "hello world"; console.log(str.slice(3));//lo world console.log(str.slice(3,7));//lo w
-
substring()
第一个参数指定字符串开始的位置,第二个参数指定子字符串最后一个字符后面的位置var str = "hello world"; console.log(str.substring(3));//lo world console.log(str.substring(3,7));//lo w
-
substr()
第一个参数指定字符串开始的位置,第二个参数指定返回字符的个数var str = "hello world"; console.log(str.substr(3));//lo world console.log(str.substr(3,7));//lo worl
-
- 字符串位置方法
indexOf()
和lastIndexOf()
。这两个方法都是从一个字符串中搜素给定的子字符串,然后返回子字符串的位置(如果没有返回-1)-
indexOf()
从头开始搜索var str = "hello world"; console.log(str.indexOf("o"));//4
-
lastIndexOf()
从末尾开始搜索var str = "hello world"; console.log(str.lastIndexOf("o"));//7
-
-
trim()
方法
该方法会创建一个字符串的副本,删除前置及后缀的所有空格,然后返回结果var str = " hello world "; console.log(str.trim());//hello world console.log(str);//" hello world "
- 字符串大小写转换方法
toUpperCase()
和toLowerCase()
是两个经典的方法,而toLocaleUpperCase()
和toLocaleLowerCase()
方法则是针对特定地区的实现,一些地区可能会不同var str = "Hello World"; console.log(str.toUpperCase());//HELLO WORLD console.log(str.toLocaleUpperCase());//HELLO WORLD console.log(str.toLowerCase());//hello world console.log(str.toLocaleLowerCase());//hello world
- 字符串正则表达式方法
-
match()
var text = "cat, bat, sat, fat"; var matchs = text.match(/.at/); console.log(matchs.index);//0
-
search()
search()
方法返回字符串第一个匹配项的索引,如果没有返回-1,该方法始终是从开头查找var text = "cat, bat, sat, fat"; var pos = text.search(/.at/); console.log(pos);//0
-
-
localeCompare()
该方法用于比较字符串var str = "yellow"; console.log(str.localeCompare("yellow"));//0 console.log(str.localeCompare("brick"));//1 console.log(str.localeCompare("zoo"));//-1
-
单体内置对象
-
global
对象
不属于任何对象的属性和方法,最终都是它的属性和方法。事实上,也没有全局变量或者全局函数;所有在全局定义的属性和函数,都是global
对象的属性- URL编码
encodeURI()
和encodeURIComponent()
方法可以对URI进行编码,以便发送给浏览器。对整个URI使用encodeURI()
。而对附加在现有URI后面的字符串使用encodeURIComponent()
与这两个方法对应的是//http://www.baidu.com/index%20mm.html console.log(encodeURI("http://www.baidu.com/index mm.html")); //http%3A%2F%2Fwww.baidu.com%2Findex%20mm.html%2F%E9%92%A2%E9%93%81 console.log(encodeURIComponent("http://www.baidu.com/index mm.html/钢铁"));
decodeURI()
和decodeURIComponent()
decodeURI()
只能对使用encodeURI()
替换的字符进行解码,同样decodeURIComponent()
能够解码使用encodeURIComponent()
编码的所有字符//http%3A%2F%2Fwww.baidu.com%2Findex mm.html%2F钢铁 console.log(decodeURI("http%3A%2F%2Fwww.baidu.com%2Findex%20mm.html%2F%E9%92%A2%E9%93%81")); //http://www.baidu.com/index mm.html/钢铁 console.log(decodeURIComponent("http%3A%2F%2Fwww.baidu.com%2Findex%20mm.html%2F%E9%92%A2%E9%93%81"));
-
eval()
方法
该方法就像是一个完整的ECMAScript解析器,它只接受一个参数,即要执行的ECMAScript(或JS)字符串
通过eval("console.log(\"hello world\");"); console.log("hello world");
eval()
执行的代码被认为是包含该次调用的执行环境一部分,因此被执行的代码具有与该执行环境相同的作用域链。
注
:严格模式下,在外部访问不到eval()
中创建的任何变量或者函数,而且为eval
赋值也会导致错误
- URL编码
-
Math
对象
Math
对象提供的计算功能执行起来要快得多-
min()
和max()
min()
和max()
用于确定一组数值里面的最大和最小值。这两个方法都可以接收任意多个数值的参数console.log(Math.max(3,52,32,16));//52 console.log(Math.min(3,52,32,16));//3
- 舍入方法
将小数值舍入整数有几个方法Math.ceil()
,Math.floor()
,Math.round()
-
Math.ceil()
执行向上舍入 -
Math.floor()
执行向下舍入 -
Math.round()
执行标准舍入,四舍五入
console.log(Math.ceil(29.4));//30 console.log(Math.floor(29.4));//29 console.log(Math.round(29.4));//29
-
-
random()
方法
Math.random()
方法返回大于等于0小于1的一个随机数
可以套用下面的公式,获得随机值
例如获得2到9则为:值 = Math.floor(Math.random() * 可能值的总数 + 第一个可能的值)
num = Math.floor(Math.random() * 9 + 2);
-