首页 > 编程 > JavaScript > 正文

Javascript学习笔记

2019-11-09 17:04:51
字体:
来源:转载
供稿:网友

首先先附上我看的这份教程吧!

http://www.liaoxuefeng.com/wiki/001434446689867b27157e896e74d51a89c25cc8b43bdb3000

数据类型和变量

Nunber包含整数,浮点数,负数。其中 NaN表示不是一个数字, Infinity表示无限大,超出了js的计算范围;字符串可以使用单引号,也可以使用双引号引起来,没有字符,只有字符串;布尔值true false与或非&& || !比较运算符 > < == === 其中 == 和 === 的区别是,==会自动转换数据类型, ===不会自动转换类型(false==0;//true,false===0;//false)特殊的情况:NaN === NaN;//false 而 isNaN(NaN);//true浮点数的比较不能直接比较,直接比较返回来的是false,要取他们之间的绝对值,小于某个阀值;null 和 undefine null表示为空,undefine表示未定义,类似于java的未初始化数组,声明数组的两种方式 var arr=[23,56,48]; var arr = new array(1,63,45);对象,对象是由一组键值对组成的无序的集合,类似于java的map集合。var person={ name:'zhangsan',age:20}对象取值的时候以.的方式取值,例如 person.name字符串常用的api取某个字符 和数组一样,var s = "abc"; s[2] 的值是 c;字符串一旦定义,是不可改变的,var str="asdfg";str[2]="5";alert(str); 最后弹出来的还是asdfgtoUpperCase toLowerCase 将字符串转为大写(小写)indexOf 搜索指定字符串的位置。substring 截取字符串,传入1个参数时指从这里截取到结尾,两个参数表示从哪里到哪里。数组常用的api取值 arr[2] 取第三个值,如果长度为3,你下标写的是3,它不会报数组越界,而是返回给你一个undefine赋值,和java一样,arr[2]="dsa";同样,赋值也不会报越界,如果超过了,会自动扩展,例如一个数组长度为3,那么arr[5]="sad"; 那么执行完这句后,数组的长度会自动的扩展到6,而 arr[3] arr[4] 的值为undefine取长度,直接使用数组的length属性就可以取到数组的长度。indexOf 取某个元素的索引,没有则返回-1;这个时候需要注意的是数据类型要一一对应,数组里面的是30,你indexOf("30"); 返回来的是-1;slice()截取,和字符串的substring一样,当此函数不传任何参数的时候,将改数组复制一份。push 和 pop push表示向数组的末尾添加若干个元素,pop则表示从该数组的结尾删除一个元素。unshift 和 shift 和push,pop 一样。unshift表示往头部添加,shift表示从开头删除。sort() 排序,直接调用的话,按照自然排序。reverse() 反转splice 修改数组, arr.splice(2, 3, 'Google', 'Facebook');// 从索引2开始删除3个元素,然后再添加两个元素,arr.splice(2, 2); // 只删除,不添加,arr.splice(2, 0, 'Google', 'Facebook'); // 只添加,不删除concat拼接数组,var arr = ['A', 'B', 'C'];arr.concat(1, 2, [3, 4]); // ['A', 'B', 'C', 1, 2, 3, 4]join()var arr = ['A', 'B', 'C', 1, 2, 3];arr.join("-"); // 'A-B-C-1-2-3'; join里面不能不传。可以传""对象:对象和java中的map集合类似,写法和C的结构体有点类似。对象以键值对的形式出现,访问属性的时候用.来表示。属性名和属性值之间用分号来表示。对象的属性名必须是一个有效的变量名,如果是一个包含有特殊符号的变量,必须用单引号引起来,否则这个属性无法使用。获取属性的两种方式:entity.key entity['key'] 如果key里面有特殊的符号,必须使用第二种方式获取。in 判断某个属性是否存在,‘key’ in entity 判断entity中是否存在key属性。存在则true,不存在则falsehasOwnPRoperty() 判断自身是否存在某个属性。entity.hasOwnProperty('key'); 和 in 不一样的是,in可以判断它父对象的属性,任何对象最终都继承自Object。if-else和java没啥区别啊,支持嵌套,支持else if循环for 和 java中的好像没啥区别啊。for in 可以用来循环实体,用来把一个对象的所有属性都循环的取出来。for(var key in entity){if(entity.hasOwnProperty('key')){alert(entity.[key])}}for in 循环数组。注意的是,循环数组得到的是String,而不是Number    var a = ['A', 'B', 'C'];for (var i in a) {   alert(i); // '0', '1', '2'   alert(a[i]);//'A','B','C'}循环还有while 和 do-whileMap Map和java一样,key不可以重复。Map的初始化:var map = new Map([['Michael', 95], ['Bob', 75], ['Tracy', 85]]);map.get('key');获取map.set('key',value); 设置,如果这个键对应的值已存在,则覆盖。map.delete('key'); 删除Set 和 java  中的set类似set的初始化:var s2 = new Set([1, 2, 3]); // 含1, 2, 3set.add();添加 添加的时候可以重复添加,但不会有效果,也不会覆盖。set.delete();删除,Iterable可迭代的。array map set 都是属于iterableiterable 可以用 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) { // 遍历Array   alert(x);}for (var x of s) { // 遍历Set   alert(x);}for (var x of m) { // 遍历Map   alert(x[0] + '=' + x[1]);}function函数function abs(x){if(x>0){return x;}else{return -x;}}function 函数的关键字,函数不需要指定返回值类型abs 函数名x 参数,如果有多个参数则要用逗号分开,参数不用指定类型大括号之间的是函数体函数执行到return则返回,不再执行下去。var abs =function(x){if(x>0){return x;}else{return -x;}};函数的第二种定义的方式,将一个匿名的函数赋值给一个变量,两种定义的方式实际上是一致的,不同的是,第二种需要在最后的大括号后面跟上一个分号,表示结束了。函数的调用,调用函数和java差不多,函数名,然后小括号里面跟上参数。当参数个数大于函数接受的参数个数的时候,后面的会直接忽略掉,当传入的参数个数小于函数可接受的参数个数的时候,会自动undefine补齐。argument 参数,它是所传进去函数的参数集。它只在函数中使用,使用起来和数组差不多,但不是一个数组。函数接受的参数个数为3个,但调用的时候传进去2个,那么argument里面就有2个,而不是3个。所以。argument实际上是参数的副本。是实际传递进去的。因为js是不限制参数的传递的个数的,所以argument经常用来判断传进去的参数的个数,来做进一步的。。rest 可变参数,函数可以接受一个个数可变的参数,其实就是一个数组,function abc(x,y,...rest)这个函数除了接受x和y两个参数外,还接收一个rest参数,函数调用的时候和其他一样。当调用的时候只传递两个参数的时候,rest为一个空数组,当调用的时候传递3个参数的时候,那就是长度为1的数组。rest必须是函数中最后一个参数,且必须前面有...函数的作用域js中,函数支持嵌套。也就是函数里面可以有函数。里面函数可以访问外面函数的变量,外面函数就不能访问里面函数的变量。如果函数的名字重复,则使用本函数里面的。全局作用域

当一个变量不是定义在function里面的时候,那么它就是一个全局的变量,作用域就是全局。可以使用windows来调用。

需要注意的是,函数里面的变量一定要 var 声明,不然就会变成一个全局变量。

方法在一个对象中绑定函数,称之为这个对象的方法。例如:var xiaoming={name:'xiaoming',birth:1990,age:function(){var y = new Date().getFullYear();return y-this.birth;}};上面的例子,age是匿名function计算出来的,这有别于其他,这样我们就可以做更多的事情了其中例子中有一个关键字 this this到底是啥?this指向的是调用函数的对象。高阶函数函数接收变量,变量可以指向函数,那么一个可以接收函数作为变量的函数就是高阶函数。function add(x,y,f){return f(x)+f(y);}

这就是一个高阶函数,函数中的第三个参数就是一个函数。例如,add(-5,6,abs),运行的结果是11

map也是一个高阶函数,它对数组array起作用,可以对array里面的每一个元素做相应的动作。

例如 array.map(fun);这里是指,对数组array里面的每个元素都调用一下fun函数,生成一个新的数组,例如array=[1,2,3]; fun = function(x){return x*x} 那么生成的新的数组那就是[1,4,9],对原数组中的每一个元素做平方的操作。

reduce 也是一个高阶函数,也对array起作用,指对array里面的元素做一些动作,使之最后得到一个结果,例如我要对数组[1,2,3] 里面的每一个元素加起来,也就是累加。那么可以使用reduce。例如:var arr = [1, 3, 5, 7, 9]; arr.reduce(function (x, y) {    return x + y;}); // 25

filter 同样是一个对array起作用的一个高阶函数,它可以过滤掉一些元素,保留一些元素形成一个新的数组。是否保留某个元素由传递进去的函数的返回的true或者false决定,那么,传递进去的函数的返回值就必须是一个boolean类型的返回值。例:var arr=[1,2,3,4]; arr.filter(function (x) {    return x % 2 !== 0; }); 得到的新的数组为[1,3]

sort 排序。它可以对数组进行排序,也可以直接调用数组的sort() 方法进行排序,但不同的是,数组直接调用sort的话,排序的方式会出现千差万别,例如一个里面是数字的数组,调用sort排序的话,会将数字先转化成string再排序,也就是,10 会排在 2 的前面,这就尴尬了,还有一点,小写的字母会排在大写字母的后面,例如 apple 会排在Zoo 的后面 因为排序的时候是按照ascll码表来排序的,自然就排在了后面,为了解决掉这些乱七八糟的情况,我们可以直接使用sort的高阶函数来进行排序,例如:var arr = [10, 20, 1, 2]; arr.sort(function (x, y) {if (x < y) { return -1;}    if (x > y) {return 1;}    return 0;}); // [1, 2, 10, 20],这样就可以实现数字的排序,相应的,如果是按照字母来排序的话,可以全部转化成大写或者小写来排序(转化成大写 toUpperCase(),)

高阶函数不仅可以将函数作为一个参数传递进去,还可以将一个函数作为返回值进行返回。

这就是典型的将函数作为返回值的情况。就上面这个例子,如果再次调用一下 var fun1=sun(ssy); 得到一个新的函数fun1 和fun 是两个不同的函数,当你对它们做 === 的操作的时候,返回来的是false, 但对函数 fun fun1 的返回值做 ===  的操作,返回的是 true  fun() === fun1();//true

闭包

在js中,方法里面可以读取全局的变量,而在方法外面是不能访问方法里面定义的变量的,所以,要在外面访问方法里面的变量,这就是函数的闭包。

所以,闭包就是定义在一个函数里面的函数,本质上,闭包就是连接函数里面和外面的一个桥梁

箭头函数

箭头函数相当于匿名函数,只用一个箭头来表示

例如 function(x){return x*x;} 可以写成这样 x => x*x;

也就是说,1,省略了 function 的声明 2,参数也省略了用小括号包裹 3,函数体也省略了用大括号包裹 4,返回也省略了return 关键字。

但不是所有的箭头函数都可以这么省略的,function是可以省略的,其他需要注意的是1,函数体超过一行的时候就要用大括号括起来,并且return也不能省了;2,参数是两个或者两个以上,也要用小括号括起来,没有参数也要用小括号;3,js函数的返回值是可以返回一个对象的,所以,当一个函数返回一个对象的时候。例如 function(x){return {name:x}} 这个函数,返回的是一个对象,这个对象中只有一个属性为name,那么使用箭头函数就不能这样写。x =>{name:x} 而是要把这个对象用小括号包起来,也就是这样 x => ({name:x})

this,箭头函数中的this和普通函数的this是有却别的,普通函数里面的this是在运行的时候决定的,也就是谁调用,this指向的就是谁,而箭头函数是,谁绑定,this就指向谁。

Generator

generator是一个新的数据类型,和方法差不多,不同的是,方法每次只能返回一个,而generator能够返回多次。如果我们要返回多个参数的话,那么就要用到数组,一次性的返回多个参数,而generator不用,可以一次一次的返回,这就是他们最大的区别,一次一次返回和一次返回全部也有千差万别的,一次一次的返回可以做到实时性,而一次返回多个,就要等到函数全部执行完毕才能接收到返回值。generator的声明和函数差不多,只是多了个* 函数的声明是:function 而generator 的声明是function* 。generator也是遇到return的时候就结束函数,中间返回数据则使用yield,当执行到yield的时候,函数就暂停了,等到下一个返回的时候才继续执行。还有一点区别是,函数调用是这样的: fun(s) fun为函数名,s为参数。而generator调用是这样的 var f = fun(s); f.next();调用next的时候才是正式的调用,当执行到yield的时候就暂停了,等到下一次的调用,当函数已经执行完毕了,也就是执行到return的时候,就不要再继续调用next了,其实generator的返回的时候是这样的[value:0,done:false],其实返回的是一个对象,该对象里面有两个属性,一个是要返回的数据value,一个是返回是否已经全部完成done,当返回的done是true的时候,函数就执行完毕了。所以,执行generator的时候有一种类似于java中for each 循环的方式:for...of... 来循环迭代对象,就变成了这样 for(var v of fun(3)){...函数体...},这样我们就可以在函数体里面对v做操作了。

Js标准对象

javascript中,标准的对象有,Number,String,Boolean,undefine,function,Object

number,string,boolean,undefine,function是可以用typeof 来判断的。 object就不行了,因为数组和null都是Object,如果要判断数组可以使用Array.isArray(arr) 来判断,如果判断null可以使用 ===

对象的包装

Number,String,Boolean都有其对应的类,类似于java的装箱拆箱。但装箱后,那么数据类型就不再是基本的标准类型了,而是Object了。所以,装箱后,再去判断是否相等,都是false。123 === new Number(123); //false 因为前面的是数字类型,而后面的是Object类型。

任何对象都有toString的方法,但null和undefine是没有的。

number调用toString是会报SyntaxError,需要如下处理:

Date对象,

new一个Date对象,还可以使用:

var d = new Date(2015, 5, 19, 20, 15, 30, 123);var d = Date.parse('2015-06-24T19:49:22.875+08:00');var d = new Date(1435146562875);

第一种指明了年月日时分秒毫秒,第二种直接由字符串转换而来,第三种传入一个时间戳,也就是毫秒数。

Date还有一个方法,转换成本地时间,toLocalString() 可以转换成当前时区的时间,还可以转换成UTC时间,toUTCString()

获取当前的时间戳,Date.now() 老版本的ie需要用new Date().getTime();


发表评论 共有条评论
用户名: 密码:
验证码: 匿名发表