Javascript内置对象

包括 Array, Boolean, Date, Function, Math, Number, RegExp, and String.

分为基本类型:underfined, boolean, null, number, string 和引用类型。

区分基本类型与引用类型


  • 基本类型指简单的数据段,按值访问,可以操作保存在变量中的实际的值。
    引用类型指可能有多个值构成的对象,按引用访问,保存在内存中,不允许直接访问。因此只能通过操作引用的对象而不是实际的对象。

  • 可以给引用对象动态地添加属性,而不能给基本类型的值添加属性。

  • 复制基本类型时,会在变量对象上创建一个新值,然后把该值复制到为新变量分配的位置上。
    复制引用类型时,不同在于复制的值实际是一个指针,两个变量实际上引用同一个对象。对其中一个变量操作会影响另一个变量。

typeof 操作符可以检测一个变量是什么类型的数据,但若是引用类型只能检测是对象而不能检测出是什么类型的对象。 typeof + 变量名

instanceof 操作符可以检测引用类型的变量是什么类型的对象(根据原型链识别)。 变量名 + instanceof + constructor (返回 true/false )

1
2
3
alert(person instanceof Object); //变量person是Object吗?
alert(color instanceof Array); //变量color是Array吗?
alert(render instanceof RegExp); //变量render是RegExp吗?

对象


创建对象:两种方法

1、使用 new 操作符

1
var person = new Object();

2、对象字面量法

1
2
3
4
5
6
7
var apple = {
price: 100,
color: 'red',
from: 'GuangZhou',
isFruit: true,
to where: 'BeiJing'
};

访问对象属性

1
2
3
4
5
6
apple.price; //100
apple["price"]; //100
var fruitColor = "color"; // 使用方括号语法可以通过变量来访问对象属性
apple[fruitColor]; // 'red'
//to where 含有空格,不能使用"."来访问,只能用方括号语法.
apple["to where"]; // "BeiJing"

数组(Array)


数组的方法

Array 对象有如下方法:

concat() 将两个数组连接成一个新数组。

1
2
3
var myArray = new Array("1", "2", "3");
myArray = myArray.concat("a", "b", "c");
// myArray is now ["1", "2", "3", "a", "b", "c"]

join(deliminator = “,”) 将数组的所有元素连接成一个字符串。

1
2
var myArray = new Array("Wind", "Rain", "Fire");
var list = myArray.join(" - "); // list is "Wind - Rain - Fire"

push() 在数组的最后增加一个元素并且返回数组的新长度。

1
2
var myArray = new Array("1", "2");
myArray.push("3"); // myArray is now ["1", "2", "3"]

pop() 从数组中删除最后一个元素并且返回该元素。

1
2
var myArray = new Array("1", "2", "3");
var last = myArray.pop(); // myArray is now ["1", "2"], last = "3"

shift() 从数组中删除第一个元素并且返回该元素。

1
2
3
4
5
6
7
var myArray = new Array ("1", "2", "3");
var first = myArray.shift(); // myArray is now ["2", "3"], first is "1"
``` javascript
unshift() 在数组开头增加一个或多个元素并且返回数组的新长度。
``` javascript
var myArray = new Array ("1", "2", "3");
myArray.unshift("4", "5"); // myArray becomes ["4", "5", "1", "2", "3"]

slice(start_index, upto_index) 抽取数组的一个片断并将其作为新数组返回。

1
2
3
4
var myArray = new Array ("a", "b", "c", "d", "e");
myArray = myArray.slice(1, 4);
/* starts at index 1 and extracts all elements
until index 3, returning [ "b", "c", "d"] */

splice 有三种方法:
注意:这种方法会改变原始数组!

1、删除功能,第一个参数为第一项位置,第二个参数为要删除几个。
array.splice(index,num),返回值为删除内容,array为结果值。

1
2
3
4
var array = ['a','b','c','d'];
var removeArray = array.splice(0,2);
alert(array);//弹出c,d
alert(removeArray);//返回值为删除项,即弹出a,b

2、插入功能,第一个参数(插入位置),第二个参数(0),第三个参数(插入的项)
array.splice(index,0,insertValue),返回值为空数组,array值为最终结果值。

1
2
3
4
var array = ['a','b','c','d'];
var removeArray = array.splice(1,0,'insert');
alert(array);//弹出a,insert,b,c,d
alert(removeArray);//弹出空

3、替换功能,第一个参数(起始位置),第二个参数(删除的项数),第三个参数(插入任意数量的项)
array.splice(index,num,insertValue),返回值为删除内容,array为结果值。

1
2
3
4
var array = ['a','b','c','d'];
var removeArray = array.splice(1,1,'insert');
alert(array);//弹出a,insert,c,d
alert(removeArray);//弹出b

reverse() 将数组元素进行反转(颠倒):第一个的数组元素将变为最后一个,而最后的元素将变为第一个。

1
2
3
var myArray = new Array ("1", "2", "3");
myArray.reverse();
// transposes the array so that myArray = [ "3", "2", "1" ]

sort() 对数组元素进行排序。

1
2
var myArray = new Array("Wind", "Rain", "Fire");
myArray.sort(); // sorts the array so that myArrray = [ "Fire", "Rain", "Wind" ]

sort() 也可以接收一个函数用于判定元素的比较结果。该函数对两个值进行比较并且返回以下三个值之一:

如果在排序方式中 a 小于 b,则返回 -1 (或任何负数)

如果在排序方式中 a 大于 b,则返回 1 (或任意正数)

如果 a 和 b 被认为相等,则返回 0。

例如,下面的代码按数组中最后一个字符进行排序:

1
2
3
4
5
6
7
var sortFn = function(a, b){
if (a[a.length - 1] < b[b.length - 1]) return -1;
if (a[a.length - 1] > b[b.length - 1]) return 1;
if (a[a.length - 1] == b[b.length - 1]) return 0;
}
myArray.sort(sortFn);
// sorts the array so that myArray = ["Wind","Fire","Rain"]

indexOf(searchElement[, fromIndex]) 根据给定元素查找数组中第一个匹配的元素,返回其索引值。

1
2
3
4
5
var a = ['a', 'b', 'a', 'b', 'a'];
alert(a.indexOf('b')); // Alerts 1
// Now try again, starting from after the last match
alert(a.indexOf('b', 2)); // Alerts 3
alert(a.indexOf('z')); // Alerts -1, because 'z' was not found

lastIndexOf(searchElement[, fromIndex]) 和indexOf类似,但是是从末尾开始并且是反向查找。

1
2
3
4
5
var a = ['a', 'b', 'c', 'd', 'a', 'b'];
alert(a.lastIndexOf('b')); // Alerts 5
// Now try again, starting from before the last match
alert(a.lastIndexOf('b', 4)); // Alerts 1
alert(a.lastIndexOf('z')); // Alerts -1

forEach(callback[, thisObject]) 对数组的每一项调用callback方法。

1
2
var a = ['a', 'b', 'c'];
a.forEach(alert); // Alerts each item in turn

map(callback[, thisObject]) 对数组的每一项调用callback方法并返回一个新的数组。

1
2
3
var a1 = ['a', 'b', 'c'];
var a2 = a1.map(function(item) { return item.toUpperCase(); });
alert(a2); // Alerts A,B,C

filter(callback[, thisObject]) 对数组的每一项调用callback方法并且返回值为true的项作为一个新数组返回。

1
2
3
var a1 = ['a', 10, 'b', 20, 'c', 30];
var a2 = a1.filter(function(item) { return typeof item == 'number'; });
alert(a2); // Alerts 10,20,30

every(callback[, thisObject]) 如果数组中的每一项调用callback返回都为true则返回true。

1
2
3
4
5
6
7
function isNumber(value){
return typeof value == 'number';
}
var a1 = [1, 2, 3];
alert(a1.every(isNumber)); // Alerts true
var a2 = [1, '2', 3];
alert(a2.every(isNumber)); // Alerts false

some(callback[, thisObject]) 如果数组中的至少一项调用callback返回都为true则返回true。

1
2
3
4
5
6
7
8
9
function isNumber(value){
return typeof value == 'number';
}
var a1 = [1, 2, 3];
alert(a1.some(isNumber)); // Alerts true
var a2 = [1, '2', 3];
alert(a2.some(isNumber)); // Alerts true
var a3 = ['1', '2', '3'];
alert(a3.some(isNumber)); // Alerts false

reduce(callback[, initialValue]) 通过合并两个值然后重复此操作来把一个序列归约成一个值的算法。(比如数组求和)

1
2
3
4
5
var a = [10, 20, 30];
var total = a.reduce(function(first, second) {
return first + second;
}, 0);
alert(total) // Alerts 60

数组迭代方法详情:http://www.w3cplus.com/javascript/array-part-7.html

上面这些函数里面有些需要接受callback 函数作为参数,在这里的被传递进去作为参数的函数叫做遍历器(iterative methods),因为这些方法遍历了整个数组,并在遍历的过程中把需要的值喂给了这些遍历器。此外,可以通过第二个可选的参数用于指定遍历器的执行上下文 this,如果没有给出这个可选的参数,this 将会是这种情况下的取值:函数在一个明确的对象上下文之外被调用,而这种情况下 this 一般指向全局对象(比如 window )

上面的回调函数(遍历器)需要三个参数,第一个是当前遍历到的元素 item ,第二个是当前遍历到的元素的索引 index,第三个是被遍历的数组本身 itself。JavaScript 函数会忽略任何没有在形参中声明的参数,因此有时候你大可以省略后面的索引和数组而不必担心会发生什么不好的事情.

函数(Function)


在JavaScript中,函数是Function类的具体实例。而且都与其它引用类型一样具有属性和方法。函数名实际上是指向函数对象的指针,函数可以作为参数参与到传参和返回值中。

定义

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
//函数声明式定义
function foo(num1,num2){
return num1 + num2;
}
//函数表达式定义
var foo = function(num1,num2){
return num1 + num2;
};
//使用Function构造函数定义
var foo = new Function("num1","num2","return num1 + num2");
//实际上创建一个Function实例并不一定要赋值给具体的指针,可以直接执行
(function(x,y){return x+y})(1,2);
//之所以用圆括号把function(){}括起来是因为js解释器会将function解释为函数声明,而函数声明不能直接跟着(x,y),我们需要将其转换为函数表达式。
//(1,2)表示要传递跟函数的参数。
//上面的例子也可以写成:
function foo(x,y){
return x+y;
}(1,2);
//函数声明的方式无法定义匿名函数,因此如果想使用匿名函数,则必须用函数表达式的定义方式。

注意:1、只有函数声明式存在函数声明提升,调用写在函数声明式的前面也不会报错,因为解析器已经先读取了函数声明,把函数声明放在顶部,所以函数调用不会出错。而函数表达式必须等到JS引擎执行到它所在行时才会解析函数表达式。所以以后尽量写要注意把函数的定义要写在函数调用的前面。

2、声明一个变量并将不带圆括号的函数名赋给它时,是访问函数,即这个变量指向函数的指针,而不是执行函数。例如:

1
2
3
4
5
6
7
8
9
10
function sum(num1,num2) {
return num1 + num2;
}
alert(sum(10,10)); //20
var anothersum = sum;
alert(anothersum(10,10)); //20
sum = null;
alert(anothersum(10,10)); //20

函数的对象特性
因为函数是Function的实例,而函数名仅仅是该实例的一个引用地址。因此可以作为参数和返回值参与到函数的传参过程中。

1
2
3
4
5
6
7
function call_some_function(some_function, some_argument) {
return some_function(some_argument);
}
function add_10(num) {
return num + 10;
}
console.log(call_some_function(add_10,20)); //30

call(), apply() 和 bing()方法

call(), apply(), bind()是每个函数都包含的自有方法。之前已经提到了函数是定义的对象,那么调用函数时候,函数中的 this 是对当前与下变量的调用。而如果想改变函数执行所在域空间,则可以使用call(),apply(),bind()来实现。

1
2
3
4
5
6
7
8
color = 'red';
var o = {color: 'blue'};
function sayColor() {
console.log(this.color);
}
sayColor(); //red
sayColor.call(this); //red
sayColor.call(o); //blue

app()和call()的作用是相同的,区别主要在于传入参数的不同。

1
2
3
4
5
call(this,para1,prar2,prar3) 第一个参数是函数要执行的作用域,后面的参数是函数的输入参数,有多少个依次写多少个。
apply(this,[para1,para2,prara3])第一个参数也是函数要执行的作用域,后面是一个Array的数组对象。
而bind( )方法创建一个新的函数,当被调用时,将其this关键字设置为提供的值,在调用新函数时,在任何提供之前提供一个给定的参数序列。

例如:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
var aFun = {
x: 30,
getX:function(){
return this.x;
}
}
var o = {
x: 20
}
var newFun = aFun.getX.bind(o); //
console.log(newFun) // function() { return this.x; } 跟aFun.getX一样的函数体 只不过newFun的this指向是o对象.
typeof(newFun) // function
newFun(); // 20
// # 修改o对象的x值
o.x = 233;
newFun(); //233

apply、call、bind总结

三者都是用来改变函数的this对象的指向的

三者第一个参数都是this要指向的对象,也就是想指定的上下文

三者都可以利用后续参数传参

bind是返回一个新函数,便于稍后调用;apply、call则是立即调用