JavaScript小结
JavaScript小结
最近时间有余,小结一下当前我所学到的,所用到的,所理解的JavaScript,如有错误,请留言指正,万分感激!
一、什么是JavaScript?
首先JavaScript就是我们常说的js,可以大致分为两类,一类是遵循ECMA 262标准的js基础语法,另一类则是遵守W3C标准的操作DOM和BOM的API。
js是一种弱类型的,广泛应用于客户端的脚本语言,与java这种编译型语言不同,js是解释型语言,这一点和python一样,在代码执行前不会预先编译成字节码文件,而是通过解释器(浏览器内置的js引擎)边解释边执行,但是在浏览器执行一段 script 之前,会将在函数作用域内的所有变量声明都提升到顶部,并且值为undefined(函数声明除外,整个函数体将都提升到顶部)。
二、遵循ECMA 262 标准的JavaScript
1. 数据类型
4种基本数据类型: number,string,undefined,boolean,以及复杂的object类型和function类型,如下:
typeof(1) // number typeof('') // string typeof(undefined) //undefined typeof(true) // boolean typeof(null) // object typeof({}) // object typeof([]) // object typeof(console.log) //function
2.数据类型转换
js中数据类型转换分为强制类型转换和隐式类型转换(弱类型语言)。
1).强制转换:
利用js提供的 parseInt(),parseFloat(),Number(),String(),Boolean()函数进行数据类型转换。前两者分别是对整形和浮点型进行转换,对数据从前往后,将数字进行转换,如果第一位就不是数字,返回NaN(number 类型的一种)。
parseInt("123");//123 parseInt("+123");//123 parseInt("-123");//123 parseInt("12.3元")//12 parseInt("abc");//NaN parseInt([1,2])//1 parseInt([1,2,4])//1 parseInt(" ");//NaN
该方法还可以将其他进制类型数据转换成整形,取决去parseInt()的第二个参数,如:
parseInt("AA",16);//170 parseInt("10",2);//2 parseInt("10",8);//8
Number()就是将数据转换成number类型,非number的返回NaN,Boolean()将空,0,undefined,'' ,"" 转换成false,其它则为true,String()将数据转换成字符串。
Number("11.2元") // 11.2 Number("") // 0 Number("开发") //NaN Boolean(0) //false Boolean(undefined) //false Boolean('') //false String (false) // "false" String(Null) //" Null"
2).隐式类型转换:
JS中隐式类型转换指数据类型和字符串之间的转换,数字类型与字符串类型进行四则运算时,会进行隐式类型转换,“+”时,会默认将数字类型进行String(),变成字符串,“-”,“%”,“/”,“*”时,会对字符串进行Number()操作,变成数字类型,如下:
11 + "11" // "1111" 11 - "11" // 0 11 * "0" // 0 11 % "11" // 1 11 / "11" // 1
3. "==" 和 "===" 的区别
"==" 判断,如果类型相同,则进行 "===" 判断,如果不同,则会进行一次类型准换,转换成相同类型再比较。
"==="判断,如果类型不同,直接false。
一般情况下,js中都用"===",只有如下图做判断时,可以用"==":
var a if( a == null ) { // 这里a表示可以是null 或者是 undefined // a === null || a === undefined }
4. 数组
创建数组的三种方式:
let arr1 = [1,2,3] //方式一 let arr2 = new Array(1,2,3) // 方式二 let arr3 = new Array(3) // 方式三 arr3[0] = 1 arr3[1] = 2 arr3[2] = 3 console.log(arr1,arr2,arr3)
遍历数组,for,while,do...while,for in,forEach 等,除forEach外,其他方式可以通过 break,continue,return(必须在函数中使用,否则报无法捕获异常: Illegal return statement):
var arr = [1,3,7,6,4,5] for (let i = 0,len = arr.length; i < len; i++) { console.log(arr[i]) // 1 3 7 6 4 5 } for (let i = arr.length - 1; i >= 0; i--) { console.log(arr[i]) // 5 4 6 3 4 1 } for(let index in arr){ console.log(index,arr[index]) // 1 3 7 6 4 5 } arr.forEach(item =>{ console.log(item) // 1 3 7 6 4 5 })
数组中常用的方法:
arr = [1,5,7,4,6] // map :遍历数组,将数组中每一元素作为参数提供给函数调用,结果作为一个新的数组返回 let mapArr = arr.map(item => item*2) console.log(mapArr) // forEach: 遍历数组,将数组中的每一个元素执行以提供的函数,没有返回值,直接改变原数组,注意和map的区别 arr.forEach(item => item*2) console.log(arr) // filter: 过滤数组中的元素,将符合条件的结果,形成一个新的数组并返回。 let filterArr = arr.filter(item => item > 5) console.log(filterArr) // sort: 排序 let sortArr = arr.sort((a,b) => a-b) console.log(sortArr) // find: 查找符合条件的第一个元素,并返回 let findEle = arr.find(item => item > 4) console.log(findEle) // some:判断数组元素至少有一个符合条件,返回true let someArr = arr.some(item => item > 6) console.log(someArr) // true //every: 判断数组中的元素是否全部符合条件 let everyArr = arr.every(item => item > 2) console.log(everyArr) //false // concat:合并数组 arr1 = [1] arr.concat(arr1) // [1,5,7,4,6,1] // push :数组末尾添加元素 // pop(): 删除数组最后一位元素 // shift:删除第一个元素 // unshift: 像数组首部添加一个或多个元素 // isArray():判断对象是否是数组 // toString: 转换成字符串 // join():转换成字符串(可设置元素之间的间隔) // splice(开始的位置,删除的个数,元素):数组切割 let arr = [1, 2, 3, 4, 5]; let arr1 = arr.splice(2, 0 'haha') let arr2 = arr.splice(2, 3) let arr1 = arr.splice(2, 1 'haha') console.log(arr1) //[1, 2, 'haha', 3, 4, 5]新增一个元素 console.log(arr2) //[1, 2] 删除三个元素 console.log(arr3) //[1, 2, 'haha', 4, 5] 替换一个元素
5.对象
对象的创建方式:
// 创建对象 var obj1 = {} function Fn(){ this.name = '小明' } var obj2 = new Fn(); var obj3= Object.create({}); console.log(obj1,obj2,obj3)
遍历对象有两种方式:for / in ,Object.keys()
for (let i in obj){ // 同时会把原型链上可枚举的属性遍历 console.log(i) console.log(obj[i]) } console.log(Object.keys(obj))// 输出对象属性名
6.原型链
我们在创建一个对象的时候,js便给这个对象创建了一个原型对象,可以通过 对象名.__proto__ 方式访问该对象的原型对象,我们称这个为对象的隐式原型对象。
js中所有的函数都可以作为构造函数,所有的函数都有一个 ‘prototype’属性,我们称之为显式原型对象。
一个对象的隐式原型对象 与构建这个对象的函数的原型对象相等。
我们在查找对象的属性时候,如果对象的原生属性不包含,会继续在该对象的原型链上去查找。
function Fn ( name ){ this.name = name } var o1 = new Fn('zhuangsan') o1.__proto__ === Fn.prototype //true
Fn.prototype.html = 'html'
console.log(o1.html) // 'html'
var o2 = new Object() o2.__proto__ === Object.prototype // true
Object.prototype.constructor === Object // true
通过原型链,我们可以在对象原型链上封装一些方法来操作DOM
7.闭包
当前作用域没有声明的变量,做为自由变量,会向声明它的作用域查找;当行成闭包时,函数即使执行结束,也不会立即销毁。
闭包的两种使用场景: 1)函数作为返回值 2)函数作为参数被引用
// 1.案例 当两次输入同一值时返回false
function fn (){ let _list = [] return function (n) { if(_list.indexOf(n) < 0){ _list.push(n) return true; }else{ return false; } } }
var f = fn()
f(5) // true
f(5) // false
在上面代码中,_list声明在fn函数中,但在它的返回函数中调用了该变量,在执行 f 时,f 中未定义_list,会向定义它的父级作用域查找,并且因为形成闭包,执行结束后,函数栈不会被销毁。
三、遵循W3C标准的 web-api
1)操作DOM
1 // 获取DOM 节点 2 var id = document.getElementById('ID') 3 var classs = document.getElementsByClassName('className') 4 var tags = document.getElementsByTagName('TagName') 5 var selectors = document.querySelectorAll('p') // 获取页面所有 p 标签 6 // 创建 DOM 节点 7 var dom = document.createElement('NodeName') 8 doc.appendChild(dom) 9 doc.append(dom) 10 11 // 改变DOM属性 12 document.getElementBy('id').attr = ... 13 14 // js 事件 addEventListener(type,function,boolean) 15 // mouseover 鼠标移上 16 // mouseout 鼠标移出 17 // click 点击 18 // mousedown 鼠标点下 19 // mouseup 鼠标弹起
2) 操作BOM
1 // Navigator 2 navigator.UserAgent // 浏览器信息 3 4 //loaction 5 loaction.href // http://www.baidu.com 6 loaction.host // 域名 : www.baidu.com 7 loaction.port // 端口 (http 默认 80,https默认 443) 8 loaction.search // ?后的内容 9 loaction.hash // #后的内容 10 loaction.pathname 11 12 // location 13 location.forward() // 前进 14 location.back()// 后退