ES几个重要版本
- ES5: 09年
- ES6: 15年发布, 也称为ECMA2015
- ES7: 16年发布, 也称为ECMA2016
ES5的几个概念
-
严格模式
ES5有两种运行模式, 一种为正常模式(混杂模式), 另一种运行模式: 严格模式(strict mode), 这种模式使得JavaScript在更严格的语法条件下运行
1.目的: 消除js语法的一些不合理,不严谨之处,减少一些怪异行为,消除代码运行的一些不安全之处, 为代码的安全运行保驾护航, 为未来的新版本做好铺垫
2.使用: 在全局或函数的第一行定义"use strict"
3.作用: 必须使用var声明变量,
禁止自定义函数的this只想window,
创建eval作用域,
对象不能有重名的属性
-
json方法
- JSON.stringify(obj/arr) js对象(数组)转换为json对象(数组)
- JSON.parse(json) json对象(数组)转换为js对象(数组)
var obj = {
name: 'yuyin',
age: 18
}
obj = JSON.stringify(obj)
console.log(typeof obj) //string
obj = JSON.parse(obj)
console.log(typeof obj) //object
-
Object扩展的方法, 常用的2个
1. Object.create(prototype, {descriptors})
作用: 一指定的对象为原型, 创建新的对象, 可以为新的对象添加新的属性, 并对属性进行描述 - value: 指定的值 - writable: 标识当前属性值是否是可修改的, 默认为false - configurable: 标识当前属性是否可以被删除, 默认为false - enumerable: 标识当前属性是否能用for in 枚举, 默认为false
var obj = {
name: 'yuyin',
age: 18
}
var newObj = Object.create(obj, {
sex:{
value: '男',
writable: true,
configurable: true,
enumerable: true
}
})
newObj.sex = '女' //如果要修改属性, 必须配置writable: true
delete newObj.sex //如果要删除属性, 必须配置configurable: true
console.log(newObj) //newObj的原型上有obj的属性方法可以直接调用
for(var i in newObj){
console.log(i) //for in 遍历原型上的属性方法, 配置enumerable: true 可以遍历添加的属性方法
}
2. Object.defineProperties(object, descriptors)
作用: 为指定对象定义扩展多个属性, 使用get拿到的值只能通过set修改
- get: 用来获取当前属性值的回调函数
- set: 修改当前属性值触发的回调函数, 实参就是修改的值
var obj = {
fristName: 'yu',
lastName: 'yin'
}
Object.defineProperties(obj, {
fullName: {
get: function () { //获取扩展属性的值自动调用
console.log('get调用了')
return this.fristName + ' ' + this.lastName
},
set: function (data) { //监听扩展属性值, 如果值改变会自动调用, 参数为修改的值
console.log('set调用了')
console.log(data)
var names = data.split(' ')
this.fristName = names[0]
this.lastName = names[1]
}
}
})
// console.log(obj.fullName)
obj.fullName = 'ha ha'
console.log(obj.fullName)
-
数组方法
Array.prototype.indexOf(value) 值在数组中第一个下标的位置
Array.prototype.lastIndexOf(value) 值在数组中最后一个下标的位置
Array.prototype.forEach((item,index)=>{}) 遍历数组
Array.prototype.map((item,index)=>{}) 遍历数组,返回新数组, 返回加工后的值
Array.prototype.filter((item,index)=>{}) 遍历过滤数组, 返回新数组, 返回条件为true的值注意: map/filter方法都是返回新数组, 在考虑使用哪个方法时可以先考虑返回值
let arr = [1, 'a', 3, 6, 'c']
let newArr = arr.map((ele, index) => ele + 10)
let newArr1 = arr.filter((ele,index) => index > 3)
console.log(newArr,newArr1)
-
函数绑定this指向
call/apply 绑定this后, 函数立即执行, 不传参时使用方式一样, 传参apply必须是数组
var obj = {
name: 'yuyin',
age: 18
}
function foo(a, b) {
console.log(this, a, b)
}
foo.call(obj, 18, 20)
foo.apply(obj, [18, 20])
bind 绑定完this不会立即调用当前函数, 将函数返回, 传参与call一样, 通常在回调函数中使用
foo.bind(obj, 18, 20)()
ES6常用知识
变量声明
-
var
变量声明提升, 可重复定义, 全局变量挂载到window上
-
let
变量声明不会提升, 不可以重复定义, 不会挂载到window上, 加强了对作用域的控制配合{}使用产生块级作用域, 变量只能在{}中使用, 在for循环中使用可以解决闭包问题
console.log(a) //报错
let a = 10;
let a = 20; //报错
a = 20;
console.log(window.a) //报错
if(true){
let a = 10;
console.log(a); //10
}
console.log(a) //报错
//解决闭包
var arr = [];
for(let i = 0; i < 10; i++){
arr[i] = function (){
console.log(i);
}
}
arr[0](); //0
arr[2](); //2
-
const
跟let用法一样, 但它是声明常量的, 声明必须赋值,否则会报错, 并且赋值后不能再改变
可以声明引用值数据类型, 比如对象/数组, 然后可以对对象或数组增删改
const a = 10;
const b; //报错
a = 20; //报错
//声明引用值, 可以对值修改
const obj = {
name: 'yuyin'
};
obj.name = 'aaa';
obj.age = 18
console.log(obj) //{name: "aaa", age: 18}
解构赋值
从对象或数组中提取数据, 并赋值给变量
let obj = {
name: 'yuyin',
age: 18,
abc: 'abc'
}
// var name = obj.name
let {name, age} = obj //只写需要的属性
let arr = [1, 'a', 2, 'b', 3]
let [a, b, c, d, e] = arr
console.log(a, b, c, d, e) //1 "a" 2 "b" 3
let [aa,,,,bb] = arr
console.log(aa,bb) //1 3
// 函数参数使用
function foo(obj){
console.log(obj.name,obj.age)
}
function foo1({name,age}){
console.log(name,age)
}
foo(obj)
foo1(obj)
模板字符串(简化字符串的拼接)
- 定义字符串必须用``包含
- 变化的部分使用${xxx}
let obj = {
name: 'yuyin',
age: 18
}
let { name, age } = obj
// let str = '我的名字叫' + name + ',今年' + age + '岁'
let str = `我的名字叫${name},今年${age}岁`
console.log(str)
对象简写方式
- 对象属性名于属性值的变量一样时可以只写属性名
- 方法可以直接写方法名,省略function
let name = 'yuyin'
let age = 19
let obj = {
name,
age,
// 方法简写
getName(){
console.log(this.name)
}
}
console.log(obj)
箭头函数
多用来定义回调函数
- 箭头函数的几种形式
// 没有形参
let fun = () => console.log('我是箭头函数')
fun()
// 只有一个形参, 可以省略()
let fun1 = a => console.log(a)
fun1(1)
// 两个及更多的参数
let fun2 = (x, y) => console.log(x, y)
fun2(1, 2)
// 函数体只有一条语句或者是表达式的时候{}可以省略,会自动返回语句执行的结果或者是表达式的结果
let fun3 = (x, y) => x + y
console.log(fun3(2, 3))
//加{}, 必须return结果
let fun4 = (x, y) => { return x + y }
console.log(fun4(2, 3))
// 函数体是多条语句,必须使用{}
let fun5 = (x, y) => {
x += 1;
y--;
console.log(x - y)
return x + y
}
fun5(10, 8)
- 箭头函数特点
没有自己的this, 箭头函数的this不是调用的时候决定的, 是在定义的时候处在的对象就是它的this
其实就是看外层是否有函数, 如果有外层函数的this就是内部箭头函数的this, 如果没有this指向window
btn1.onclick = function () {
console.log(this)// btn1
}
btn2.onclick = () => {
console.log(this)// window
}
let obj = {
name: '箭头函数',
getName() {
btn3.onclick = () => {
console.log(this) // obj
}
}
}
obj.getName()
let obj1 = {
name: '箭头函数',
getName: () => {
btn4.onclick = () => {
console.log(this) // window
}
}
}
obj1.getName()
运算符...(简化书写长度, 提升开发效率)
作用: spreed展开, rest收集功能, 可以从读和写两个角度考虑
- 写:(收集,比如函数的参数), 解决参数不固定的问题,相当于arguments(类数组),但它是数组,可以直接使用数组的方法
function sum(...arg) {
console.log(arg); //[1, 2, 3]
let sumNumber = 0;
arg.forEach(function(ele){
sumNumber += ele;
})
return sumNumber;
}
console.log(sum(1, 2, 3));
可以指定前面的参数, ...arg必须作为最后的参数
function test(a, b, ...arg) {
console.log(a, b, arg); //1 2 [3, 4, 5]
}
test(1, 2, 3, 4, 5)
- 读:(展开数组,es7可以展开对象) ,可以用于数组合并
let arr = [1, 2, 'a', 'b'];
console.log(...arr) //1 2 "a" "b"
let arr2 = ['abc'];
let newArr = [...arr, ...arr2];
console.log(newArr); //[1, 2, "a", "b", "abc"]