系统化学习ECMAScript 2015(拉钩训练营学习笔记)

老生常谈: const let var

闭包是函数作用域为了摆脱 全局作用域带来的影响。
有了ES2015我们可以使用块级作用域来解决全局作用域带来的影响。

for 有两层作用域 这两个分别有自己的作用域。

for (let i = 0; i < 3; i++) {
  // console.log(i);
  let i = 99999
  console.log(i)
}

解析: 
let i = 0;

if (i < 3) {
    console.log(i)
}
i ++ 

const 和 let 的区别 const只声明了只读特性。
const 声明必须赋值。
const 不允许修改它指向的内存地址。但是可以修改他的属性。
最佳实践: 不用var 主用const 配合let.
总结

const 配合let 可以让我们知道我们声明的变量是可读写的。还是只读的。减少不可预测的结果。

数组的解构

当结构提取的成员小于要结构的数据时,会从左到解构出来。
当结构提取的成员大于要结构的数据时,多余的会返回undefind.类似于为定义了没有赋值的变量。

const arr = [ 100, 200, 300 ];

const [a, ...res] = arr;
console.log(a, res)
// 100 [ 200, 300 ]
// 赋默认值。
const [a, , , d=2 ] = arr;
console.log(d)

对象的解构

根据健匹配值。

const obj = {name: 'zce', age: 18};
const name = 'yoom';
// 如果结构出现同名可以起个别名。 也可以添加默认值。
const { name: objName = "123" } = obj;
console.log(objName, name)

模版字符串的高级用法

const res = console.log `打印`
输出 : [ '打印' ];


const name = 'tom';
const gender = 'true'
function myTagFunc (val, name, gender) {
  console.log(val, name, gender) // 输出: [ 'hey, ', ' is a ', '' ] 'tom' 'true'
  // 返回值等于res的值。
  return val[0] + name+ val[1] + gender + val[2]
}
const res = myTagFunc`hey, ${name} is a ${gender}`
console.log(res) //  hey, tom is a true

扩展方法:

const message = `Error: foo is not defind.`

console.log(message.startsWith('')) // 判断字符串一某某开头 返回布尔值 true
console.log(message.endsWith('。')) // 判断字符串一某某结尾 返回布尔值 false
console.log(message.includes('foo')) // 字符串包含某某     返回布尔值 true

默认值参数

带有默认值的参数 需要放在参数最后面。

剩余参数

在es2015之前js接收剩余参数使用arguments接收。

之前:
function foo () {
    console.log(arguments) // [Arguments] { '0': 1, '1': 2, '2': 3, '3': 4 }
}
foo(1,2,3,4);

es2015: 
function foo (first, ...args) {
    console.log(first, args)  // 1 [ 2, 3, 4 ] 
}
foo(1,2,3,4);

彻底弄懂箭头函数

箭头函数表达式的语法比函数表达式更简洁, 它并没有自己的this, arguments super 或new target. 箭头函数表达式更适用于哪些本来需要匿名函数的对方。并且它不能用作构造函数。

高级语法:

// 加括号的函数体返回对象的字面量
params => ({foo: bar}) ;
// 支持剩余参数和默认参数。 参数支持解构。

没有单独的this.

在箭头函数出现之前。每一个新函数根据它是被如何调用的来定义这个函数的this值。

箭头函数不会创建自己的this,它只会从自己的作用域链的上一层继承this.当前作用域当中的this, 任何方式都没有办法改变它的this.

while 阻断主进程谁也执行不了,等我执行完才行。

对象字面量的增强

const bar = '345';
const obj = {
  foo: 123,
  // 定义的变量和名字一致的话可以这样简写
  bar,
  // 函数名一样 的话或者匿名也可以简写。
  method1() {
    console.log(this, 888)
  }
  // 如果这个属性名是个变量的话 可以加方括号写。
  [Math.random()]: 123;
}
console.log(obj);
obj.method1()

Object.assign 扩展方法

Object.assign 是深拷贝吗?????

const source1 = {
  a: 123,
  b: 123
}
const source2 = {
  a: 789,
  d: 789
}
const target = {
  a: 456,
  c: 456
}
// Object.assign() 右边的对象合并到左边,如果两个对象有相同的健,则右边替换左边的值。如果右边有左边没有的话,则新加上这个属性。
const result = Object.assign(target, source1, source2)

console.log(target === result, target) // true

function func (obj) {
 // 用来复制一个新的对像。 
  let newObj = Object.assign({}, obj)
  // 在函数内部进行操作。而不改变外面的值。
  newObj.name = 'func obj';
  console.log(newObj, 2)
}
const obj = {name: 'global obj'};
func(obj);
console.log(obj);

Object.is 判断两个值是否相等 (感觉用处不大)

console.log(
  // +0 === -0
  // NaN === NaN
  // 判断出NaN等于NaN
  Object.is(NaN, NaN),
  // 判断出+0不等于-0
  Object.is(-0, +0)

)

Object.defineProperty 和 Proxy

系统化学习ECMAScript 2015(拉钩训练营学习笔记)_第1张图片
Object.defineProperty 监听不到对象的删除操作。Proxy可以。

const person = {
  name: 'zce',
  age: 20
};
// 第一个参数没目标代理函数。第二个参数是个对象其中又一个监听删除 deleteProperty方法。并且返回一个新的对象。
const personProxy = new Proxy(person, {
 // 一个是代理的对象。一个是传过来的需要删除属性。 删除后原对象属性即被删除。
  deleteProperty(target, property) {
    console.log('delete', property);
    delete target[property];
  }
})
delete personProxy.age;
console.log(personProxy, person, personProxy ===person) // { name: 'zce' } { name: 'zce' } false

Proxy专门为对象做访问代理器的。对象的读写都可以监听到。

const person = {
  name: 'zce',
  age: 20
};
// Proxy 第一个参数是需要代理的对象。 第二个参数是一个对象。这个对象有get set deleteProperty 方法
const personProxy = new Proxy(person, {
// get方法有两个参数。一个是代理的对象。一个是传过来的属性。
// 这个属性可能有也可能没有。
  get (target, property) {
   // 判断如果有这个属性则返回。 没有的话返回默认值。 
    return property in target ? target[property] : '你要的东西我没有';
  },
  // set方法。有三个参数。target 代理的对象。 property:传过来的属性。这个属性可能有也可能没有。没有的话则是新添加的属性。
  有的话则是更新旧属性。 里面可以做你想要的逻辑判断。
  set(target, property, value){
    if (property === 'age' && !Number.isInteger(value)) {
      throw new TypeError(`${value} is not an int`)
    }
    target[property] = value
  }
})
personProxy.age = true;
console.log(personProxy.name);
console.log(personProxy.a);
console.log(personProxy);
在VUE中会重写数组当中的方法。替换数组原型上的方法。从而达到监听的目的。而Proxy可以很好的监听数组的变化。

proxy 监听数组


const list = [];
// 第一个参数是个数组。
通过set监听bush的数据。
const listProxy = new Proxy(list, {
  set (target, property, value) {
    console.log('set', property, value,0);
    target[property] = value;
    return true;
  }
})
listProxy.push(100)
listProxy.push(10)
set 0 100 0 // 输出 输出两边不知道为什么。
set length 1 0
set 1 10 0
set length 2 0

你可能感兴趣的:(javascript,前端,html5,node.js)