ES6新特性:Proxy 对象,类 Class,let, conts 数据类型
9 Proxy 对象
用于定义基本操作的自定义行为(如属性查找、赋值、枚举、函数调用等)。
https://developer.mozilla.org/zh-CN/docs/Web/JavaScript/Reference/Global_Objects/Proxy
let view = new Proxy({ selected: null }, { set: function (obj, prop, newval) { let oldval = obj[prop]; console.log(obj); console.log(prop); console.log(newval); console.log(oldval); if (prop === 'selected') { if (oldval) { oldval.setAttribute('aria-selected', 'false'); } if (newval) { newval[0].setAttribute('aria-selected', 'true'); } } // 默认行为是存储被传入 setter 函数的属性值 obj[prop] = newval; // 表示操作成功 return true; } }); let i1 = view.selected = document.getElementById('item-1'); console.log(i1.getAttribute('aria-selected')); // 'true' let i2 = view.selected = document.getElementById('item-2'); console.log(i1.getAttribute('aria-selected')); // 'false' console.log(i2.getAttribute('aria-selected')); // 'true'
10. 类 Class
class Rectangle { height = 0; width= 0; constructor() { console.log("constructor2"); this.height = 100; this.width = 100; } }
10.1 constructor 构造函数
constructor方法是一个特殊的方法,这种方法用于创建和初始化一个由class创建的对象。
一个类只能拥有一个名为 “constructor”的特殊方法。
如果类包含多个constructor的方法(参数数量无关,名称一样就是多个),则将抛出 一个SyntaxError 。
10.2 注意事项
函数声明和类声明之间的一个重要区别是函数声明会提升,类声明不会。你首先需要声明你的类,然后访问它,否则像下面的代
码会抛出一个ReferenceError:
let p = new Rectangle(); // ReferenceError class Rectangle {}
10.3 extends
class Rectangle { height = 0; width = 0; constructor() { console.log("constructor1"); this.height = 100; this.width = 100; } } let data = new Rectangle(); console.log(data.height); console.log(data.width); console.log(); console.log(); console.log(); class Rectangle2 extends Rectangle { constructor() { console.log("constructor2"); super(); super.height = -1; super.width = -1; } } let data2 = new Rectangle2(); console.log(data2.height); console.log(data2.width); console.log(); console.log(); console.log();
11. let, conts 数据类型
11.1 let:
那到底let和var有什么不同呢?
let声明的变量拥有块级作用域。也就是说用let声明的变量的作用域只是外层块,而不是整个外层函数。
let声明仍然保留了提升的特性,但不会盲目提升。在runTowerExperiment这个示例中,通过将var替换为let可以快速修复问题
,如果你处处使用let进行声明,就不会遇到类似的bug。
let声明的全局变量不是全局对象的属性。这就意味着,你不可 以通过window.变量名的方式访问这些变量。它们只存在于一个不
可见的块的作用域中,这个块理论上是Web页面中运行的所有JS代码的外层块。
形如for (let x...)的循环在每次迭代时都为x创建新的绑定。
这是一个非常微妙的区别,拿我们的会说话的猫的例子来说,如果一个for (let...)循环执行多次并且循环保持了一个闭包,那
么每个闭包将捕捉一个循环变量的不同值作为副本,而不是所有闭包都捕捉循环变量的同一个值。
所以在会说话的猫示例中,也可以通过将var替换为let修复bug。
这种情况适用于现有的三种循环方式:for-of、for-in、以及传统的用分号分隔的类C循环。
let声明的变量直到控制流到达该变量被定义的代码行时才会被装载,所以在到达之前使用该变量会触发错误。举个例子:
function update() { console.log("当前时间:", t); // 引用错误(ReferenceError) ... let t = readTachymeter(); }
11.2 conts :
ES6引入的第三个声明类关键词与let类似:const。
const声明的变量与let声明的变量类似,它们的不同之处在于,const声明的变量只可以在声明时赋值,不可随意修改,否则会导
致SyntaxError(语法错误)。
const MAX_CAT_SIZE_KG = 3000; // 正确 MAX_CAT_SIZE_KG = 5000; // 语法错误(SyntaxError) MAX_CAT_SIZE_KG++; // 虽然换了一种方式,但仍然会导致语法错误