es6基础-javascript的6种声明方式

ECMAScript6

  • es6的声明6种方式
    1. es5中只有两中声明变量的方式,var命令和function命令
    2. es6除了添加let和const命令,还添加了两种声明变量的方法:import命令和class命令

var 命令

   var a; // undefined
   var b = 1
  1. var定义的变量可以修改,如果不初始化会输出undefined
  2. var声明的变量在window上,使用let和const声明的变量,不会被放在window上
  3. 很多语言中有块级作用域,但js没有, 使用var声明的变量使用function来划分作用域为全局作用域和局部作用域,使用{}不能确定var的作用域,因此var声明的变量具有变量提升的效果
  4. var声明的变量的作用域是全局的或者是函数级的(局部作用域)

function命令

function  add(a, b) {
   return a + b
}
  1. 声明了一个add的新变量,并为其分配一个函数定义
  2. {}直接的内容被分配了add
  3. 函数内部的代码是以字符串存放在堆中的,不会被执行,为备将来调用的时候使用

const 命令

  const a  //报错,必须进行初始化
  const b = 1
  1. const定义的变量不可修改,而且必须初始化
  2. 该变量是一个全局变量,或者模块内的全局变量
  3. 如果一个变量只有在声明时才被赋值一次,永远不会在其他的代码中被重新赋值,那么应该使用const
  4. 创建一个只读常量,在不同的浏览器中表现为不可修改,拥有块级作用域
  5. const的值是一个常量索引,也就是说,变量的名字在内存中的指针不可以改变,但是指针指向的变量的值是可以改变的
  6. const定义的变量不可修改,一般在require一个模块时候用或定义一些全局变量
  7. 可以在全局作用域或者函数内声明常量,但必须初始化常量
  8. 常量不能和它所在的作用域中其他变量或者函数重名

let 命令

   let a // undefined
   let b = 1
   function add (a, b) {
      return a + b
   }
   let c = add(1, 2)
  1. 需要javascript的严格模式
  2. 不存在变量的提升
  3. 不允许重复声明
  4. let声明的变量作用域在块级域中,函数内部使用let定义后,对函数外部无影响(块级作用域)
  5. 可以在声明时为变量赋值,默认为undefined, 没有变量提升,因此在声明之前无法使用(暂存死区)

exoprt/import 命令

 [方式一]
export function foo() {}
export var name = "anan"
var bar = [1,2,3]
export {bar}


 [方式二]
 function foo(){}
 var name = "anan"
 var var = [1, 2, 3]
 exoprt {foo, name, bar}


 [方式三]
  function foo() {}
  exoprt {foo as foo1} // 导出时时命名

 [方式四]
 function foo() {}
 exoprt default  foo

 [导入]
 import {foo} form "xxx"
 import fooFn from 'xxx' // 随意命名

 export default function foo() {}
 export function bar() {}
 export function baz() {}
 import fooFn { bar, baz  } from "module";

  1. es6中的模块就是一个js文件
  2. 主要有两种模块化方式:CMD和AMD
  3. import有变量提升的过程和var变量一样

class命令

  • es6之前js没有类的概念,但可以通过构造函数来时类的功能

     function Person(name, age) {
        this.name = name
        this.age = age
        this.sayHello = function () {
           console.log("name:" + this.name)
        }
     }
     function Worker(job) {
        this.job = job
        this.sayJob = function () {
           console.log(this.job)
        }
     }
     Worker.prototype = new Person("anan", 20) // 利用原型链继承实现worker对Person方法和属性的继承
     var teacher = new Worker("ananTea")
    
    • 分析:
      1. 创建一个构造函数perosn,我么么可以认为是“类”, 其中两个属性是name和age,和一个类的方法sayHello
      2. 采用new实例化Person, 返回一个person对象
      3. Person的构造函数中有一个prototype方法,指向该构造函数的原型对象Person.prototype,该原型对象包含了两个默认的方法(constrcutor和__proto__), Person.prototype.constructor指向当前的构造函数,Person.prototype.__proto__指向创建Person.prototype对象的构造函数的原型对象
      4. 利用原型链的方式实现继承
  • es6中提供了class关键字,提供了对类的支持

 class Person {
    constructor (name, age) {
       this.name = name
       this.age = age
    }
    sayHello() {
       console.log(this.name)
    }
 }
 var person = new Person("anan", 20)
 person.sayName() // anan
  • 分析

    • class关键字定义了Person类,constructor为该类的构造方法 sayHello为类方法,在使用new创建一个实例对象perosn时,会自动调用constructor构造方法,传入参数,返回实例对象,this指向的就是该实例对象

    • 使用class定义的类的实例化相当于给Person.prototype添加属性和方法,实际上定义子类的所有方法都是定义在prototype属性上的

    • 严格模式,在类和模块的内部默认的就是严格模式

      • constructor方法是类的默认方法, 通过new关键字声明对象时,自动调用该方法,一个类必须有constructor方法,如果不定义构造函数,则默认又一个构造函数
      class Person {
      
      }
      class Person {
         constructor () {
      
         }
      }
      
      • constructor方法默认返回实例对象(this),完全可以指定返回的另一个对象
      class Person {
         constructor () {
            return Object.create(null)
         }
      }
      new Person() instanceof Person // false
      
      • 类的实例对象:生成的实例对象的写法,与ES一样使用new命令,实例的属性除非显示定义在其本身,即this对象上,否则就是定义在原型上
       class Person {
          constructor (name, age) {
             this.name = name
             this.age = age
          }
          sayHello () {
             return this.name
          }
       }
      
       var person = new Person("anan", 20)
       console.log(person.sayHello()) // anan
       person.hasOwnProperty("name") // true
       person.hasOwnProperty("age") // true
       person.hasOwnProperty("sayHello") // false
       person.__proto__.hasOwnProperty("sayHello") // true
      
  • name和age都是person的自身的属性,而sayHello是原型对象的属性

  • class的取值函数(getter)和存值函数(setter)

    • 和es5一样,在类的内部可以使用get和set关键字,对某个属性设置存值函数和取值函数,拦截该属性的存取行为
     class MyClass {
        constructor {
    
        }
        get prop() {
           return 'getter'
        }
        set prop(value) {
           console.log('setter' + value)
        }
     }
    
     let myclass = new MyClass()
     myclass.prop = 123 // setter123
     console.log(myclass.prop) // getter
    
  • class的静态方法

    • 类相当于实例的原型,所以在类中定义的方法,都会被实例继承,如果在一个方法前,加上static关键字,就表示该方法不会被实例继承,而是直接通过类来调用,这就成为‘静态方法’, 静态方法中的this指向的时当前的类,而不是实例
    • 父类的静态方法,可以被子类继承
    class Foo () {
       static classMethod () {
          return 'hello'
       }
    }
    Foo.classMethod() // hello
    var foo = new Foo()
    // foo.classMethod // 报错
    class Bar extends Foo {
    
    }
    Bar.classMethod() // hello
    
  • class的静态属性和实例属性

    • 静态属性指的是class本身的属性,即类名.propName, 而不是定义在实例对象(this)的属性
      • 类的实例属性可以用等式,写入类的定义之中
      class Foo {
         myProp = 40  // 即使没this只要在类的定义之中就是实例属性
         constructor () {
            console.log(this.myProp) // 40
         }
      }
      Foo.prop = 1  // 类的属性
      Foo.prop // 1
posted @ 2019-06-10 15:44  KuiShen  阅读(3363)  评论(0编辑  收藏  举报