美文网首页
JavaScript进阶

JavaScript进阶

作者: 夜阑w | 来源:发表于2018-12-20 23:22 被阅读0次

一、ES6基础

1. ECMAScript 6 简介

ECMAScript(ES6) 是JavaScript语言的下一代标准,已经在2015年6月正式发布了;在 JavaScript 的基础上做了重大的更新,提供了更优雅的语法和特性。

ECMAScript 和 JavaScript 的关系

ECMAScript 和 JavaScript 的关系是,前者是后者的规格,后者是前者的一种实现。日常场合,这两个词是可以互换的。那为什么不叫 JavaScript 为换名字了呢?原因如下:

  1. 商标,1996年11月,JavaScript的创造者Netscape公司,决定将JavaScript提交给国际标准化组织ECMA,希望这种语言能够成为国际标准。根据授权协议,只有Netscape公司(Javascript 的创造者)可以合法地使用JavaScript这个名字,且 JavaScript 本身也已经被 Netscape 公司注册为商标。
  2. 想体现这门语言的制定者是 ECMA,不是 Netscape,这样有利于保证这门语言的开放性和中立性。

2. ES6 新特性

let 和 const

ES6提供了两种新的声明变量的方式:let 和 const。其中let 和 const 相比于 var 声明的变量有块作用域,let 和 const 只在于当前的块作用域中有效。而 var 声明的变量是在函数作用域内有效。
没有块级作用域,会出现很多不合理的情况。
1、内层变量可能会覆盖外层变量。例如:

var n = 5;      
function f1() {
  console.log(n); 
  if (true) {
    var n = 10;
  }
}
f1();  //undefined

发生了变量提升,导致内层的n变量覆盖了外层的n变量。 而块级作用域不存在变量提升 ,let所声明的变量一定要在声明后使用,否则就会报错。上述代码如果使用let进行声明,则会报错。

let n = 5;      
function f1() {
  console.log(n); 
  if (true) {
    let n = 10;
  }
}
f1();  //报错

ES6 明确规定,如果区块中存在let和const命令,这个区块对这些命令声明的变量,从一开始就形成了封闭作用域。凡是在声明之前就使用这些变量,就会报错。总之,在代码块内,使用let命令声明变量之前,该变量都是不可用的。这在语法上,称为“暂时性死区”。这样可以减少运行时的错误,防止在变量声明前就使用这个变量,从而导致意料之外的行为。
2、用来计数的循环变量会泄露为全局变量。例如下面的代码如果使用var,最后输出的是10。

var a = [];
for (var i = 0; i < 10; i++) {
  a[i] = function () {
    console.log(i);
  };
}
a[6](); // 10

其中变量i是var命令声明的,在全局范围内都有效,所以全局只有一个变量i。所有数组a的成员里面的i,指向的都是同一个i,导致运行时输出的是最后一轮的i的值,也就是 10。
如果使用let,声明的变量仅在块级作用域内有效,最后输出的是 6。

var a = [];
for (let i = 0; i < 10; i++) {
  a[i] = function () {
    console.log(i);
  };
}
a[6](); // 6

变量i是let声明的,当前的i只在本轮循环有效,所以每一次循环的i其实都是一个新的变量,所以最后输出的是6。JavaScript 引擎内部会记住上一轮循环的值,初始化本轮的变量i时,就在上一轮循环的基础上进行计算。

变量的解构赋值

按照一定的模式,从数组或对象中提取值,对变量进行赋值的操作。

数组的解构

var [a,b,c] = [1,2,3] // 结果 a=1 b=2 c=3
var [a,[b,c]] = [1,[2,3]] // 结果 a=1 b=2 c=3

//解构不成功
var [a] = [];  // a = undefined   
var [a, b] = [1]; //a=1 b=undefined

//不完全解构
var [a] = [1,2]; //a=1

//默认值
var [a=1] = [] //a=1

如果等号的右边不是数组(或者严格地说,不是可遍历的结构),那么将会报错

let [a] = 1;
let [a] = false;
let [a] = NaN;
let [a] = undefined;
let [a] = null;
let [a] = {};

对象的解构

var { b, a } = { a: "aaa", b: "bbb" };
a // "aaa"
b // "bbb"

字符串拓展

模版字符串

模板字符串(template string)是增强版的字符串,用反引号(`)标识。它可以当作普通字符串使用,也可以用来定义多行字符串(类似 pre 标签的作用),或者在字符串中嵌入变量。

// 普通字符串 想要换行需要加上 '\n'
`In JavaScript '\n' is a line-feed.`

// 多行字符串
`In JavaScript this is
 not legal.`

// 字符串中嵌入变量
var name = "ac", time = "today";
`Hello ${name}, how are you ${time}?` // Hello ac, how are you today? 

rest 展开运算符

function example(...values){
    console.log(values)// console: [1,2,3,4]
}

example(1,2,3,4) 


var a = [1,2,3]

var b = [...a,4,5,6] //b = [1,2,3,4,5,6]

箭头函数

ES6 提供了新的方式 => 来定义函数

var func = parm => parm
等同于
var func = function (parm){
    return parm
}

如果函数没有参数或有多个参数,那么:

var func = () => //some code
等同于
var func = function (){
    some code
}

var func = (parm1,parm2) => //some code
等同于
var func = function (parm1,parm2){
    some code
}

如果箭头函数的函数体只包含一行代码,则可以不需要写大括号以及 return 语句返回(如果有返回值)

var sum = (num1,num2) => num1+num2
等同于
var sum = (num1,num2) => {return num1+num2}
等同于
var sum = function(num1,num2){return num1+num2}

箭头函数使得表达更加简洁

[1,2,3].map( item=> 2 * item)
等同于
[1,2,3].map(function(item){
    return item * 2
})

[1,3,2].sort((a,b) => a - b)

二、面向对象基础

什么是面向对象编程

  • 把一组数据结构和处理它们的方法组成对象(Object);
  • 把相同行为的对象归纳为类(Class), 通过类的封装(encapsulation)隐藏内部细节;
  • 通过继承(inheritance)实现类的特化(specializetion)/泛化(generalization),;
  • 通过多态(polymorphism)实现基于对象类型的动态分派。

面向对象的好处?

  1. 接近人的思维,符合人类对现实世界的认知;
  2. 封装特性可以使开发者不必在意内部的具体实现,更方便互相协作;
  3. 继承特性可以减少代码冗余,实现代码复用;
  4. 多态特性令子类相比父类有不同的行为,这是非常接近现实的;

封装

1、字面量模式

var Cat = {
 name : '',
 color : ''
} 

这样的方法的缺点是如果多生成几个实例,写起来就非常麻烦。

2、工厂模式

function Cat(name,color) {
 return {
    name:name,
    color:color  
  }
}

这样写可以解决生成多个实例的问题,比较方便,但是调用之后实例的类型只是一个普通的对象,而不是一个具体的类型。

3、构造函数模式

function Cat(name,color){
   this.name=name;
   this.color=color;
   this.eat = function(){};
}
var cat1 = new Cat("big","yellow");
var cat2 = new Cat("small","black");

这样解决了实例不为一个特定类型的问题,使用instanceof运算符可以验证原型对象与实例对象之间的关系。

console.log(cat1 instanceof Cat); //true

但是这样有一个问题是:每一次生成一个实例,都会产生一个新的内容一模一样的方法,是重复的部分,会多占用内存空间。

4、原型模式

function Cat(){ }
Cat.prototype = {  
   type='animal';
   this.eat = function(){};
}

使用原型模式所有实例的type属性和eat()方法,其实都是同一个内存地址,指向prototype对象,因此就提高了运行效率。但是对任何一个实例的操作会影响到所有的实例。

5、混合模式

function Cat(name,color){
  this.name = name;
  this.color = color;
}
Cat.prototype.type = "animal";
Cat.prototype.eat = function(){};

需要变化的属性使用构造函数定义,不变的属性和方法使用原型来定义。但是这种写法不够美观。

6、类

ES6 提供了更接近传统语言的写法,引入了 Class(类)这个概念,作为对象的模板。通过class关键字,可以定义类。新的class写法可以让对象原型的写法更加清晰、更像面向对象编程的语法。

class Cat(){
  constructor(name,color) {
    this.name = name;
    this.color = color;
  }
  eat() {}
}

继承

Class 可以通过extends关键字实现继承,例如定义了一个ColorPoint类,该类通过extends关键字,继承了Point类的所有属性和方法。

class Point {
  constructor(x, y) {
    this.x = x;
    this.y = y;
  }
  toString() {
    return '(' + this.x + ', ' + this.y + ')';
  }
}
class ColorPoint extends Point {
}

super关键字表示父类的构造函数,用来新建父类的this对象。子类必须在constructor方法中调用super方法,否则新建实例时会报错。这是因为子类自己的this对象,必须先通过父类的构造函数完成塑造,得到与父类同样的实例属性和方法,然后再对其进行加工,加上子类自己的实例属性和方法。如果不调用super方法,子类就得不到this对象。

class ColorPoint extends Point {
  constructor(x, y, color) {
    super(x, y); // 调用父类的constructor(x, y)
    this.color = color;
  }
  toString() {
    return this.color + ' ' + super.toString(); // 调用父类的toString()
  }
}

相关文章

  • JavaScript学习笔记(五)

    慕课网JavaScript进阶篇第9章学习笔记 JavaScript进阶篇—第9章 JavaScript学习笔记(...

  • 技术书刊

    Javascript# ########《JavaScript设计模式》《高性能网站建设指南》《高性能网站建设进阶...

  • 进阶篇:浏览器渲染 & 白屏和FOUC(1)

    饥人谷学习进阶第 1 天 JavaScript 网页 = Html + CSS + JavaScript Html...

  • 0. JavaScript学习资料汇总

    JavaScript教程 - 廖雪峰的官方网站 JavaScript入门篇 - 慕课网 JavaScript进阶篇...

  • 前端心得

    1.基础阶段:HTML+CSS 2.js阶段:JavaScript基础、JavaScript进阶、JavaScri...

  • #30天专注橙长计划#向前端工程师进发#day0#航线设计

    发现问题,路线大修。 学习方面:暂定按HTML入门→CSS入门→HTML进阶→CSS进阶→JavaScript入门...

  • JavaScript ☞ day3

    JavaScript基础学习笔记之JavaScript进阶 焦点事件 鼠标事件-单击与双击 鼠标事件-mouseo...

  • 技术栈

    一、HTML、CSS基础、JavaScript语法基础。 二、JavaScript语法进阶。包括:作用域和闭包、t...

  • 2020前端技术栈

    一、HTML、CSS基础、JavaScript语法基础。二、JavaScript语法进阶。包括:作用域和闭包、th...

  • javascript进阶

    1. 数组及操作方法 数组就是一组数据的集合,javascript中,数组里面的数据可以是不同类型的。 定义数组的...

网友评论

      本文标题:JavaScript进阶

      本文链接:https://www.haomeiwen.com/subject/uhvskqtx.html