ES6基础知识


一.   作用域

var 可以是全局变量,在任何文件都可以用

//1. 

var a = 12345;   // 全局变量 ,具备全局作用域
b=123; // 这个是作为window的属性在使用,具备全局作用域


//2. 说明
function test(){
  ab = 45  
}
test()

//没有使用var定义的,都会挂在window上,作为属性使用,可以使用window.ab拿到





//3. 函数作用域,局部作用域

function test(){
    var a =3 
    return a+4
}
console.log(test())






//4.块级作用域

function test(){
    var a =3 
    if(a === 3){
        let b = 4   //形成壁垒,没有变量提升,块级作用域,就是有{}的地方就是块级作用域
        console.log('abc')
    }
    else{
        console.log('abcd')
    }
    return a+4
}
console.log(test())
// 使用let和const没有变量提升



//5.闭包
function test(){
    var a= 3
function test2(){
return a
}
return test2  
}

动态作用域

//动态作用域
window.a=3
function test () {
  console.log(this.a)
}
test()

test.bind({a:100})()
//会输出1和100,this是动态指向的,不是固定指向window的
//bind是函数动态绑定到对象去,这时候this指向这个对象本身,才会导致同一个函数导致输出不同的结果

 

let和const的使用

  1. let具有块级作用域
  2. let声明的变量的提升,不能使用全局属性来访问
  3. let不可以重复定义
  4. let不会进行变量提升

const定义常量

基本和let一样

不可以先声明再赋值

{
    let  a = 1
    console.log(a)
}
//console.log(a)//这个是访问不到的,a是块级作用域里面的,因为使用了let


var b = 3
let c = 4
console.log(b,c)
console.log(window.b,window.c)//b可以输出。c是undefined

.   Array 

2.1   ES5中数组有多少种遍历的方法?

// for循环
const arr = [1,2,3,4,5]
for(let i = 0;i){
    if(arr[i]===2){
        continue
    }
//    console.log( arr[i])
}


// forEach,不支持break,和continue
arr.forEach(function(item){
    // console.log(item)
})


//every
arr.every(function(item){
   
    if(item===2){
        return false//遇到2跳过,或者为空
    }
    // console.log(item)
    return true  //没有return的话只输出1
})



//for in 是为object设计的。也可以遍历数组,但是有小问题
//数组也是对象
//arr.a=8;//如果加入这个,那边索引是a。出现了索引字符串
//重点。for  in 支持continue和break的,但是索引是字符串,注意类型问题
for(let index in arr){
    console.log(index,arr[index])//索引和值
}

2.2  ES5种数组有多少种遍历的方法?

// for循环
const arr = [1,2,3,4,5]
for(let i = 0;i){
    if(arr[i]===2){
        continue
    }
//    console.log( arr[i])
}


// forEach,不支持break,和continue
arr.forEach(function(item){
    // console.log(item)
})


//every
arr.every(function(item){
   
    if(item===2){
        return false//遇到2跳过,或者为空
    }
    // console.log(item)
    return true  //没有return的话只输出1
})



//for in 是为object设计的。也可以遍历数组,但是有小问题
//数组也是对象
//arr.a=8;//如果加入这个,那边索引是a。出现了索引字符串
//重点。for  in 支持continue和break的,但是索引是字符串,注意类型问题
for(let index in arr){
    //console.log(index,arr[index])//索引和值
}
2.3 ES5种将伪数组转换成数组该怎么办? ES6中如何做?
//判断一个对象是不是可遍历的,不可以是不是数组,object的。要反过来想,很多数组对象都是不一样的。除了object和数组还有其他的吗?
//for of 功能更强大,可以自定义
for(let item of arr){
    // console.log(item)
}

const Price = {
    A:[1.5,2.3,4.5],
    B:[3,4,5],
    C:[0.5,0.8,1.2]
}



//ES5种将伪数组转换成数组该怎么办?
//ES6中如何做?

//转换,这个是es5用法
// let args = [].slice.call(arguments)
// let imgs = [].slice.call(document.querySelectorAll('img'))
// console.log(args)

// Array.prototype.from,es6用法
//let args = Array.from(arguments)
//let imgs = Array.from(document.querySelectorAll('img')) 
//imgs.forEach()//再用


//Array.from(arrayLink,mapFn,thisArg)
//let array = Array(5)

// 例子
// let array = Array(5)
// for(let i = 0, len = array.length; i
//     array[i] = 1
// }
// console.log(array)
let array = Array.from({length:5},function(){return 1})
console.log(array)

2.4 Array.of-fill (如何生成新数组?)

ES5中创建一个新数组该怎么做?

ES6中如何做?

// 生成新数组
// ES5
// let array = Array(5)
// let array = ['','']

// ES6
// Array.prototype.of
// let array =Array.of(1,2,3,4,5)
// console.log(array)

// Array.prototype.fill
// let array =Array(5).fill(1)
// console.log(array)
// Array.fill(value,start.end)可以用在替换

 2.5  Find&FindIndex(如果查找数组)

 ES5中如何查找一个元素呢?

ES6中如何做?

// 查找新元素,查找为了验证或者筛选
// ES5
//filter缺点是性能不太好,返回所有值
// let array = [1,2,3,4,5]
// let find = array.filter(function(item){
//     return item===3;
// })
// console.log(find)

//ES6
//Array.prototype.find
//返回数字,返回第一个值
let array = [1,2,3,4,5]
let find = array.find(function(item){
    return item % 2===3;
})
console.log(find)

//Array.prototype.findIndex,返回索引

总结:遍历,转换,生成,查找

三. Class

3. 1 

ES5中怎么声明一个类的?

ES6是如何做的呢?

//ES5
let Animal = function(type){
    this.type = type
    // this.eat = function () {
    //     console.log('eat food')
    // }  挂在原型链上,要不然每个实例都有这个方法
}


Animal.prototype.eat=function(){
    console.log('eat food')
}


let dog = new Animal('dog')
let monkey = new Animal('monkey')
console.log(dog)
console.log(monkey)

// monkey.eat=function(){
//     console.log('error')
// }  只对自己有效果

monkey.constructor.prototype.eat = function (){
    console.log('error')
}
//都有一个eat方法
dog.eat()
monkey.eat()





// ES6
class Animal6 {
    constructor(type){
        this.type=type
    }
    eat(){
        console.log('eat food 6')
    }
}
let dog6 = new Animal6('dog')
let monkey6 = new Animal6('monkey')
console.log(dog6)
console.log(monkey6)



// console.log(typeof Animal6)  判断类型

3.2 Setter&Getter(如何读写属性?)

//ES6 属性的保护和只读
let _age = 4
class Animal {
    constructor(type){
        this.type=type
    }
    get age(){
        return _age
    }
    set age(val){
        if(val <7 && val >4)//不满足条件拦截
        _age = val
    }
    eat(){
        console.log('eat food 6')
    }
}
let dog = new Animal('dog')
console.log(dog.age)
dog.age = 8;//5的话就满足条件
console.log(dog.age)
 3.3 Static Methods (如何操作方法?)  ES5中怎么操作一个方法? ES6是如何做的呢? 开发中什么时候类的实例对象(依赖于实例对象的属性),什么时候用类静态(拿不到当前的实例对象)  
//如何操作方法
// 静态方法,属于类,不属于方法
// ES5
let Animal = function (type){
    this.type = type
    // this.eat = function(){}
}
Animal.prototype.eat=function(){
    Animal.walk()
    console.log('i am eat food')
}
// 静态方法
Animal.walk = function(){
    console.log('I am walking')
}
let dog = new Animal('dog')
dog.eat()
// dog.walk()   错误


//ES6
class Animal {
    constructor(type){
        this.type=type
    }
    eat(){
        Animal.walk()
        console.log('eat food 6')
    }
    static walk(){
        console.log('I am walking')
    }
}
let dog = new Animal('dog')
dog.eat()

3.4 Sub Classes(如何继承一个类)

 ES5中怎么继承另一个类? ES6是如何做的呢?
//继承
// ES5 
let Animal = function (type){
    this.type = type
}
Animal.prototype.eat=function(){
    Animal.walk()
    console.log('i am eat food')
}
Animal.walk = function(){
    console.log('I am walking')
}

//继承
let Dog = function () {
    //初始化父类的构造函数,指针指向dog类
    Animal.call(this,'dog')
    this.run = function(){
        
    }
}
//引用类型
Dog.prototype = Animal.prototype

let dog = new Dog('dog')
dog.eat()






// ES6
let Animal = function (type){
    this.type = type
}
Animal.prototype.eat=function(){
    Animal.walk()
    console.log('i am eat food')
}
Animal.walk = function(){
    console.log('I am walking')
}

//继承
class Dog extends Animal {
    constructor (type){
        super(type)
        this.age = 2
    }
}

let dog = new Dog('dog')
dog.eat()

总结:声明,属性,方法,继承

        四. Function Updates 4.1  ES5中怎么处理函数参数的默认值? ES6是如何做的呢?  
//ES5
//处理参数问题
function f(x,y,z){
    if(y===undefined){
        y=7
    }
    if(z===undefined){
        z=42
    }
    return x+y+z
}
console.log(f(1,8,43))



//ES6
function f(x,y=7,z=42){
    console.log(arguments.length)//arguments就是看函数的参数情况,可以看看Array.from(arguments)es5语法
    console.log(f.length)//达不到效果
    return x+y+z
}
console.log(f(1))
console.log(f(1,undefined,43))//不想传就填undefined

4.2 ES5中怎么处理不确定参数的问题?

ES6是如何做的呢?

// 求和函数
//ES5
function sum(){
    let num=0
    // Array.prototype.forEach.call(arguments,function(item){
    //     num +=item*1
    // })
    Array.from(arguments).forEach(function(item){
        num +=item*1
    })
    return num
}
console.log(sum(1,2,3,4,5))

//ES6
function sum(...nums){
    //Rest paramenter
    let num = 0;
    nums.forEach(function(item){
        num +=item*1
    })
    return num
}

 4.3 Spread Operator(rest参数的逆运算)

//es5
function sum(x=1,y=2,z=3){
    return x+y+z
}
let data=[4,5,7]
console.log(sum.apply(this,data))
//ES6
console.log(...data)