JavaScript基础学习笔记(三)---引用类型

Object类型

  • 创建object实例方式有两种
var person = new Object();
person.name = "Nicholas";
person.age = 29;

//对象字面量表示法
var person = {
name : "Nicholas",
age : 29
};
  • 两种访问对象属性的方法
alert(person["name"]);    //"Nicholas"   优点在于可以使用变量来进行访问
alert(person.name);       //"Nicholas"

Array 类型

  • ECMAScript 数组的每一项可以保存任何类型的数据,大小是可以动态调整的,即可以随着数据的添加自动增长以容纳新增数据。使用Array 构造函数时也可以省略new 操作符
var colors = new Array();
var colors = new Array(3); // 创建一个包含3 项的数组
var names = new Array("Greg"); // 创建一个包含1 项,即字符串"Greg"的数组


//数组字面量表示法
var colors = ["red", "blue", "green"]; // 创建一个包含3 个字符串的数组
var names = []; // 创建一个空数组
var values = [1,2,]; // 不要这样!这样会创建一个包含2 或3 项的数组
var options = [,,,,,]; // 不要这样!这样会创建一个包含5 或6 项的数组
  • 数组的length 属性很有特点——它不是只读的。因此,通过设置这个属性,可以从数组的末尾移除项或向数组中添加新项。
var colors = ["red", "blue", "green"]; // 创建一个包含3 个字符串的数组
colors.length = 2;
alert(colors[2]); //undefined

var colors = ["red", "blue", "green"]; // 创建一个包含3 个字符串的数组
colors[99] = "black"; // (在位置99)添加一种颜色
alert(colors.length); // 100
  • 检测数组
if (value instanceof Array){
//对数组执行某些操作
}
//instanceof 操作符的问题在于,它假定只有一个全局执行环境

if (Array.isArray(value)){
//对数组执行某些操作
}
//这个方法的目的是最终确定某个值到底是不是数组,而不管它是在哪个全局执行环境中创建的
  • 转换方法 : 调用数组的toString()方法会返回由数组中每个值的字符串形式拼接而成的一个以逗号分隔的字符串。而调用valueOf()返回的还是数组,,toLocaleString()方法与前两个方法唯一的不同之处在于,这一次为了取得每一项的值,调用的是每一项的toLocale-String()方法,而不是toString()方法。如果使用join()方法,则可以使用不同的分隔符来构建这个字符串。join()方法只接收一个参数,即用作分隔符的字符串,然后返回包含所有数组项的字符串
var colors = ["red", "blue", "green"]; // 创建一个包含3 个字符串的数组
alert(colors.toString()); // red,blue,green
alert(colors.valueOf()); // red,blue,green
alert(colors); // red,blue,green

var colors = ["red", "green", "blue"];
alert(colors.join(",")); //red,green,blue
alert(colors.join("||")); //red||green||blue
  • 栈方法:push()和pop()方法,以便实现类似栈的行为。
var colors = new Array(); // 创建一个数组
var count = colors.push("red", "green"); // 推入两项
alert(count); //2
count = colors.push("black"); // 推入另一项
alert(count); //3
var item = colors.pop(); // 取得最后一项
alert(item); //"black"
alert(colors.length); //2
  • 队列方法:使用shift()和push()方法,可以像使用队列一样使用数组。
var colors = new Array(); //创建一个数组
var count = colors.push("red", "green"); //推入两项
alert(count); //2
count = colors.push("black"); //推入另一项
alert(count); //3
var item = colors.shift(); //取得第一项
alert(item); //"red"
alert(colors.length); //2
  • ECMAScript 还为数组提供了一个unshift()方法。顾名思义,unshift()与shift()的用途相反:它能在数组前端添加任意个项并返回新数组的长度。因此,同时使用unshift()和pop()方法,可以从相反的方向来模拟队列,即在数组的前端添加项,从数组末端移除项,如下面的例子所示。
var colors = new Array(); //创建一个数组
var count = colors.unshift("red", "green"); //推入两项
alert(count); //2
count = colors.unshift("black"); //推入另一项
alert(count); //3
var item = colors.pop(); //取得最后一项
alert(item); //"green"
alert(colors.length); //2
  • 重排序方法:reverse()和sort()reverse()方法会反转数组项的顺序默认情况下,sort()方法按升序排列数组项,即使数组中的每一项都是数值,sort()方法比较的也是字符串sort()方法可以接收一个比较函数作为参数,以便我们指定哪个值位于哪个值的前面。
function compare(value1, value2) {
    if (value1 < value2) {
        return -1;
    } else if (value1 > value2) {
        return 1;
    } else {
        return 0;
    }
}

var values = [0, 1, 5, 10, 15];
values.sort(compare);
alert(values); //0,1,5,10,15
  • 对于数值类型或者其valueOf()方法会返回数值类型的对象类型,可以使用一个更简单的比较函数。这个函数只要用第二个值减第一个值即可。
function compare(value1, value2){
return value2 - value1;
}
  • 操作方法:concat()方法可以基于当前数组中的所有项创建一个新数组在没有给concat()方法传递参数的情况下,它只是复制当前数组并返回副本。如果传递给concat()方法的是一或多个数组,则该方法会将这些数组中的每一项都添加到结果数组中。如果传递的值不是数组,这些值就会被简单地添加到结果数组的末尾
var colors = ["red", "green", "blue"];
var colors2 = colors.concat("yellow", ["black", "brown"]);
alert(colors); //red,green,blue
alert(colors2); //red,green,blue,yellow,black,brown
  • slice(),它能够基于当前数组中的一或多个项创建一个新数组。slice()方法可以接受一或两个参数,即要返回项的起始和结束位置。在只有一个参数的情况下,slice()方法返回从该参数指定位置开始到当前数组末尾的所有项。如果有两个参数,该方法返回起始和结束位置之间的项——但不包括结束位置的项。注意,slice()方法不会影响原始数组
var colors = ["red", "green", "blue", "yellow", "purple"];
var colors2 = colors.slice(1);
var colors3 = colors.slice(1,4);
alert(colors2); //green,blue,yellow,purple
alert(colors3); //green,blue,yellow
  • splice()的主要用途是向数组的中部插入项
    • 删除:可以删除任意数量的项,只需指定2 个参数:要删除的第一项的位置和要删除的项数。例如,splice(0,2)会删除数组中的前两项。
    • 插入:可以向指定位置插入任意数量的项,只需提供3 个参数:起始位置、0(要删除的项数)和要插入的项。如果要插入多个项,可以再传入第四、第五,以至任意多个项。例如,splice(2,0,”red”,”green”)会从当前数组的位置2 开始插入字符串”red”和”green”。
    • 替换:可以向指定位置插入任意数量的项,且同时删除任意数量的项,只需指定3 个参数:起始位置、要删除的项数和要插入的任意数量的项。插入的项数不必与删除的项数相等。例如,splice (2,1,”red”,”green”)会删除当前数组位置2 的项,然后再从位置2 开始插入字符串”red”和”green”。
    • splice()方法始终都会返回一个数组,该数组中包含从原始数组中删除的项(如果没有删除任何项,则返回一个空数组)。
var colors = ["red", "green", "blue"];
var removed = colors.splice(0,1); // 删除第一项
alert(colors); // green,blue
alert(removed); // red,返回的数组中只包含一项
removed = colors.splice(1, 0, "yellow", "orange"); // 从位置1 开始插入两项
alert(colors); // green,yellow,orange,blue
alert(removed); // 返回的是一个空数组
removed = colors.splice(1, 1, "red", "purple"); // 插入两项,删除一项
alert(colors); // green,red,purple,orange,blue
alert(removed); // yellow,返回的数组中只包含一项
  • 位置方法:indexOf()和lastIndexOf()。这两个方法都接收两个参数要查找的项和(可的)表示查找起点位置的索引。其中,indexOf()方法从数组的开头(位置0)开始向后查找,lastIndexOf()方法则从数组的末尾开始向前查找。
var numbers = [1,2,3,4,5,4,3,2,1];
alert(numbers.indexOf(4)); //3
alert(numbers.lastIndexOf(4)); //5
alert(numbers.indexOf(4, 4)); //5
alert(numbers.lastIndexOf(4, 4)); //3
var person = { name: "Nicholas" };
var people = [{ name: "Nicholas" }];
var morePeople = [person];
alert(people.indexOf(person)); //-1
alert(morePeople.indexOf(person)); //0
  • 迭代方法:

    • every():对数组中的每一项运行给定函数,如果该函数对每一项都返回true,则返回true。
    • filter():对数组中的每一项运行给定函数,返回该函数会返回true 的项组成的数组。
    • forEach():对数组中的每一项运行给定函数。这个方法没有返回值。
    • map():对数组中的每一项运行给定函数,返回每次函数调用的结果组成的数组。
    • some():对数组中的每一项运行给定函数,如果该函数对任一项返回true,则返回true。以上方法都不会修改数组中的包含的值。
  • 归并方法:reduce()和reduceRight()。这两个方法都会迭代数组的所有项,然后构建一个最终返回的值。其中,reduce()方法从数组的第一项开始,逐个遍历到最后。而reduceRight()则从数组的最后一项开始,向前遍历到第一项。


Date类型

  • Date.parse()方法接收一个表示日期的字符串参数,然后尝试根据这个字符串返回相应日期的毫秒数
var someDate = new Date("May 25, 2004");//会在后台调用Date.parse()
// 本地时间2000 年1 月1 日午夜零时
var y2k = new Date(2000, 0);
// 本地时间2005 年5 月5 日下午5:55:55
var allFives = new Date(2005, 4, 5, 17, 55, 55);
  • Data.now()方法,返回表示调用这个方法时的日期和时间的毫秒数

  • toDateString()——以特定于实现的格式显示星期几、月、日和年;

  • toTimeString()——以特定于实现的格式显示时、分、秒和时区;

  • toLocaleDateString()——以特定于地区的格式显示星期几、月、日和年;

  • toLocaleTimeString()——以特定于实现的格式显示时、分、秒;

  • toUTCString()——以特定于实现的格式完整的UTC 日期。


RegExp 类型

  • ECMAScript 通过RegExp 类型来支持正则表达式
var expression = / pattern / flags ;
/*
* 匹配第一个"bat"或"cat",不区分大小写
*/
var pattern1 = /[bc]at/i;
/*
* 匹配第一个" [bc]at",不区分大小写
*/
var pattern2 = /\[bc\]at/i;
/*
* 匹配所有以"at"结尾的3 个字符的组合,不区分大小写
*/
var pattern3 = /.at/gi;
/*
* 匹配所有".at",不区分大小写
*/
var pattern4 = /\.at/gi;
  • RegExp 构造函数
/*
* 匹配第一个"bat"或"cat",不区分大小写
*/
var pattern1 = /[bc]at/i;
/*
* 与pattern1 相同,只不过是使用构造函数创建的
*/
var pattern2 = new RegExp("[bc]at", "i");



var text = "this has been a short summer";
var pattern = /(.)hort/g;
/*
* 注意:Opera 不支持input、lastMatch、lastParen 和multiline 属性
* Internet Explorer 不支持multiline 属性
*/
if (pattern.test(text)){
alert(RegExp.input); // this has been a short summer
alert(RegExp.leftContext); // this has been a
alert(RegExp.rightContext); // summer
alert(RegExp.lastMatch); // short
alert(RegExp.lastParen); // s
alert(RegExp.multiline); // false
}

Function 类型

  • 函数实际上是对象。每个函数都是Function 类型的实例,而且都与其他引用类型一样具有属性和方法。由于函数是对象,因此函数名实际上也是一个指向函数对象的指针,换句话说,一个函数可能会有多个名字,不会与某个函数绑定。函数通常是使用函数声明语法定义的。(没有重载)
function sum (num1, num2) {
return num1 + num2;
}

//或者
var sum = function(num1, num2){
return num1 + num2;
};

//或者
var sum = new Function("num1", "num2", "return num1 + num2"); // 不推荐

  • 函数声明与函数表达式

    • 解析器在向执行环境中加载数据时,对函数声明和函数表达式并非一视同仁。解析器会率先读取函数声明,并使其在执行任何代码之前可用(可以访问);至于函数表达式,则必须等到解析器执行到它所在的代码行,才会真正被解释执行
alert(sum(10,10));
function sum(num1, num2){
return num1 + num2;
}
//以上代码完全可以正常运行。因为在代码开始执行之前,解析器就已经通过一个名为函数声明提升的过程,读取并将函数声明添加到执行环境中

alert(sum(10,10));
var sum = function(num1, num2){
return num1 + num2;
};
//以上代码之所以会在运行期间产生错误,原因在于函数位于一个初始化语句中,而不是一个函数声明。换句话说,在执行到函数所在的语句之前,变量sum 中不会保存有对函数的引用;
  • 作为值的函数
    • 因为ECMAScript 中的函数名本身就是变量,所以函数也可以作为值来使用。也就是说,不仅可以像传递参数一样把一个函数传递给另一个函数,而且可以将一个函数作为另一个函数的结果返回。
function callSomeFunction(someFunction, someArgument){
return someFunction(someArgument);
}
//这个函数接受两个参数。第一个参数应该是一个函数,第二个参数应该是要传递给该函数的一个值。然后,就可以像下面的例子一样传递函数了。
function add10(num){
return num + 10;
}
var result1 = callSomeFunction(add10, 10);
alert(result1); //20
function getGreeting(name){
return "Hello, " + name;
}
var result2 = callSomeFunction(getGreeting, "Nicholas");
alert(result2); //"Hello, Nicholas"
  • 函数内部属性
    • arguments 的主要用途是保存函数参数,但这个对象还有一个名叫callee 的属性,该属性是一个指针,指向拥有这个arguments 对象的函数
function factorial(num){
    if (num <=1) {
        return 1;
    } else {
        return num * factorial(num-1)
    }
}
//在函数有名字,而且名字以后也不会变的情况下,这样定义没有问题。但问题是这个函数的执行与函数名factorial 紧紧耦合在了一起。

function factorial(num){
    if (num <=1) {
        return 1;
    } else {
        return num * arguments.callee(num-1)
    }
}
//在这个重写后的factorial()函数的函数体内,没有再引用函数名factorial。这样,无论引用函数时使用的是什么名字,都可以保证正常完成递归调用

//例如
var trueFactorial = factorial;
    factorial = function(){
    return 0;
};
alert(trueFactorial(5)); //120
alert(factorial(5)); //0
  • 函数内部的另一个特殊对象是this,其行为与Java 和C#中的this 大致类似。this引用的是函数据以执行的环境对象

    • 另一个函数对象的属性:caller 这个属性中保存着调用当前函数的函数的引用,如果是在全局作用域中调用当前函数,它的值为null,也可以通过arguments.callee.caller来访问相同的信息。
function outer(){
inner();
}
function inner(){
alert(inner.caller);
}
outer();
//以上代码会导致警告框中显示outer()函数的源代码。因为outer()调用了inter(),所以inner.caller 就指向outer()

function outer(){
inner();
}
function inner(){
alert(arguments.callee.caller);
}
outer();
//为了实现更松散的耦合,也可以通过arguments.callee.caller
来访问相同的信息。
  • 函数属性和方法
    • length 属性表示函数希望接收的命名参数的个数,prototype 是保存它们所有实例方法的真正所在.apply()和call()。这两个方法的用途都是在特定的作用域中调用函数,实际上等于设置函数体内this 对象的值。区别仅在于接收参数的方式不同apply()方法接收两个参数:一个是在其中运行函数的作用域,另一个是参数数组。使用call()方法时,传递给函数的参数必须逐个列举出来
    • 它们真正强大的地方是能够扩充函数赖以运行的作用域。下面来看一个例子。
window.color = "red";
var o = { color: "blue" };
function sayColor(){
alert(this.color);
}
sayColor(); //red
sayColor.call(this); //red
sayColor.call(window); //red
sayColor.call(o); //blue
  • bind()。这个方法会创建一个函数的实例,其this 值会被绑定到传给bind()函数的值。
window.color = "red";
var o = { color: "blue" };
function sayColor(){
alert(this.color);
}
var objectSayColor = sayColor.bind(o);
objectSayColor(); //blue

基本包装类型

  • 每当读取一个基本类型值的时候,后台就会创建一个对应的基本包装类型的对象,从而让我们能够调用一些方法来操作这些数据
var s1 = "some text";
var s2 = s1.substring(2);

//引用类型与基本包装类型的主要区别就是对象的生存期,使用new 操作符创建的引用类型的实例,在执行流离开当前作用域之前都一直保存在内存中。而自动创建的基本包装类型的对象,则只存在于一行代码的执行瞬间,然后立即被销毁。这意味着我们不能在运行时为基本类型值添加属性和方法

var s1 = "some text";
s1.color = "red";
alert(s1.color); //undefined
//是第二行创建的String 对象在执行第三行代码时已经被销毁了。第三行代码又创建自己的String 对象,而该对象没有color 属性
  • Boolean类型
var booleanObject = new Boolean(true);//调用Boolean构造函数并传入true 或false 值

var falseObject = new Boolean(false);
var result = falseObject && true;
alert(result); //true
var falseValue = false;
result = falseValue && true;
alert(result); //false
//要注意分清是对象还是值
  • Number类型
var numberObject = new Number(10);//调用Number 构造函数时向其中传递相应的数值。

var num = 10;
alert(num.toString()); //"10"
alert(num.toString(2)); //"1010"
alert(num.toString(8)); //"12"
alert(num.toString(10)); //"10"
alert(num.toString(16)); //"a"
//为toString()方法传递一个表示基数的参数,告诉它返回几进制数值的字符串形式

var num = 10;
alert(num.toFixed(2)); //"10.00"
//toFixed()方法会按照指定的小数位返回数值的字符串表示
var num = 10.005;
alert(num.toFixed(2)); //"10.01"
//如果数值本身包含的小数位比指定的还多,那么接近指定的最大小数位的值就会舍入
  • String类型
var stringObject = new String("hello world");//可以像这样使用String 构造函数来创建。
  • charAt()方法以单字符字符串的形式返回给定位置的那个字符,
  • charCodeAt()返回给定位置的那个字符字符编码
  • concat(),用于将一或多个字符串拼接起来,返回拼接得到的新字符串。
  • indexOf()方法从字符串的开头向后搜索子字符串,而lastIndexOf()方法是从字符串的末尾向前搜索子字符串,从一个字符串中搜索给定的子字符串,然后返子字符串的位置(如果没有找到该子字符串,则返回-1)。
  • toLowerCase()和toUpperCase()大小写转换
  • match(),在字符串上调用这个方法,本质上与调用RegExp 的exec()方法相同。
var text = "cat, bat, sat, fat";
var pattern = /.at/;
//与pattern.exec(text)相同
var matches = text.match(pattern);
alert(matches.index); //0
alert(matches[0]); //"cat"
alert(pattern.lastIndex); //0
  • search()方法返回字符串中第一个匹配项的索引;如果没有找到匹配项,则返回-1
  • replace()方法,。如果第一个参数是字符串,那么只会替换第一个子字符串。要想替换所有子字符串,唯一的办法就是提供一个正则表达式,而且要指定全局(g)标志
  • split(),这个方法可以基于指定的分隔符将一个字符串分割成多个子字符串,并将结果放在一个数组中
  • localeCompare(),这个方法比较两个字符串
  • fromCharCode()。这个方法的任务是接收一或多个字符编码,然后将它们转换成一个字符串。
    alert(String.fromCharCode(104, 101, 108, 108, 111)); //"hello"

单体内置对象

  • Global对象
    • encodeURI()不会对本身属于URI 的特殊字符进行编码,例如冒号、正斜杠、问号和井字号;而encodeURIComponent()则会对它发现的任何非标准字符进行编码。所以可以对整个URI 使用encodeURI(),而只能对附加在现有URI 后面的字符串使用encodeURIComponent()。
var uri = "http://www.wrox.com/illegal value.htm#start";
//"http://www.wrox.com/illegal%20value.htm#start"
alert(encodeURI(uri));
//"http%3A%2F%2Fwww.wrox.com%2Fillegal%20value.htm%23start"
alert(encodeURIComponent(uri));
  • decodeURI()和decodeURIComponent()进行相应的解码
 var uri = "http%3A%2F%2Fwww.wrox.com%2Fillegal%20value.htm%23start";
//http%3A%2F%2Fwww.wrox.com%2Fillegal value.htm%23start
alert(decodeURI(uri));
//http://www.wrox.com/illegal value.htm#start
alert(decodeURIComponent(uri));
  • eval()方法就像是一个完整的ECMAScript 解析器,它只接受一个参数,即要执行的ECMAScript (或JavaScript)字符串。
var msg = "hello world";
eval("alert(msg)"); //"hello world"

//变量msg 是在eval()调用的环境之外定义的,但其中调用的alert()仍然能够显示"hello world"。这是因为上面第二行代码最终被替换成了一行真正的代码

eval("function sayHi() { alert('hi'); }");
sayHi();

// 函数sayHi()是在eval()内部定义的。但由于对eval()的调用最终会被替换成定义函数的实际代码,因此可以在下一行调用sayHi()
  • 在使用eval()时必须极为谨慎,特别是在用它执行用户输入数据的情况下。否则,可能会有恶意用户输入威胁你的站点或应用程序安全的代码(即所谓的代码注入)

  • window 对象
    • 在全局作用域中声明的所有变量和函数,就都成为了window对象的属性。
    • 另一种取得Global 对象的方法是使用以下代码:
var global = function(){
return this;
}();
//通过简单地返回this 来取得Global 对象
  • Math对象
    • min()和max()方法用于确定一组数值中的最小值和最大值
    • 要找到数组中的最大或最小值,可以像下面这样使用apply()方法。
var values = [1, 2, 3, 4, 5, 6, 7, 8];
var max = Math.max.apply(Math, values);
  • Math.ceil()执行向上舍入,即它总是将数值向上舍入为最接近的整数;
  • Math.floor()执行向下舍入,即它总是将数值向下舍入为最接近的整数;
  • Math.round()执行标准舍入,即它总是将数值四舍五入为最接近的整数(这也是我们在数学课上学到的舍入规则)。
  • Math.random()方法返回大于等于0 小于1 的一个随机数
var num = Math.floor(Math.random() * 10 + 1);//一个1到10 之间的数值

var num = Math.floor(Math.random() * 9 + 2);//2 到10 之间的值
  • selectFrom()接受两个参数:应该返回的最小值和最大值
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值