写在前面:
如题,这篇是看《js高程》这本书的代码部分的笔记,大部分是第5章的引用类型,还有一些其他的js基础知识。
笔记是按个人情况来记的,所以可能不是全部的内容都特别详细,不过都是很基础的东西,毕竟新手。
反正个人而言,全部看完这些代码弄懂,感觉收获还是很大的。
直接上代码,详见代码注释。
下面的代码是在sublime text3上编辑在nodejs上运行过的。
【Object】
这部分掺杂一些看视频《网易web前端微课程》时候的笔记
//Object类型相关代码
function Car(type,color,id){
this.id=id;
this.type=type;
this.color=color;
}
var benz=new Car('benz','black',12345);
for(var key in benz){
console.log(key+':'+benz[key]);
}
//for-in循环输出的属性名顺序是不可预测的,因浏览器而异
Car.prototype.start=function(){
console.log(this.type+'start');
}
for(var key in benz){
console.log(key+':'+benz[key]);
}
for(var key in benz){
if(benz.hasOwnProperty(key)){
console.log(key+':'+benz[key]);
}
}
console.log('-----------------------------');
function setName(obj){
obj.name='Nicholas';
obj=new Object();
obj.name='Greg';
}
var person=new Object();
setName(person);
console.log(person.name);//Nicholas
console.log('-----------------------------');
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:'Nicholas',
age:29
});
//Name:Nicholas
//Age:29
displayInfo({
name:'Greg'
});
//Name:Greg
//这种传递参数的模式最适合需要向函数传入大量可选参数的情形
//比如一些插件的配置方式
【Array】
这部分除了js高程的学习笔记,还有之前看数据结构的时候从网上摘下来的几个方法的实际运用函数。
//shift和unshift都会改变原数组
var arr=['a','b','c'];
console.log(arr.toString());//返回以,分隔值的字符串 a,b,c
console.log(arr.valueOf());//返回数组 [ 'a', 'b', 'c' ]
var retn=arr.shift();
console.log(retn);//返回被删项,a
retn=arr.unshift('A');
console.log(retn);//返回数组新长度,3
console.log('-----------------------------');
//sort
//比较函数
function compare(value1,value2){
if(value1value2){
return 1;
}else{
return 0;
}
}
var values=[2,6,9,4,0,-1];
values.sort(compare);
console.log(values);//[ -1, 0, 2, 4, 6, 9 ]
//sort()通过调用每个项的toString()转型方法,然后比较得到的字符串再排序
//比较函数在第一个参数应在第二个之后排序的情况下返回1,
//在第一个在第二个之前排序要返回-1,
//故 比较函数还可以写成:
function comp(value1,value2){
return value2-value1;
}
var values=[2,6,9,4,0,-1];
values.sort(compare);
console.log(values);//[ -1, 0, 2, 4, 6, 9 ]
console.log('-----------------------------');
//split-join
var sentence = "the quick brown fox jumped over the lazy dog";
//split以' '分割字符串成数组
var words=sentence.split(' ');
for (var i = 0; i < words.length; i++) {
console.log('word'+i+':'+words[i]);
}
//join以' '连接数组元素成字符串
var str1=words.join(' ');
console.log(str1);//the quick brown fox jumped over the lazy dog
//toSring将数组元素用','连接成字符串
var str2=words.toString();
console.log(str2);//the,quick,brown,fox,jumped,over,the,lazy,dog
console.log('----------------------------');
//indexOf-lastIndexOf
//indexOf()判断参数值是否存在,存,返第一个出现该元素的下标,不存,返-1;
//.lastIndexOf()反序查找
//IE9+\Firefox2+\Safari3+\Opera9.5+\Chrome
var names = ["David","Cynthia","Raymond","Clayton","Jennifer"];
var name = 'David';
var position = names.indexOf(name);
if (position >= 0) {
console.log("Found " + name + " at position " + position);
}
else {
console.log(name + " not found in array.");
}
//Found David at position 0
var lastindex=names.lastIndexOf('Clayton');
console.log("Found Clayton at position " + lastindex);//Found Clayton at position 3
console.log('----------------------------');
//splice
var nums = [1,2,3,7,8,9];
var newElements = [4,5,6];
nums.splice(3,0,newElements);
console.log(nums); // [ 1, 2, 3, [ 4, 5, 6 ], 7, 8, 9 ]
var nums = [1,2,3,7,8];
nums.splice(3,0,4,5,6);
console.log(nums);//[ 1, 2, 3, 4, 5, 6, 7, 8 ]
var nums = [1,2,3,100,200,300,400,4,5];
var removed=nums.splice(3,4);//返回被删项
console.log(nums); //[ 1, 2, 3, 4, 5 ]
console.log(removed);//[ 100, 200, 300, 400 ]
var nums = [1,2,3,4,5,6];
nums.splice(0,0,0);//在下标为0的元素前面加入0
console.log(nums);//[ 0, 1, 2, 3, 4, 5, 6 ]
nums.splice(5,0,0);//splice对原数组发生改变
console.log(nums);//[ 0, 1, 2, 3, 4, 0, 5, 6 ]
console.log('----------------------------');
//数组迭代的五个方法,不会改变原数组
//IE9+\Firefox2+\Safari3+\Opera9.5+\Chrome
var numbers=[1,2,3,4,5];
//every每一项都返回真时返回真,some只要有一项返回真就返回真
var everyr=numbers.every(function(item,index,thearray){return item>2;});
console.log(everyr);//false
var somer=numbers.some(function(item,index,thearray){return item>2;});
console.log(somer);//true
function isEven(num) {//是偶数返回true
return num % 2 == 0;
}
var nums = [2, 4, 6, 8, 10];
var even = nums.every(isEven);
if (even) {
console.log("all numbers are even");
} else {
console.log("not all numbers are even");
}
//all numbers are even
console.log('----------------------------');
//filter返回函数返回true的项组成的数组
var numbers=[1,2,3,4,5];
var filterr=numbers.filter(function(item,index,thearray){return item>2;});
console.log(filterr);//[ 3, 4, 5 ]
function isEven(num) {
return num % 2 == 0;
}
function isOdd(num) {
return num % 2 != 0;
}
var nums = [];
for (var i = 0; i < 20; ++i) {
nums[i] = i + 1;
}
var evens = nums.filter(isEven);
console.log("Even numbers: ");
console.log(evens);//[ 2, 4, 6, 8, 10, 12, 14, 16, 18, 20 ]
var odds = nums.filter(isOdd);
console.log("Odd numbers: ");
console.log(odds);//[ 1, 3, 5, 7, 9, 11, 13, 15, 17, 19 ]
//下面使用 filter() 筛选所有成绩及格的分数:
function passing(num) {
return num >= 60;
}
var grades = [];
for (var i = 0; i < 20; ++i) {//随机产生20个[0-100]的成绩
grades[i] = Math.floor(Math.random() * 101);
}
var passGrades = grades.filter(passing);
console.log("All grades:");
console.log(grades);//[ 12, 21, 62, 81, 2, 2, 41, 67, 66, 8, 81, 96, 92, 71, 54, 0, 70, 40, 79, 93 ]
console.log("Passing grades: ");
console.log(passGrades);//[ 62, 81, 67, 66, 81, 96, 92, 71, 70, 79, 93 ]
//可以使用 filter() 方法过滤字符串数组
//下面这个例子过滤掉了那些不包含“cie” 的单词
function afterc(str) {
if (str.indexOf("cie") > -1) {
return true;
}
return false;
}
var words = ["recieve","deceive","percieve","deceit","concieve"];
var misspelled = words.filter(afterc);
console.log(misspelled); // [ 'recieve', 'percieve', 'concieve' ]
console.log('----------------------------');
//map返回每次函数调用结果组成的数组
var numbers=[1,2,3,4,5];
var mapr=numbers.map(function(item, index,thearray) {
return item*item;
});
console.log(mapr);//[ 1, 4, 9, 16, 25 ]
console.log(numbers);//[ 1, 2, 3, 4, 5 ]
function curve(grade) {
return grade += 5;
}
var grades = [77, 65, 81, 92, 83];
var newgrades = grades.map(curve);
console.log(newgrades); // [ 82, 70, 86, 97, 88 ]
function first(word) {
return word[0];
}
var words = ["for", "your", "information"];
var acronym = words.map(first);
console.log(acronym)//[ 'f', 'y', 'i' ]
console.log(acronym.join("")); // fyi
console.log('----------------------------');
//forEach无返回值
var foreachr=numbers.forEach(function(item, index,thearray) {
return item++;
});
console.log(foreachr);//undefined
console.log(numbers);//[ 1, 2, 3, 4, 5 ]
console.log('-----------------------------');
//归并方法
//IE9+\Firefox3+\Safari4+\Opera10.5+\Chrome
var values=[1,2,3,4,5];
var sum=values.reduce(function(prev,cur,index,thearray){
return prev+cur;
});
console.log(sum);//15
console.log(values);//[ 1, 2, 3, 4, 5 ]
var rsum=values.reduceRight(function(prev,cur,index,thearray){
return prev+cur;
});
console.log(rsum);//15
console.log(values);//[ 1, 2, 3, 4, 5 ]
var flattened = [[0, 1], [2, 3], [4, 5]].reduce(function(a, b) {
return a.concat(b);
}, ['a','b','c']);//['a','b','c']作为归并基础的初始值
console.log(flattened);//[ 'a', 'b', 'c', 0, 1, 2, 3, 4, 5 ]
//reduce() 方法也可以用来将数组中的元素连接成一个长的字符串
function concatWords(previousValue,currentValue) {
return previousValue+currentValue;
}
var words = ["the ", "quick ","brown ", "fox "];
var sentence = words.reduce(concatWords);
console.log(sentence); //the quick brown fox
//reduceRight()从右到左
var sentence = words.reduceRight(concatWords);
console.log(sentence); // fox brown quick the
console.log('----------------------------');
console.log(new Date(2017,8,8,13,50));//2017-09-08T05:50:00.000Z
console.log(new Date('May 25,2018'));//2018-05-24T16:00:00.000Z
console.log(Date.now());//1504850147543
console.log(+new Date());//1504850147544
console.log(new Date(2017,8,8,13,50).toLocaleString());//2017-9-8 13:50:00
console.log(new Date(2017,8,8,13,50).toString());//Fri Sep 08 2017 13:50:00 GMT+0800 (中国标准时间)
console.log(new Date(2017,8,8,13,50).valueOf());//1504849800000
console.log(new Date(2017,8,8,14,00).toDateString());//Fri Sep 08 2017
console.log(new Date(2017,8,8,14,00).toTimeString());//14:00:00 GMT+0800 (中国标准时间)
console.log(new Date(2017,8,8,13,50).toLocaleDateString());//2017-9-8
console.log(new Date(2017,8,8,13,50).toLocaleTimeString());//13:50:00
console.log(new Date(2017,8,8,13,50).toUTCString());//Fri, 08 Sep 2017 05:50:00 GMT
console.log('-----------------------------');
var pattern1=/[bc]at/gi;
var pattern2=new RegExp('[bc]at','ig');
console.log(pattern1.test('bcattttaffbcat'));//true
console.log(pattern2.test('bactccbcatbca'));//true
console.log(pattern1.toString());///[bc]at/gi
console.log(pattern1.toLocaleString());///[bc]at/gi
//RegExp实例集成的toLocalString和toString返回正则表达式的字面量,与创建正则表达式方式无关
console.log('-----------------------------');
var re=null,i;
for (var i = 0; i < 5; i++) {
re=/cat/g;
console.log(re.test('catastrophe'));
}
//在ECMAScript3中,第一个循环体实际上只创建了一个RegExp实例,
//所以在循环中再次调用test()会失败。
//第一次匹配后,第二次调用从索引为3的字符开始,
//下一次又从头开始。
//在ECMAScript5中,正则表达式字面量必须像直接调用RegExp构造函数一样,每次都重新创建一个实例。
//IE9+\Firefox4+\Chrome支持
for (var i = 0; i < 5; i++) {
re=new RegExp('cat','g');
console.log(re.test('catastrophe'));
}
console.log('-----------------------------');
var text='fa mom and dad and baby and baby adsfda';
var pattern3=/mom( and dad( and baby)?)?/gi;
var matches=pattern3.exec(text);
console.log(matches.index);//3
console.log(matches.input);//fa mom and dad and baby and baby adsfda
console.log(matches[0]);//mom and dad and baby
console.log(matches[1]);// and dad and baby
console.log(matches[2]);// and baby
console.log(matches[3]);//undefined
console.log('-----------------------------');
var text='cat,bat,sat,fat';
var pattern4=/.at/;
var matches=pattern4.exec(text);
console.log(matches.index);//0
console.log(matches[0]);//cat
console.log(pattern4.lastIndex);//0
matches=pattern4.exec(text);
console.log(matches.index);//0
console.log(matches[0]);//cat
console.log(pattern4.lastIndex);//0
//非全局模式下,每次调用exec返回的都是第一个匹配项,且lastIndex始终不变
var pattern5=/.at/g;
var matches=pattern5.exec(text);
console.log(matches.index);//0
console.log(matches[0]);//cat
console.log(pattern5.lastIndex);//3
matches=pattern5.exec(text);
console.log(matches.index);//5
console.log(matches[0]);//bat
console.log(pattern5.lastIndex);//7
//全局模式下每次调用exec返回下一个匹配项,且lastIndex会增加
//RegExp有9个用于储存捕获组的构造函数属性,调用exec或test时被自动填充
var text='this has been a short summer';
var pattern=/(..)or(.)/g;
if(pattern.test(text)){
console.log(RegExp.$1);//sh
console.log(RegExp.$2);//t
}
var pattern=/(.)hort/g;
if(pattern.test(text)){
console.log(RegExp.input);//this has been a short summer
console.log(RegExp.leftContext);//this has been a
console.log(RegExp.rightContext);// summer
console.log(RegExp.lastMatch);//short
console.log(RegExp.lastParen);//s
console.log(RegExp.multiline);//false或undefined
}
//Opera不支持input、lastMatch、lastParen、multiline
//IE不支持multiline
console.log('-----------------------------');
function sum(num1,num2){
return num1+num2;
}
console.log(sum(10,10));//20
var anotherSum=sum;
console.log(anotherSum(10,10));//20
sum=null;
console.log(anotherSum(10,10));//20
console.log('-----------------------------');
console.log(sum1(1,1));//2
function sum1(num1,num2){
return num1+num2;
}
//console.log(sum2(1,1));//报错,'sum2 is not a function'
var sum2=function(num1,num2){
return num1+num2;
}//函数位于初始化语句中,不是一个函数声明,解析器不会有函数声明提示的过程
console.log('-----------------------------');
function factorial(num){
if(num<=1){
return 1;
}else{
return num*arguments.callee(num-1)
}
//arguments的callee属性指向拥有这个arguments对象的函数
//严格模式下arguments.callee会报错
//这样写解除了factorial与num的耦合
}
console.log(factorial(5));//120
var anotherFactorial=factorial;
factorial =function(){return 0;};
console.log(anotherFactorial(5));//120
console.log(factorial(5));//0
//严格模式下可以这样写
var factorial=(function f(num){
if(num<=1){
return 1;
}else{
return num*f(num-1)
}
});
var anotherFactorial=factorial;
factorial=null;
console.log(anotherFactorial(4));//24
console.log('-----------------------------');
function outer(){
inner();
}
function inner(){
console.log(arguments.callee.caller);
}
outer();//[Function: outer]
//如果是alert会显示outer的源代码
//caller中保存着调用当前函数的函数的引用
console.log('-----------------------------');
//apply()和call()能够扩充函数赖以运行的作用域
//最大的好处是,让对象不需要与方法有任何耦合
//window.color='red';
var o={color:'blue'};
function sayColor(){
console.log(this.color);
}
//sayColor();//red
//sayColor.call(window);//red
sayColor.call(o);//blue
var objSayColor=sayColor.bind(o);
objSayColor();//blue,即使在全局作用域中调用这个函数也返回blue
//查找字符串中指定的某个字母
var str='mfoakp fkpofkpowk fkokfoaofkpa kfwo';
var positions=new Array();
var pos=str.indexOf('f');
var count=0;
while(pos>-1){
positions.push(pos);
pos=str.indexOf('f',pos+1);
count++;
}
console.log(positions);//[ 1, 7, 11, 18, 22, 26, 32 ]
console.log(count);//7
console.log('-----------------------------');
//字符串的模式匹配方法
var text='cat, bat, sat, fat';
var pattern=/.at/;
//match方法类似于RegExp的exec,接收一个参数模式
var matches=text.match(pattern);
console.log(matches.index);//0
console.log(matches[0]);//cat
console.log(pattern.lastIndex);//0
//search返回第一个匹配的索引,没找到返回-1
var pos=text.search(/at/);
console.log(pos);//1
pos=text.search(/ab/);
console.log(pos);//-1
//replace
var result=text.replace('at','ond');
console.log(result);//cond, bat, sat, fat
result=text.replace(/at/g,'ont');
console.log(result);//cont, bont, sont, font
result=text.replace(/(.at)/g,'word:$1');//使用最近一次匹配结果中的内容
console.log(result);//word:cat, word:bat, word:sat, word:fat
//当replace的第二个参数是函数时
function htmlEscape(text){
return text.replace(/[<>"&]/g,function(match,pos,thetext){
switch(match){
case '<':return '<';
case '>':return '>';
case '&':return '&';
case '"':return '"';
}
});
}
console.log(htmlEscape('hello!
'));
//hello!
console.log('-----------------------------');
var colorText='red,blue,green,yellow';
console.log(colorText.split(','));//[ 'red', 'blue', 'green', 'yellow' ]
//split的第二个参数限制数组长度
console.log(colorText.split(',',2));//[ 'red', 'blue' ]
//最后一项和第一项是空串,因为通过正则表达式指定的分隔符出现在了字符串的开头‘red’和末尾‘yellow’
console.log(colorText.split(/[^\,]+/));//[ '', ',', ',', ',', '' ]
console.log('-----------------------------');
【Math】
下面两函数感觉都比较实用
var str='yellow';
function determineOrder(value){
var result=str.localeCompare(value);
if(result<0){
console.log('yellow comes before '+value);
}else if(result>0){
console.log('yellow comes after '+value);
}else{
console.log('yellow is equal to '+value);
}
}
console.log(determineOrder('brick'));//yellow comes after brick
console.log(determineOrder('yellow'));//yellow is equal to yellow
console.log(determineOrder('zoo'));//yellow comes before zoo
//同时因为函数没有返回值所以还会返回一个undefined
console.log('-----------------------------');
function selectFrom(lowerValue,upperValue){
var choices=upperValue-lowerValue+1;
return Math.floor(Math.random()*choices+lowerValue);
}
console.log(selectFrom(2,8));//返回[2,8]区间的数
var colors=['red','green','blue','yellow','black','purple','brown'];
console.log(colors[selectFrom(0,colors.length-1)]);//任意返回一个数组项
console.log('-----------------------------');
console.log(Infinity/Infinity);//NaN
console.log(Infinity%Infinity);//NaN
console.log(Infinity*0);//NaN
console.log(Infinity/2);//Infinity
console.log(Infinity%2);//NaN
console.log("a">3);//false,'a'被解释为NaN
console.log("23"<"3");//true,比较的是字符串第一个字符'2'和'3'的字符编码50和51
console.log('-----------------------------');
var i='helloworld';
switch(i){
case 1:
console.log(1);
break;
case 2:
console.log(2);
break;
case 3:
//合并两种情况
case 4:
console.log('3 or 4');
break;
case 'a':
console.log('a');
break;
case 'hello'+'world'://case后可以是表达式
console.log('hello world');
break;
case i>10 && i<20:
console.log('...');
break;
default:
console.log('other');
}
console.log('-----------------------------');