第五章笔记
这本书已经看完一遍了,现在是看第二遍。目标是不少于三遍。这本书个人感觉真的是写的太好了。由于看第一遍的时候忽略了敲代码(主要是每这个时间精力)。正好放暑假自己的空余时间比较多,所以二遍的时候就是把书上的代码知识点再仔仔细细的过一遍。不知道这次的时间长久。初步估计是三个月(不敢把握,担心杂七杂八的事情凑合起来自己完不成这个任务)。二遍完了就是先学习一下node.js。买了一个域名,自己开发了一个博客,由于留言版这个功能实现起来需要node.js(没有打算用php)的支持,所以网站也就没上线,搁着的。这是我的一个初步计划。
上传的是自己笔记,可能比较乱。但是还可以看下去。其中对一些知识点有自己的一些理解,不深入可是方便理解。
/*function howmangyArray(num1,num2) {
num2 =4;
alert(arguments[0]+arguments[1]);
}
howmangyArray(2,5);
---------------------------------------------------
var person = new Object();
person.name = "HJC";
alert(person.name);
下面这段代码说明只能给引用类型动态添加属性
var name ="hjc";
name.age = 24;
alert(name.age);
复制引用类型的值
var person = new Object();
var person_two = person;
person.name ="hjc";
alert(person_two.name);说明这里是在使用指针进行操作,复制是让原来的地址指向堆中的另外一个对象
------------------------------------------------
if(true){
var color = "blue";
}
alert(color);
function add(num1,num2) {
sum = num1 + num2;
return sum;
}
alert(add(2,5));
alert(sum);
------------------------------------------
var color = "blue";
function getColor() {
var color ="red";注意这里不加这句代码的区别
return color;
}
alert(getColor());
-----------------------------------------
function creatPerson(name) {
var localPerson = new Object();
localPerson.name = name;
return localPerson;
}
var globalPerson = creatPerson("HJC");
globalPerson = null;
----------------------------------------
创建Object实例的两种方式
1.使用new操作符后面跟Object构造函数
var person = new person();
person.name="Hjc";
person.age = 29;
2.对象字面量表示法
var person = {
name:"Hjc",
age :29
}
通过对象字面量定义对象时,实际上不会调用Object构造函数
------------------------------------------------
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";
}
alert(output);
}
displayInfo({
name:"Hjc",
age:30
});
displayInfo({
name:"JCH",
age:21
});
-------------------------
var person = {
name:"Hjc",
age :29
}
var personname = "name";这里是一个特别容易出错的知识点
这里尝试了3种写法
1.var personname = person.name
2.var personname = name
3 var personname = "name"
考虑第一种:首先我尝试打印出personname的值是Hjc,如果此时alert(person[personname]);中括号里面的值为Hjc这个时候
打印出来的结果就是undefined
2.alert(personname)打印不出来任何东西,此时的name不属于这个对象,personname理所当然的得不到任何值,
alert(person[personname])也就得不到任何值。
3alert(personname)按照道理会打印出name字符串,此时存在一个personname="name"的关系,同时我们的表达式
alert(person[personname])等价于alert(person["name"])。此时就可以顺利打印出"Hjc"
alert(personname);
---------------------------------------------------------------------------
创建数组的基本方式有两种
1.使用Array构造函数
var array = new Array();括号里面添加数据可以设置多大的数组
var array = new Array("blue","red");也可以向括号里面传入直接的数据项
记住可以省略new操作符,但是为了规范起见,建议还是把new写出来
2.使用字面量的方式创建数组
var array = [];这种形式的创建方法
var array = [1,2,];
alert(array[2]+" "+array.length);这个打印出来的结果是undefined 和 2 测试到ie8
var array = ["blue","red","green"];
alert(array[2]);
array.length=2;
alert(array[2]);
这里先设置;一个数组长度为3的数组,然后打印数组最后一项,打印出green
后面将数组长度设置为2还是打印最后一项,出来的结果是undefined。
var array = ["blue","red","green"];
alert(Array.isArray(array));检测是不是数组通过isArray(数组名)返回的布尔类型
var person ={
toLocaleString:function () {
return "toLocaleString";
},
toString:function () {
return "toString";
}
};
var person2={
toLocaleString:function () {
return "toLocaleString2";
},
toString:function () {
return "toString2";
}
}
var people =[person,person2];
alert(people.toLocaleString());
alert(people);
alert(people.toString());
数组里面只有显示调用toLocaleString才会使用此方法,否则使用toString方法
和Valueof三者返回都以逗号分隔的字符数组
使用数组表示栈的操作,提供了两个方法pop和push
var array = ["blue","red","green"];
array.push("black","blue");添加在数组的末尾
alert(array.length);
array.pop();删除的是最后一项
alert(array[0]+" "+array[array.length-1]);
var color = array.shift();
alert(color);数组的一个数据出队列
模拟队列只需要记住出队列的方法
array.unshift("yellow");在数组的首位置添加数据,和shift的作用相反
var valueof = ["blue","red","green"];
valueof.reverse();
这里sort会调用toString方法,转换成字符串然后作比较
valueof.sort(function (a,b) {
return b-a;
});如果不要这个函数,那么对于数组1,11,111,2,222,3,4则会产生错误的排序结果
这里面的函数的意思是:如果第一个参数位于第二个参数之前就返回一个负数,如果相等则为零否则返回正数,这里是降序排列
var valueof = [2,3,11,4,1,7,6];
valueof.sort(function (a,b) {
return b-a;
});
alert(valueof);
var valueof = ["blue","red","green"];
var newValueof=valueof.concat("yello");复制一个数组的副本传给新数组,如果里面有参数直接添加到末尾
alert(newValueof);
var valueof = ["blue","red","green"];
var newValueof=valueof.slice(1,3);特别注意这里不包括第二个参数的项,只从1到2
alert(valueof + "--"+newValueof);同时原数组不会被改变
splice有三种用法
1.删除--指定两个参数要删除的位置和要删除的项数
var valueof = ["blue","red","green"];
var newValueof = valueof.splice(0,1);返回删除的项
alert(newValueof+"--"+valueof);对原数组会产生影响
2.插入--指定三个参数起始位置,要删除的项数,要插入的项
var newValueof = valueof.splice(1,2,"black","blue");
alert(newValueof+"--"+valueof);red,green--blue,black,blue
newValueof返回的是被删除的项
3.替换--向指定位置插入任意数量的项,且同时删除任意数量的项---三个参数---起始位置,删除的项数和要插入的项
var valueof = ["blue","red","green"];
var newValueof = valueof.splice(1,1,"black","blue");
alert(newValueof+"--"+valueof);red--blue,black,blue,green
var valueof = [2,3,3,4,1,7,6];
alert(valueof.indexOf(3,2));第二个参数是从这个位置开始查找,包含这个点
alert(valueof.lastIndexOf(3));
迭代方法
var number =[1,2,3,4,5,4,3,2,1];
var everResult = number.every(function (item,index,array) {//三个参数:数组项的值,在数组中的位置,数组对象本身
return item>2;
});//判断数组中的值都大于一个特定值
alert(everResult);
var number =[1,2,3,4,5,4,3,2,1];
var everResult = number.some(function (item,index,array) {//三个参数:数组项的值,在数组中的位置,数组对象本身
return item>2;
});//判断数组中有值大于特定值即可
alert(everResult);
var number =[1,2,3,4,5,4,3,2,1];
var everResult = number.filter(function (item,index,array) {//三个参数:数组项的值,在数组中的位置,数组对象本身
return item>2;
});//构造大于特定值的数组
alert(everResult);
var number =[1,2,3,4,5,4,3,2,1];
var everResult = number.map(function (item,index,array) {//三个参数:数组项的值,在数组中的位置,数组对象本身
return item*2;
});//map主要用于返回函数每次调用后返回的结果
alert(everResult);
var number =[1,2,3,4,5,4,3,2,1];
var everResult = number.forEach(function (item,index,array) {//三个参数:数组项的值,在数组中的位置,数组对象本身
//对数组每一项运行特定的函数,没有返回值
});
alert(everResult);
缩小方法reduce reduceRight
这两个方法都接收两个参数----一个在每一项上调用的函数和缩小基础的初始值
传进去的函数接收四个参数----前一个值,当前值,项的索引,和数组对象
var number = [1,2,3,4,5];
var everyNumber = number.reduce(function (p1, p2, number2, ts) {
return p1+p2;//用来求数组项的和
});
alert(everyNumber);
var number = [1,2,3,4,5];
var everyNumber = number.reduceRight(function (p1, p2, number2, ts) {
return p1+p2;//用来求数组项的和
});
alert(everyNumber);
记住数组也不会调用Array构造函数
------------创建日期对象
var date = new Date(Date.parse("5 32,2014"));//这段错误的代码现在浏览器都会返回Invalid Date
alert(date);
var date = new Date(Date.UTC(2000,0));//Sat Jan 01 2000 08:00:00 GMT+0800 (中国标准时间)
alert(date);
var date = new Date(Date.UTC(2015,4,13,22,22,30));//Thu May 14 2015 06:22:30 GMT+0800 (中国标准时间)
alert(date);
Date.now 返回调用这个方法时的日期和时间的毫秒数
var start = Date.now();
alert(start);
在不支持这个方法的浏览器中只需在new Date()前面添加一个加号转化成字符串
Date类型的valueof根本不会返回字符串,而是返回日期的毫秒表示。所以可以比较方便的使用比较操作符来比较日期
var date = new Date();
alert(date.toLocaleString());//2017/7/27 下午10:33:19
alert(date.toString());//Thu Jul 27 2017 22:33:02 GMT+0800 (中国标准时间)
alert(date.toTimeString());//22:34:04 GMT+0800 (中国标准时间)显示时分秒
alert(date.toDateString());//Thu Jul 27 2017 显示星期几,月,日,年
alert(date.getFullYear());
alert(date.getMonth());
alert(date.getMinutes());
alert(date.getSeconds());
alert(date.getMilliseconds());
------------正则表达
var re =null,
i;
for(i=0;i<10;i++){
re = /cat/g;
re.test("fdjfcat");
}
for(i=0;i<10;i++){
re = new RegExp("cat","g");
re.test("fdjfcat");
}
var text = "mom and dad and baby";
var pattern = /mom( and dad (and baby))?/gi;
var matches = pattern.exec(text);//extc接收一个参数即要应用模式的字符串,然后返回包含第一个匹配信息的数组
alert(matches.index); //没有信息匹配的情况下返回null,返回的时Array属性,但是包含两个额外的属性
alert(matches.input); //index表示匹配出现在字符串中的位置,input表示应用正则表达式的字符串
alert(matches[0]); //数组中第一项是与整个模式匹配的字符串,其他项是是与模式中的的捕获组匹配的字符串
alert(matches[1]);//angd dad angd baby
alert(matches[2]);//and baby
//对于exec()方法而言,即使设置了全局标志,他每次只回返回一个匹配项,在不设置全局标志的情况下,在同一个字符串上
//多次调用exec()方法只会返回第一个匹配项。而在设置了全局标志后,则会每次调用exec()方法都会有查找新的匹配项
var text ="cat,bat,sat,fat";
var pattern1 = /.at/;//这里匹配的是和第一个at相符的词并加上at的前一个字母
var matches = pattern1.exec(text);
alert(matches.index);
alert(matches.input);//应用正则表达式的内容,这里就是text
alert(matches[0]);
alert(pattern1.lastIndex);
var matches = pattern1.exec(text);
alert("---"+matches.index);//没有设置全局变量,这里exec只会返回第一个匹配项
alert("---"+matches.input);//应用正则表达式的内容,这里就是text
alert("---"+matches[0]);
alert("---"+pattern1.lastIndex);
var text ="cat,bat,sat,fat";
var pattern1 = /.at/;//这里匹配的是和第一个at相符的词并加上at的前一个字母
var matches = pattern1.exec(text);
alert(matches.index);
alert(matches.input);//应用正则表达式的内容,这里就是text
alert(matches[0]);
alert(pattern1.lastIndex);
var matches = pattern1.exec(text);
alert("---"+matches.index);//没有设置全局变量,这里exec只会返回第一个匹配项
alert("---"+matches.input);//应用正则表达式的内容,这里就是text
alert("---"+matches[0]);
alert("---"+pattern1.lastIndex);//不是全局变量的情况下,值一直为零
var text ="cat,bt,fat,sat";
var pattern2 =/.at/g;
var matches = pattern2.exec(text);
alert(matches.index);
alert(matches.input);//应用正则表达式的内容,这里就是text
alert(matches[0]);
alert(pattern2.lastIndex);
matches = pattern2.exec(text);
alert("---"+matches.index);//没有设置全局变量,这里exec只会返回第一个匹配项
alert("---"+matches.input);//应用正则表达式的内容,这里就是text
alert("---"+matches[0]);
alert("---"+pattern2.lastIndex);//这一次匹配成功后的下一项的位置如cat lastindex代表的位置是后面那个逗号的位置
var text ="this has been a mshort summershort";
var pattern = /(.)hort/gmi;
if(pattern.test(text)){
document.write("input:"+RegExp.input+"<br>");//input输出全部匹配项
document.write("leftContext:"+RegExp.leftContext+"<br>");//输出匹配项左边的文本
document.write("rightContext:"+RegExp.rightContext+"<br>");//输出匹配项右边边的文本
document.write("lastMatch:"+RegExp.lastMatch+"<br>");//输出匹配项
document.write("lastParen:"+RegExp.lastParen+"<br>");//输出匹配项的首字母
document.write("multiline:"+RegExp.multiline+"<br>");//属性应该被废弃掉了,均为undefined
}
-------------函数
var num = function (number) {
return number+10;
};
var num = function (number1,number2) {
return number1+number2;
};
alert(num(10));
alert(num(100,100));//没有重载,不管参数是否不同,这里都不行
解析器会首先执行函数声明,并使其在执行任何代码之前都可以访问;函数表达式则必须要等到解析器执行到它所在的代码行
alert(sum(10,10));//这里有一个函数声明的提升的过程,读取并将函数声明添加到执行环境中
function sum(num,number) {//即使声明函数函数的代码在调用它的后面,javascript引擎会把函数声明提升到源代码树的顶部
return num+number;
}
----下面这段代码不能运行
alert(sum(10,10));
var sum = function(num,number){
return num+number;
}javascript引擎执行代码是自上而下的,这里是初始化变量sum,引擎就不会把这个函数的声明提升到源代码树的顶部
作为值的函数-----这个记住一点---函数的参数里面可以是函数,这个不需要加括号
//阶乘函数
function factorial(num) {
if(num<=1){
return 1;
}else{
return num * factorial(num-1);
}
}
//----可以改写为如下形式
function factorial(num) {
if(num<=1){
return 1;
}else{
return num * arguments.callee(num-1);//arguments有一个callee属性,这个属性是一个指针,指向用于arguments对象的函数
}
}
window.color = "red";
var o={
color:"blue"
};
function saycolor() {
alert(this.color);//this引用的就是函数据以执行的环境对象。我的理解就是在哪里执行就代表哪一块区域
}
saycolor();
o.saycolor=saycolor;//给对象o添加了一个属性,这里是指针的复制,不能加括号,但是他俩指的是同一个函数
o.saycolor();
function outer() {
inner();
}
function inner() {
alert(inner.caller);//caller保存着调用当前函数的函数的引用,简单理解就是谁调用inner,caller就指向谁
}
outer();
function outer() {
inner();
}
function inner() {//arguments.callee代表这个函数
alert(arguments.callee.caller);//caller保存着调用当前函数的函数的引用,简单理解就是谁调用inner,caller就指向谁
}
outer();
//函数即是对象,每个函数都包含两个属性---length和prototype
//length表示函数希望接收到的参数个数
function sayName(name) {
}
function sum(num1,num2) {
}
function sayHi() {
}
alert(sayName.length+","+sum.length+","+sayHi.length);
//toString和valueof方法实际都保存在prototype下,通过各自的实例对象访问。
//prototype在es5下面是不可枚举的。for-in无法发现
//每个函数都包含两个非继承的方法apply()和call()-----在特定的作用域中调用函数.实际上等于设置函数体内的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]);//这里的this指代sum函数
}
alert(callsum1(10,10));
alert(callsum2(20,20));
//call与apply最大的变化是参数必须全部列出来,第一个参数没有变化
function sum(num1,num2) {
return num1+num2;
}
function callsum(num1,num2) {
return sum.call(this,num1,num2);
}
alert(callsum(10,10));
//call和apply最大的用处是扩充函数的作用域
window.color ="red";
var o= {color:"blue"};
function sayColor() {
alert(this.color);
}
sayColor();
sayColor.call(this);
sayColor.call(window);
sayColor.call(o);
//bind()创建一个函数实例,其this值会被绑定到传给bind()函数的值
window.color = "red";
var o ={color:"blue"};
function sayColor() {
alert(this.color);
}
var objectSayColor = sayColor.bind(o);
objectSayColor();//bind简单的理解为可以给函数绑定作用域
*/