前端知识一些总结

前言

自从ES6标准发布之后,我还没怎么细看,所以关于js的知识总体还留在几年以前。虽然借着Vue,ElmentUI等前端框架能做出实用的界面来,但新瓶还是装着老酒。如果只有我自己,也足以应付很多事情,但涉及到和前端同事合作,有时他们写的新式语法不甚了解时不免略有尴尬。

借着大前端的红火,以及ES6及后期版本的某些语法接近于C#,熟悉起来相对简单。

let命令

众所周知,js的var是很灵活的,灵活到变量未声明前也可使用。

b="bb"
var b="cc"

输出:“bb”

C# var

在很早以前,C#是不支持var的。后来吸取了javascript的var,但也做了一些优化:

  • 必须在变量声明时赋值。
可以写var a="1234";
不能写出  var a;   a="1234"
  • 必须是局部变量
 //局部变量a可以用a声明,b必须指定类型
  class Program
  {
      string b = "222";

      static void Main(string[] args)
      {
          var a = "111";
      }
  }
  • 变量声明后,类型确定,不能再改变类型

ES6 let

ES6针对var的优化方式就是新增了let和const,用来区分不同的应用场景

  • var可以在未声明变量前使用,let会报错
a="12"
var a="3"

输出:“12”

b="bb"
let b="bb"

输出:Uncaught SyntaxError: Identifier ‘b’ has already been declared
at :1:1

  • let声明的变量只在代码块有效
{
let a1="12"
var b2="3"
}
a1

输出:VM486:5 Uncaught ReferenceError: a1 is not defined
at :5:1

{
let a1="12"
var b2="3"
}
b2

输出:“3”

  • 暂时性死区

只要块级作用域内存在let,它所声明的变量就“绑定"这个区域,不再受外部的影响。

var tmp = 123;

if (true) {
  tmp = 'abc'; // ReferenceError
  let tmp;
}

输出:VM566:4 Uncaught ReferenceError: tmp is not defined
at :4:7
(anonymous) @ VM566:4

ES6 明确规定,如果区块中存在let和const命令,这个区块对这些命令声明的变量,从一开始就形成了封闭作用域。凡是在声明之前就使用这些变量,就会报错。

总之,在代码块内,使用let命令声明变量之前,该变量都是不可用的。这在语法上,称为“暂时性死区”(temporal dead zone,简称 TDZ)。

Module

c#有using,java有import,但以前的javascript却没有相应的模块(module)体系,无法将一个大程序拆分成互相依赖的小文件,再用简单的方法拼装起来。这对开发大型的、复杂的项目形成了巨大障碍。

在 ES6 之前,社区制定了一些模块加载方案,最主要的有 CommonJS 和 AMD 两种。前者用于服务器,后者用于浏览器。ES6 在语言标准的层面上,实现了模块功能,而且实现得相当简单,完全可以取代 CommonJS 和 AMD 规范,成为浏览器和服务器通用的模块解决方案。

ES6 模块的设计思想是尽量的静态化,使得编译时就能确定模块的依赖关系,以及输入和输出的变量。CommonJS 和 AMD 模块,都只能在运行时确定这些东西。比如,CommonJS 模块就是对象,输入时必须查找对象属性。

// CommonJS模块
let { stat, exists, readFile } = require('fs');

// 等同于
let _fs = require('fs');
let stat = _fs.stat;
let exists = _fs.exists;
let readfile = _fs.readfile;

面代码的实质是整体加载fs模块(即加载fs的所有方法),生成一个对象(_fs),然后再从这个对象上面读取 3 个方法。这种加载称为“运行时加载”,因为只有运行时才能得到这个对象,导致完全没办法在编译时做“静态优化”。

ES6 模块不是对象,而是通过export命令显式指定输出的代码,再通过import命令输入。


// ES6模块
import { stat, exists, readFile } from 'fs';

export 命令

模块功能主要由两个命令构成:export和import。export命令用于规定模块的对外接口,import命令用于输入其他模块提供的功能。

一个模块就是一个独立的文件。该文件内部的所有变量,外部无法获取。如果你希望外部能够读取模块内部的某个变量,就必须使用export关键字输出该变量。下面是一个 JS 文件,里面使用export命令输出变量。

// profile.js
export var firstName = 'Michael';
export var lastName = 'Jackson';
export var year = 1958;

上面代码是profile.js文件,保存了用户信息。ES6 将其视为一个模块,里面用export命令对外部输出了三个变量。

export的写法,除了像上面这样,还有另外一种。

// profile.js
var firstName = 'Michael';
var lastName = 'Jackson';
var year = 1958;

export {firstName, lastName, year};

Components组件

对我来说,了解Module如何应用最容易的办法,是翻看VUE或ElementUI的源码。

例如alert组件 element\packages\alert\src\main.Vue

<template>
//省略
  .
  .
  .
</template>

<script type="text/babel">
  const TYPE_CLASSES_MAP = {
    'success': 'el-icon-success',
    'warning': 'el-icon-warning',
    'error': 'el-icon-error'
  };
  export default {
    name: 'ElAlert',

    props: {
      title: {
        type: String,
        default: ''
      },
      type: {
        type: String,
        default: 'info'
      },
      //省略...
    },

    data() {
      return {
        visible: true
      };
    },

    methods: {
      close() {
        //省略。
      }
    },

    computed: {
      typeClass() {
        return `el-alert--${ this.type }`;
      },
      //省略
    }
  };
</script>

从这里我们可以看到几个关键点:

  • export 用于输出
  • props-父组件可以通过props将值传给子组件

总结

官方文档很详细。暂时不想写了。懒惰是罪人

参考

Vue

 
posted @ 2018-11-27 20:05  从此启程  阅读(533)  评论(0编辑  收藏  举报