ES5和ES6那些你必须知道的事儿

ES6新增的东西

一、块级作用域:关键字let,常量const

  let与var的区别:

    a、不会进行变量声明提升

    b、变量不允许被重复定义

    c、变量不允许被删除

    d、在for循环中可以保留i的值

    e、循环的变量只能在当前块级作用域中使用

  const和var的区别:

    a、常用于声明常量时或声明不可被修改的变量的时候

    b、const的值不允许被修改

    c、不会进行变量声明提升

    d、常量不允许被删除    

二、对象字面量属性赋值简写

var name = “我是name”;
var age = 18; var obj = {
name,
age
} //此处的对象的key值与value值是一样的,所以简写 //不简写的话就是 var obj = {
name:name, //即name:“我是name”
age:age //即age:18
}

三、解构赋值

let singer = { first: "Bob", last: "Dylan" };
let { first: f, last: l } = singer; // 相当于 f = "Bob", l = "Dylan"
let [all, year, month, day] = /^(\d\d\d\d)-(\d\d)-(\d\d)$/.exec("2015-10-25");
let [x, y] = [1, 2, 3]; // x = 1, y = 2

四、展开运算符... 

var arr=[1,2,3,4];

console.log(...arr)

//打印出来不是一个数组,
//而是将数组里的内容分开打印
//1 2 3 4

五、箭头函数

//正常函数的写法:

function a(){
//内容
} //如果改成箭头函数 a()=>{
//内容
}
//箭头函数的简写

x => x * x

//上面的代码相当于下面的代码

function (x) {
return x * x;
} //如果参数不是一个,就需要用括号()括起来: // 两个参数:
(x, y) => x * x + y * y // 无参数:
() => 3.14 // 可变参数:
(x, y, ...rest) => {
var i, sum = x + y;
for (i=0; i<rest.length; i++) {
sum += rest[i];
}
return sum;
} //如果要返回一个对象,就要注意,写成下面这样 x => ({ foo: x })

要注意箭头函数的this

普通函数下的this:

  • 在普通函数中的this总是代表它的直接调用者,在默认情况下,this指的是window,
  • 在严格模式下,没有直接调用者的函数中的this是 undefined使用
  • call,apply,bind(ES5新增)绑定的,this指的是 绑定的对象

箭头函数中的this:

  • 箭头函数没有自己的this, 它的this是继承而来; 默认指向在定义它时所处的对象(宿主对象),
  • 而不是执行时的对象, 定义它的时候,可能环境是window,也有可能是其他的。

看下面这段代码:

function a() {
console.log(this); //window
}
a();

因为a是一个全局函数,也就是挂载在window对象下的,所以a(),等价于window.a();

var obj = {
say: function () {
setTimeout(function () {
console.log(this); //window
});
}
}
obj.say();

定时器中的函数,由于没有默认的宿主对象,所以this指向window

var obj = {
func: function() {},
say: function () {
console.log(this);//obj,此时的this是obj对象
setTimeout(function () {
console.log(this); //window
that.func();
});
}
}
obj.say();

此时say的宿主环境是obj,所以say里面的this是obj,定时器中的函数, 由于没有默认的宿主对象,所以默认this指向window

箭头函数中的this:

var obj = {
say: function () {
setTimeout(() => {
console.log(this);// obj
});
}
}
obj.say();

此时的 this继承自obj, 指的是定义它的对象obj, 而不是 window!

 

var obj = {
say: function () {
var f1 = () => {
console.log(this); // obj
setTimeout(() => {
console.log(this); // obj
})
}
f1();
}
}
obj.say()
因为f1定义时所处的函数 中的 this是指的 obj, setTimeout中的箭头函数this继承自f1,所以不管有多层嵌套,都是 obj

var obj = {
say: function () {
var f1 = function () {
console.log(this); // window, f1调用时,没有宿主对象,默认是window
setTimeout(() => {
console.log(this); // window
})
};
f1();
}
}
obj.say()

结果: 都是 window,因为 箭头函数在定义的时候它所处的环境相当于是window, 所以在箭头函数内部的this函数window

换个理解方式:因为箭头函数没有this,当需要判断当前this是什么的时候,把箭头函数去掉,看剩下的代码此处的this指向哪里即可。

        var a=10;
var obj={
a:50,
getA(){
return this.a
},
b:()=>{
return this.a
}
}
console.log(obj.getA())//
console.log(obj.b())//
console.log(obj.getA.call())//

六、字符串模版` `

var name = "Bob", time = "today";
`Hello ${name}, how are you ${time}?`
// return "Hello Bob, how are you today?"

七、迭代器

八、生成器

九、class

Class,有constructor、extends、super,但本质上是语法糖(对语言的功能并没有影响,但是更方便程序员使用)。

class Artist {
constructor(name) {
this.name = name;
} perform() {
return this.name + " performs ";
}
} class Singer extends Artist { constructor(name, song) {
super.constructor(name);
this.song = song;
} perform() {
return super.perform() + "[" + this.song + "]";
}
} let james = new Singer("Etta James", "At last");
james instanceof Artist; // true
james instanceof Singer; // true james.perform(); // "Etta James performs [At last]"

十一、Map() Set()

// Sets
var s = new Set();
s.add("hello").add("goodbye").add("hello");
s.size === 2;
s.has("hello") === true; // Maps
var m = new Map();
m.set("hello", 42);
m.set(s, 34);
m.get(s) == 34;

十二、一些新的API

一些新的API

Number.EPSILON
Number.isInteger(Infinity) // false
Number.isNaN("NaN") // false Math.acosh(3) // 1.762747174039086
Math.hypot(3, 4) //
Math.imul(Math.pow(2, 32) - 1, Math.pow(2, 32) - 2) // "abcde".includes("cd") // true
"abc".repeat(3) // "abcabcabc" Array.from(document.querySelectorAll('*')) // Returns a real Array
Array.of(1, 2, 3) // Similar to new Array(...), but without special one-arg behavior [0, 0, 0].fill(7, 1) // [0,7,7]
[1, 2, 3].find(x => x == 3) //
[1, 2, 3].findIndex(x => x == 2) //
[1, 2, 3, 4, 5].copyWithin(3, 0) // [1, 2, 3, 1, 2]
["a", "b", "c"].entries() // iterator [0, "a"], [1,"b"], [2,"c"]
["a", "b", "c"].keys() // iterator 0, 1, 2
["a", "b", "c"].values() // iterator "a", "b", "c" Object.assign(Point, { origin: new Point(0,0) })

十三、proxy

Proxy 让我们能够以简洁易懂的方式控制外部对对象的访问。其功能非常类似于设计模式中的代理模式。

使用 Proxy 的好处是:对象只需关注于核心逻辑,一些非核心的逻辑(如:读取或设置对象的某些属性前记录日志;设置对象的某些属性值前,需要验证;某些属性的访问控制等)可以让 Proxy 来做。从而达到关注点分离,降级对象复杂度的目的。

var p = new Proxy(target, handler);

其中,target 为被代理对象。handler 是一个对象,其声明了代理 target 的一些操作。p 是代理后的对象。

当外界每次对 p 进行操作时,就会执行 handler 对象上的一些方法。handler 能代理的一些常用的方法如下:

  • get:读取
  • set:修改
  • has:判断对象是否有该属性
  • construct:构造函数
  • ...
var target = {
name: 'obj'
};
var logHandler = {
get: function(target, key) {
console.log(`${key} 被读取`);
return target[key];
},
set: function(target, key, value) {
console.log(`${key} 被设置为 ${value}`);
target[key] = value;
}
}
var targetWithLog = new Proxy(target, logHandler);
targetWithLog.name; // 控制台输出:name 被读取,执行的get
targetWithLog.name = 'others'; // 控制台输出:name 被设置为 others,执行了set
console.log(target.name); // 控制台输出: others
  • targetWithLog 读取属性的值时,实际上执行的是 logHandler.get :在控制台输出信息,并且读取被代理对象 target 的属性。
  • 在 targetWithLog 设置属性值时,实际上执行的是 logHandler.set :在控制台输出信息,并且设置被代理对象 target 的属性的值。
实现私有变量
 
代理中把以 _ 开头的变量都认为是私有的。
var api = {
_secret: 'xxxx',
_otherSec: 'bbb',
ver: 'v0.0.1'
}; api = new Proxy(api, {
get: function(target, key) {
// 以 _ 下划线开头的都认为是 私有的
if (key.startsWith('_')) {
console.log('私有变量不能被访问');
return false;
}
return target[key];
},
set: function(target, key, value) {
if (key.startsWith('_')) {
console.log('私有变量不能被修改');
return false;
}
target[key] = value;
},
has: function(target, key) {
return key.startsWith('_') ? false : (key in target);
}
}); api._secret; // 私有变量不能被访问
console.log(api.ver); // v0.0.1
api._otherSec = 3; // 私有变量不能被修改
console.log('_secret' in api); //false
console.log('ver' in api); //true

使用代理(Proxy)监听对象的操作,然后可以做一些相应事情。

可监听的操作: get、set、has、deleteProperty、apply、construct、getOwnPropertyDescriptor、defineProperty、getPrototypeOf、setPrototypeOf、enumerate、ownKeys、preventExtensions、isExtensible。

十四、Symbol

Symbol是一种基本类型。Symbol 通过调用symbol函数产生,它接收一个可选的名字参数,该函数返回的symbol是唯一的。

var key = Symbol("key");
var key2 = Symbol("key");
key == key2 //false

十五、promise

Promises是处理异步操作的对象,使用了 Promise 对象之后可以用一种链式调用的方式来组织代码,让代码更加直观

function fakeAjax(url) {
return new Promise(function (resolve, reject) {
// setTimeouts are for effect, typically we would handle XHR
if (!url) {
return setTimeout(reject, 1000);
}
return setTimeout(resolve, 1000);
});
} // no url, promise rejected
fakeAjax().then(function () {
console.log('success');
},function () {
console.log('fail');
});

异步操作的同步代码

  

 

ES5和ES6那些你必须知道的事儿(三)的更多相关文章

  1. ES5和ES6那些你必须知道的事儿(二)

    ES5和ES6那些你必须知道的事儿 ES5新增的东西 二.对象方法 1.Object.getPrototypeOf(object) 返回对象的原型 function Pasta(grain, widt ...

  2. ES5和ES6那些你必须知道的事儿(一)

    ES5和ES6那些你必须知道的事儿 ES5新增的东西 一.数组方法 1.forEach     用途:遍历,循环 对于空数组不会执行回调函数 //用法 array.forEach( function( ...

  3. React入门 (1)—使用指南(包括ES5和ES6对比)

    前言 本篇会简明扼要的介绍一下React的使用方法.代码会用JSX+ES5和JSX+ES6两种方式实现. React简介 React来自Facebook,于2013年开源.至今不断修改完善,现在已经到 ...

  4. ES5和ES6中对于继承的实现方法

    在ES5继承的实现非常有趣的,由于没有传统面向对象类的概念,Javascript利用原型链的特性来实现继承,这其中有很多的属性指向和需要注意的地方. 原型链的特点和实现已经在之前的一篇整理说过了,就是 ...

  5. JavaScript面向对象轻松入门之概述(demo by ES5、ES6、TypeScript)

    写在前面的话 这是一个JavaScript面向对象系列的文章,本篇文章主要讲概述,介绍面向对象,后面计划还会有5篇文章,讲抽象.封装.继承.多态,最后再来一个综合. 说实话,写JavaScript面向 ...

  6. JavaScript面向对象轻松入门之封装(demo by ES5、ES6、TypeScript)

    本章默认大家已经看过作者的前一篇文章 <JavaScript面向对象轻松入门之抽象> 为什么要封装? 封装(Encapsulation)就是把对象的内部属性和方法隐藏起来,外部代码访问该对 ...

  7. JavaScript面向对象轻松入门之多态(demo by ES5、ES6、TypeScript)

    多态(Polymorphism)按字面的意思就是"多种状态",同样的行为(方法)在不同对象上有不同的状态. 在OOP中很多地方都要用到多态的特性,比如同样是点击鼠标右键,点击快捷方 ...

  8. JavaScript、ES5和ES6的介绍和区别

    JavaScript由三部分组成: ECMAScript(核心) DOM(文档对象模型) BOM (浏览器对象模型) ES5(ECMAScript第五个版本) strict模式 严格模式,限制一些用法 ...

  9. ES5与ES6的小差异

    ES5与ES6的小差异 变量的定义 ES6与ES5的区别 ES5: <script> console.log(username); var username; var username = ...

随机推荐

  1. 《CSS世界》读书笔记(十六)

    <!-- <CSS世界>张鑫旭著 --> line-height与“垂直居中” line-height 可以让单行或多行元素近似垂直居中,原因在于 CSS 中“行距的上下等分机 ...

  2. JS(JavaScript)的进一步了解3(更新中···)

    数据的三种存储方式 String   “ ” Array    [ ] Json    { } 所有编程语言java c python c++ 等 他们都是面向对象编程,面向对象必须有三大特点,封装, ...

  3. 20175312 2018-2019-2 实验一《Java开发环境的熟悉》实验报告

    20175312 2018-2019-2 实验一<Java开发环境的熟悉>实验报告 实验内容 1.使用JDK编译.运行简单的Java程序: 2.使用Eclipse 编辑.编译.运行.调试J ...

  4. <抽象工厂>比<工厂方法>多了啥

    前言:仅当复习讨论,写得不好,多多指教! 上一篇文章<比多了啥>介绍了简单工厂模式和工厂方法模式.本篇文章则讲最后一个工厂----抽象工厂.如果对工厂方法比较模糊的,可以返回上一篇文章复习 ...

  5. Request method 'PUT'/ 'POST' not supported

    起因 在项目中遇到需要进行crud操作的功能,用的是Springboot+MybatisPlus+MySQL+AVue,在通过postman测试接口正确性时遇到此错误. 排查过程 因为项目运行是没问题 ...

  6. vim编辑器-多行加注释与去注释

    在使用vim编辑器时,有时候需要对多行代码进行加注释或去注释,下面将介绍两种方法. 方法一:块选择模式 1. 插入注释 (1)首先按键盘上的ESC进入命令行模式 (2)再按Ctrl+V进入VISUAL ...

  7. Python 开发 项目《外星人入侵》

    2019-02-05 本篇心路历程: 本篇是打算记录自己的第一个python项目,也是众人皆知的<外星人入侵项目>,本项目大概500多行.趁着寒假,大概耗时3天吧,把完整代码敲了出来,当然 ...

  8. setTimeout异步

    同步任务和异步任务 同步和异步操作的区别就是是否阻碍后续代码的执行. 同步任务是那些没有被引擎挂起.在主线程上排队执行的任务.只有前一个任务执行完毕,才能执行后一个任务. 异步任务是那些被引擎放在一边 ...

  9. .net扩展方法

    http://www.cnblogs.com/landeanfen/p/4632467.html 看了博客才知道定义一个Util工具类并且在工具类里面写静态扩展方法并不是最好的选择.

  10. k个一组翻转链表(java实现)

    题目: 给出一个链表,每 k 个节点一组进行翻转,并返回翻转后的链表. k 是一个正整数,它的值小于或等于链表的长度.如果节点总数不是 k 的整数倍,那么将最后剩余节点保持原有顺序. 示例 : 给定这 ...