Javascript 自学笔记
文章目录
基本入门
- 方法一:直接嵌在网页里,如
<script> alert('hello');</script>
- 方法二:放在单独js文件内,在html中通过
<script src="/static/js/abc.js"></script>
进行调用
基本语法
每个语句以
;
结束,语句块使用{...}
赋值语句:
var x=1;
判断语句:
if (2>1) { x=1; y=2; z=3; }
注释
使用
//
块注释:
/* ... */
数据类型
数字:统一Number,NaN;Infinity
字符串:用单引号或者双引号括起来
布尔值:
true
;false
与或非:
&& || !
比较运算:
==
: 会自动转换数据类型再比较===
不会自动转换数据类型isNaN
是否是无穷
null
:空值
数组
数组里面可以包括任何数据类型,例如
[1,2,3,'hello',null,true]
创建数组除了直接定义,还可以:
new Array(1,2,3);
一般来说,直接使用
var arr=[1,2,3];
访问数组使用:
arr[0]
,arr[1]
…
对象
组成:键+值
var person={ name:'Bob', age:20, tags:['js','web','mobile'], city:'Beijing', hasCar:true, zipcode:null };
键都是字符串类型,值可以是任意数据类型,每个键也称作对象的属性,例如
person
的name
属性为'Bob'
获得对象属性:
person.name; person.zipcode;
变量
var a; var $b=1;//申明变量b,并给b赋值 var s_007='007'; var Answer=true; var t = null; var a = 112; a = 'ABC';
显示变量的内容
var x=100; console.log(x);
操作字符串
字符串不可变,因此不可以对s[i]赋值
var s='hello world'; s.length; s[0]; s[3];
toUpperCase:把一个字符串全部变为大写
toLowerCase:把一个字符串全部变为小写
var s = 'hello'; var upper = s.toUpperCase();
indexOf():搜索字符串出现的位置;
var s = 'hello world'; s.indexOf('world');//返回1 s.indexOf('World');//没有找到指定的字串,返回-1
substring():返回指定索引区间的字串
var s = 'hello,world' s.substring(0,5);//从索引0开始到4,返回‘hello’ s.substring(7);//从索引7开始到结束,返回'world'
操作数组
var arr=[1,2,'hello',null]; arr.length; arr[1]=23; arr;
indexOf():搜索一个元素的位置
var arr=[10,20,'30']; arr.indexOf(10);
slice():截取部分元素
var arr=['1','b','c','3']; arr.slice(0,3);//从0开始到第二个 arr.slice(3);//从索引3开始到结束 arr.slice;//复制数组
unshift:向数组头部添加若干元素
var arr=[1,2]; arr.unshift('1','2');
shift():把array数组的第一个元素删掉
var arr=[1,2]; arr.shift();
sort:对当前数组进行排序
var arr = [1,4,2]; arr.sort();
reverse:把数组元素反向排列
var arr = [1,4,65]; arr.reverse();
splice():修改数组,从指定索引开始删除若干元素,然后再从该位置添加若干元素
arr.splice(2,3);//从索引2开始删除三个元素 arr.splice(2,0,'gll','apple');//从索引2开始删除0个元素,并从索引2之前开始添加新元素‘gll',’apple‘
cancat:把两个数组连接起来
var arr = [1,2,3]; var added = arr.cancat(['a','b','c']);
join:把每个元素都用指定字符串连接起来
var arr = [2,3,4]; arr.join('-');//[2-3-4]
多维数组
var arr=[[20,3,4],[23,4,2],'-'];
对象
var xiaohong = { name: '小红', 'middle-school': ’no.1 middle school' };
访问属性名
xiaohong['name']; xiaohong.name; xiaohong['middle-school'];
动态添加属性
xiaohong.age = 18;
动态删除属性
delete xiaohong.age; delete xiaohong['name'];
检查是否拥有某一属性
'name' in xiaohong;//true
判断是否是自身拥有的属性
xiaohong.hasOwnProperty('name');
条件判断
if () {...} else {...}
var age = 20; if (age>=18) { alert('adult'); } else { alert('teenager'); }
循环
for (i=1;i<10000;i++) { x = x+1; }
for … in:把一个对象的所有属性依次循环出来
var xiaoming = { name: 'xiaoming', age: 20 }; for (var key in xiaoming) { console.log(key); }
要过滤掉对象继承的属性循环出来
for (var key in xiaoming) { if (xiaoming.hasOwnProperty(key)) { console.log(key); } }
遍历数组
var a = [1,2,3]; for (var i in a) { console.log(a[i]); }
while
var x = 0; var n = 90; while (n>0) { x = x+n; n = n-2; }
键值对 Map 和 Set
var m = new Map([['michael',96],['Bob',76],['ten',76]]); m.get('michael');
var m = new Map(); m.set('Adam',65); m.set('Bob',76); m.has('Adam');//是否存在Adam m.get('Adam');//65 m.delete(‘Adam’);//删除'Adam'
Set不存储value,key不重复
var s1 = new Set(); var s2 = new Set([1,2,3]); add(4); delete(3);
iterable
Map和Set无法使用下标循环,可以使用
for ... of
循环遍历var a = ['A','B','C']; var s = new Set(['A','B','C']); var m = new Map([[1,'x'],[2,'y'],[3,'z']]); for (var x of a) //遍历a { console.log(x); } for (var x of s) { console.log(x); } for (var x of m) { console.log(x[0]+'='+x[1]); //输出1=x,2=y,3=z }
更好的,使用
forEach
方法var a = ['A','B','C']; a.forEach(function (element,index,array){ console.log(element + ',index=' + index); }); //A, index = 0 //B, index = 1 //C, index = 2 var s = new Set(['A','B']); s.forEach(function (element,sameelement,set){ console.log(element); }); var m = new Map([[1,'x'],[2,'y'],[3,'z']]); m.forEach(function (value,key,map){ console.log(value); });
函数
函数定义和调用
function abs(x) { if (x>=0) return x; else return -x; }
或者
var abs = function (x) { if (x>=0) return x; else return -x; }
javascript 允许传入任意个参数而不影响调用,例如
abs(-3,'hha')
要避免收到
undefined
,需要对参数进行检查funtion abs(x) { if (typeof x !== 'number') { throw 'Not a number'; } if (x>=0) { ...} }
argument:获得调用者传入的所有参数,可以用于判断是否传入了参数,或者传入的个数
function abs() { if (arguments.length === 0) { return 0; } var x = arguments[0]; erturn x >=0 ? x : -x; }
function foo(a,b,c) { if (arguments.length ===2) { c = b; b = null; } }
由于函数可以接受任意多个参数,所以需要使用arguments来获取所有参数,为了方便,引入了rest参数
function foo(a,b,...rest) { console.log(a); console.log(b); console.log(rest); } fo(1,2,3,4,5); //1 //2 //[3,4,5]
变量
所有变量被绑定到一个全局对象
window
var cou = '23'; alert(cou); alert(window.cou);
定义自己唯一的全局变量
var MYAPP = {}; MYAPP.name = 'myapp'; MYAPP.version = 1.0; MYAPP.foo = function (){ return 'foo'; }
块级作用域声明
function foo() { var sum = 0; for (let i=0;i<100;i++){ sum += i; } }
定义常量 const
const PI = 3.14;
解构赋值
var [x,y,z] = ['hello','js','es']; //x = hello //y = js //z = es
解构赋值也可以忽略某些元素或者嵌套赋值
let [x,[y,z]] = ['hello',['js','es']]; let [,,z] = ['hello','js','es'];
解构赋值也可以对嵌套对象的属性进行赋值
var person = { name:'xiaoming' age: 19, addr: { city:'beijing', street:'no1 street' } } var {name,address:{city,street}} = person;
交换变量值
var x=1; var y=2; [x,y] = [y,x];
快速获取当前页面的域名和路径
var {hostname:domain, pathname:path} = location;
方法
在一个对象中绑定函数,叫做这个对象的方法
其中
this
始终指向当前对象,是一个特殊变量使用
this
前首先使用var that = this;
来捕获this
,否则this
指向全局对象window
var xiaoming = { name:'xiaoming', birth:1990, age:function() { var that = this; function getAge(){ var y = new Date().getFullYear(); return y-that.birth; } return geAge(); } }
apply:指定函数的this指向哪个参数,还可以使用
apply()
方法,第一个参数是需要绑定的变量,第二个是数组,表示函数本身的参数function getage(){ var y = new Date().getFullYear(); return y = this.birth; } var xiaoming = { name: 'xiaoming', birth: 1990, age: getage }; xiaoming.age(); getage.apply(xiaoming,[]);
call:与apply类似,只是参数传入是不需要变成数组
max.apply(null,[2,3,4]); max.call(null,[2,3,4]); //普通函数调用`this`绑定为null
装饰器,不改变原方法统计代码调用次数
高阶函数
让函数的参数能够接收别的函数
function add(x,y,f){ return f(x)+f(y); } var x = add(-5,5,Math.abs); console.log(x);
map
function pow(x) { return x*x; } var arr = [1,2,3,4,5]; var results = arr.map(pow); console.log(results);
当然也可以循环
var f = function (x){ return x*x; }; var arr = [1,2,3,4,5]; var result - []; for (i = 0;i<arr.length;i++) result.push(f(arr[i]));
map还可以用于其他函数,如把数组中所有数字变成字符串
var arr = [1,2,3,4]; arr.map(String);
reduce:把结构和序列的下一个元素累积计算
//求和 var arr = [1,2,3]; arr.reduce(function(x,y){ return x+y; }); //求积 arr.reduce(function(x,y){ return x*y; }); //比如有两个输入参数 //数字组合 arr.reduce(function(x,y){ return x*10+y; }); //[1,3,4,5]->>>1345
把字符串变成数字
var ss = s.split("").map(function(x){ return x*1}); return ss.reduce(function(x,y){ return x*10+y; });
把用户输入的不规范的英文名字,变为首字母大写,其他小写的规范名字。输入:
['adam', 'LISA', 'barT']
,输出:['Adam', 'Lisa', 'Bart']
。return arr.map(function(i){ return i[0].toUpperCase()+i.slice(1).toLowerCase();
利用
map()
把字符串变成整数var arr = ['1','2','3']; var r; r = arr.map(function(i){ return +i; }); //或者 r = arr.map(Number);
filter
//删掉偶数,只保留奇数 var arr = [1,2,3,4]; var r = arr.filter(function(x){ return x%2!==0; });
把空字符串删掉
var arr = ['A','']; var r = arr.filter(function(s){ return s && s.trim(); });
去除数组中的重复元素
r = arr.filter(function (element,index,self){ return self.indexOf(element) === index; });
筛选素数
function get_primes(arr) { return arr.filter(function(x){ if (x===1) return false; else{ var a = true; for (let i = 2;i<x;i++){ if (x%i===0) a = false; } return a; } }) }
排序
数字大小排序,不能简单用
sort
,会出现错误由于
sort
是高阶函数,所以还可以自定义如下:var arr = [1,32,34,2]; arr.sort(function(x,y){ if(x<y){ return -1; } if(x>y){ return 1; } return 0; }); console.log(arr);
倒序排序
var arr = [1,32,34,2]; arr.sort(function(x,y){ if(x<y){ return 1; } if(x>y){ return -1; } return 0; }); console.log(arr);
排序字符串不忽略大小写直接
sort
如果忽略大小写,那么有
var arr = ['Goole','apple','Microsoft']; arr.sort(function(s1,s2){ x1 = s1.toUpperCase(); x2 = s2.toUpperCase(); if (x1<x2){ return -1; } if (x1>x2){ return 1; } return 0; });
注意:
sort()
方法会对数据进行修改
闭包
数组求和:
function sum(arr){{ return arr.reduce(function(x,y){ return x+y; }) }
返回求和函数的函数
function lazy_sum(arr){ var sum = function(){ retuan arr.reduce(function(x,y){ return x+y; }); } return sum; } //调用函数时,返回求和函数f f = lazy_sum([1,2,3,4]); f();//10
箭头函数
x=>x*x; //等价于 function(x){ return x*x; } //返回一个对象 x=>({foo:x});
//箭头函数内部的 this 是语法作用域,由上下文确定 var obj = { birth: 1990, getage:function() { var b = this.birth; var fn = () => new Date().getFullYear() - this.birth; return fn(); } }; obj.getage();
箭头函数简化排序函数
arr.sort((x,y)=>{ return x-y; //或者 return x<y? -1:1; //或者 arr.sort((x,y)=> x-y) });
generator生成器
可以返回多次,定义如下:
function* foo(x){ yield x+1; yield x+2; return x+3; }
产生斐波那契数列
//方法一 function fid(max){ var t, a=0, b=1, arr = [0,1]; while(arr.length<max){ [a,b] = [b,a+b]; arr.push(b); } return arr; } //方法二 function* fid(max){ var t, a = 0, b = 1, n = 0; while (n<max) { yield a; [a,b] = [b,a+b]; n++; } return; } //调用 var f = fid(5); f.next();//0 f.next();//1 f.next();//1 f.next();//2 f.next();//3 //或者使用for of调用 for (var x of fid(10)){ console.log(x); } //依次输出0,1,1,2,3...