手牵手系列之记录JavaScript高级程序设计(第3版)

背景 

《JavaScript高级程序设计》可谓是前端工程师的圣典,全书比较基础讲述js的知识点。最初想要读这本书并做笔记的目的是巩固基础知识点,弥补不足,希望自己能坚持下来,争取每天都能有新的笔记痕迹。备注:本篇并不一定按顺序阅读记录。

开始

引用类型(第5章)

引用类型是一种数据结构, 用于将数据和功能组织在一起。它也常被称为类,但这种称呼并不妥当。
  • Object 类型

创建 Object 实例的方式有两种。第一种是使用 new 操作符后跟 Object 构造函数

var person = new Object(); 
person.name = "Nicholas"; 
person.age = 29;

另一种方式是使用对象字面量表示法。

var person = { 
 name : "Nicholas", 
 age : 29 
};

备注:开发人员更青睐对象字面量语法

访问对象属性时使用的都是点表示法

alert(person.name);
JavaScript 也可以使用方括号表示法来访问对象的属性
alert(person["name"]);
  • Array 类型

ECMAScript 数组的每一项可以保存任何类型的数据。

创建数组的基本方式有两种。第一种是使用 Array 构造函数

var colors = new Array();
下面的代码将创建 length 值为 20 的数组。
var colors = new Array(20);
也可以向 Array 构造函数传递数组中应该包含的项
var colors = new Array("red", "blue", "green");
创建数组的第二种基本方式是使用数组字面量表示法。
var colors = ["red", "blue", "green"]; // 创建一个包含 3 个字符串的数组
var names = []; // 创建一个空数组
var values = [1,2,]; // 不要这样!这样会创建一个包含 2 或 3 项的数组
var options = [,,,,,]; // 不要这样!这样会创建一个包含 5 或 6 项的数组
在读取和设置数组的值时,要使用方括号并提供相应值的基于 0 的数字索引,如下所示:
var colors = ["red", "blue", "green"]; // 定义一个字符串数组
alert(colors[0]); // 显示第一项
colors[2] = "black"; // 修改第三项
colors[3] = "brown"; // 新增第四项
  • 检测数组

对于一个网页, 或者一个全局作用域而言,使用 instanceof 操作符就能得到满意的结果:

if (value instanceof Array){ 
 //对数组执行某些操作
}

​​​​​ECMAScript 5 新增了 Array.isArray()方法。这个方法的目的是最终确定某 个值到底是不是数组,而不管它是在哪个全局执行环境中创建的。

if (Array.isArray(value)){ 
 //对数组执行某些操作
}
  • 转换方法 
所有对象都具有 toLocaleString() toString() valueOf() 方法。
var colors = ["red", "blue", "green"];
alert(colors.toString()); // red,blue,green
alert(colors.valueOf()); // ["red", "blue", "green"]
console.log(colors.toLocaleString());// red,blue,green

而如果使用 join()方法,则可以使用不同的分隔符来构建这个字符串。

var colors = ["red", "green", "blue"]; 
alert(colors.join(",")); //red,green,blue 
alert(colors.join("||")); //red||green||blue

 备注:如果数组中的某一项的值是 null 或者 undefined,那么该值在 join()、 toLocaleString()、toString()valueOf()方法返回的结果中以空字符串表示。

  • 栈方法

ECMAScript 为数组专门提供了 push()pop()方法,以便 实现类似栈的行为。

push() 方法可以接收任意数量的参数,把它们逐个添加到数组末尾,并返回修改后数组的长度。而
pop() 方法则从数组末尾移除最后一项,减少数组的 length 值,然后返回移除的项。
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
  • 队列方法 

栈数据结构的访问规则是 LIFO(后进先出),而队列数据结构的访问规则是 FIFOFirst-In-First-Out, 先进先出)。 

var colors = ["red", "blue"];
var item = colors.shift(); //取得第一项
alert(item); //"red" 
alert(colors.length); //2

var colors = new Array(); //创建一个数组
var count = colors.unshift("red", "green"); //从前推入两项
alert(count); //2
  • 重排序方法

数组中已经存在两个可以直接用来重排序的方法:reverse()sort()

// 倒序
var values = [1, 2, 3, 4, 5]; 
values.reverse(); 
alert(values); //5,4,3,2,1

// 正序
var values = [0, 1, 5, 10, 15]; 
values.sort(); 
alert(values); //0,1,10,15,5

 备注:因为数值 5 虽然小于 10,但在进行字符串比较时,"10"则位于"5"的前面,于是数组的顺序就被修改了。

// 升序
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

// 降序
 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); // 15,10,5,1,0
  • 操作方法
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()方法不会影响原始数组。

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() 的主要用途是向数组的中部插入项,但使用这种方法的方式则有如下 3 种。
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,返回的数组中只包含一项
  •  位置方法

ECMAScript 5 为数组实例添加了两个位置方法:indexOf()lastIndexOf()

这两个方法都返回要查找的项在数组中的位置,或者在没找到的情况下返回1

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
 
  •  归并方法

ECMAScript 5 还新增了两个归并数组的方法:reduce()reduceRight()

var values = [1,2,3,4,5]; 
var sum = values.reduce(function(prev, cur, index, array){ 
 return prev + cur; 
}); 
alert(sum); //15
var values = [1,2,3,4,5]; 
var sum = values.reduceRight(function(prev, cur, index, array){ 
 return prev + cur; 
}); 
alert(sum); //15
  • Date 类型
//取得开始时间
var start = Date.now();
//取得开始时间
var start = +new Date();
  •  日期格式化方法
toDateString()——以特定于实现的格式显示星期几、月、日和年;
toTimeString()——以特定于实现的格式显示时、分、秒和时区;
toLocaleDateString()——以特定于地区的格式显示星期几、月、日和年;
toLocaleTimeString()——以特定于实现的格式显示时、分、秒;
toUTCString()——以特定于实现的格式完整的 UTC 日期。
  • 日期/时间组件方法
getTime() 返回表示日期的毫秒数;与valueOf()方法返回的值相同
setTime(毫秒) 以毫秒数设置日期,会改变整个日期
getFullYear() 取得4位数的年份(如2007而非仅07)
getUTCFullYear() 返回UTC日期的4位数年份
setFullYear(年) 设置日期的年份。传入的年份值必须是4位数字(如2007而非仅07)
setUTCFullYear(年) 设置UTC日期的年份。传入的年份值必须是4位数字(如2007而非仅07)
getMonth() 返回日期中的月份,其中0表示一月,11表示十二月
getUTCMonth() 返回UTC日期中的月份,其中0表示一月,11表示十二月
setMonth(月) 设置日期的月份。传入的月份值必须大于0,超过11则增加年份
setUTCMonth(月) 设置UTC日期的月份。传入的月份值必须大于0,超过11则增加年份
getDate() 返回日期月份中的天数(1到31)
getUTCDate() 返回UTC日期月份中的天数(1到31)
setDate(日) 设置日期月份中的天数。如果传入的值超过了该月中应有的天数,则增加月份
setUTCDate(日) 设置UTC日期月份中的天数。如果传入的值超过了该月中应有的天数,则增加月份
getDay() 返回日期中星期的星期几(其中0表示星期日,6表示星期六)
getUTCDay() 返回UTC日期中星期的星期几(其中0表示星期日,6表示星期六)
getHours() 返回日期中的小时数(0到23)
getUTCHours() 返回UTC日期中的小时数(0到23)
setHours(时) 设置日期中的小时数。传入的值超过了23则增加月份中的天数
setUTCHours(时) 设置UTC日期中的小时数。传入的值超过了23则增加月份中的天数
getMinutes() 返回日期中的分钟数(0到59)
getUTCMinutes() 返回UTC日期中的分钟数(0到59)
setMinutes(分) 设置日期中的分钟数。传入的值超过59则增加小时数
setUTCMinutes(分) 设置UTC日期中的分钟数。传入的值超过59则增加小时数
getSeconds() 返回日期中的秒数(0到59)
getUTCSeconds() 返回UTC日期中的秒数(0到59)
setSeconds(秒) 设置日期中的秒数。传入的值超过了59会增加分钟数
setUTCSeconds(秒) 设置UTC日期中的秒数。传入的值超过了59会增加分钟数
getMilliseconds() 返回日期中的毫秒数
getUTCMilliseconds() 返回UTC日期中的毫秒数
setMilliseconds(毫秒) 设置日期中的毫秒数
  •  RegExp 类型
g:表示全局(global)模式
i:表示不区分大小写(case-insensitive)模式
m:表示多行(multiline)模式 
/* 
* 匹配字符串中所有"at"的实例
*/ 
var pattern1 = /at/g; 
/* 
* 匹配第一个"bat"或"cat",不区分大小写
*/ 
var pattern2 = /[bc]at/i; 
/* 
* 匹配所有以"at"结尾的 3 个字符的组合,不区分大小写
*/ 
var pattern3 = /.at/gi;

面向对象的程序设计(第6章)

  • 属性类型
[[Configurable]]:表示能否通过 delete 删除属性从而重新定义属性

[[Enumerable]]:表示能否通过 for-in 循环返回属性

[[Writable]]:表示能否修改属性的值

[[Value]]:包含这个属性的数据值 

备注要修改属性默认的特性,必须使用 ECMAScript 5 Object.defineProperty()方法。

var person = {}; 
Object.defineProperty(person, "name", { 
 writable: false, 
 value: "Nicholas" 
}); 
alert(person.name); //"Nicholas" 
person.name = "Greg"; 
alert(person.name); //"Nicholas"

 这个例子创建了一个名为 name 的属性,它的值"Nicholas"是只读的。

var person = {}; 
Object.defineProperty(person, "name", { 
 configurable: false, 
 value: "Nicholas" 
}); 
alert(person.name); //"Nicholas" 
delete person.name; 
alert(person.name); //"Nicholas"
configurable 设置为 false ,表示不能从对象中删除属性。如果对这个属性调用 delete ,则在非严格模式下什么也不会发生,而在严格模式下会导致错误。 一旦把属性定义为不可配置的, 就不能再把它变回可配置了。
var person = {}; 
Object.defineProperty(person, "name", { 
 configurable: false, 
 value: "Nicholas" 
}); 
//抛出错误
Object.defineProperty(person, "name", { 
 configurable: true, 
 value: "Nicholas" 
});
  • 访问器属性
[[Configurable]]:表示能否通过 delete 删除属性从而重新定义属性
[[Enumerable]]:表示能否通过 for-in 循环返回属性
[[Get]]:在读取属性时调用的函数。默认值为 undefined
[[Set]]:在写入属性时调用的函数。默认值为 undefined
  • 工厂模式
function createPerson(name, age, job){ 
 var o = new Object(); 
 o.name = name; 
 o.age = age; 
 o.job = job; 
 o.sayName = function(){ 
 alert(this.name); 
 }; 
 return o; 
} 
var person1 = createPerson("Nicholas", 29, "Software Engineer"); 
var person2 = createPerson("Greg", 27, "Doctor");
  •  构造函数模式
function Person(name, age, job){ 
 this.name = name; 
 this.age = age; 
 this.job = job; 
 this.sayName = function(){ 
 alert(this.name); 
 }; 
} 
var person1 = new Person("Nicholas", 29, "Software Engineer"); 
var person2 = new Person("Greg", 27, "Doctor");
  •  原型模式
function Person(){ 
} 
Person.prototype.name = "Nicholas"; 
Person.prototype.age = 29; 
Person.prototype.job = "Software Engineer"; 
Person.prototype.sayName = function(){ 
 alert(this.name); 
}; 
var person1 = new Person(); 
person1.sayName(); //"Nicholas" 
var person2 = new Person();
person2.sayName(); //"Nicholas" 
alert(person1.sayName == person2.sayName); //true

 备注:判断属性是否在对象中person1.hasOwnProperty("name")或alert("name" in person1)或(hasPrototypeProperty(person, "name")。

 

 

 
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值