ES6笔记

顶层对象

在浏览器环境指的是window对象, 浏览器和 Web Worker 里面,self也指向顶层对象, 但是 Node 没有self。 Node 里面,顶层对象是global,但其他环境都不支持。

取顶层对象

同一段代码为了能够在各种环境, 都能取到顶层对象, 现在一般是使用this变量,但是有局限性

全局环境中,this会返回顶层对象。 但是,Node 模块和 ES6 模块中,this返回的是当前模块,严格模式下,这时this会返回undefined。 不管是严格模式,还是普通模式,new Function('return this')(),总是会返回全局对象。

但是,如果浏览器用了 CSP(Content Security Policy,内容安全政策),那么eval、new Function这些方法都可能无法使用。 在所有情况下,都取到顶层对象。下面是两种勉强可以使用的方法。

// 方法一
(typeof window !== 'undefined'
   ? window
   : (typeof process === 'object' &&
     typeof require === 'function' &&
     typeof global === 'object')
    ? global
    : this);
​
// 方法二
var getGlobal = function () {
  if (typeof self !== 'undefined') { return self; }
  if (typeof window !== 'undefined') { return window; }
  if (typeof global !== 'undefined') { return global; }
  throw new Error('unable to locate global object');
};

垫片库system.global模拟了这个提案,可以在所有环境拿到global。

// CommonJS 的写法
require('system.global/shim')();
​
// ES6 模块的写法
import shim from 'system.global/shim'; shim();
上面代码可以保证各种环境里面,global对象都是存在的。
​
// CommonJS 的写法
var global = require('system.global')();
​
// ES6 模块的写法
import getGlobal from 'system.global';
const global = getGlobal();

let

1.let 不能预解析 ( 只要块级作用域内存在let命令,它所声明的变量就“绑定”(binding)这个区域,不再受外部的影响。)

2.同作用域内 let声明的变量 不允许重复

3.有块级作用域{ ... } 内部定义变量 外部不能访问

4.只能先声明在使用

 

const

let 4条规则都适用

声明的常量不允许重新赋值 

2.常量必须初始化

const a; //报错 

const a ={ } 

3.可以改变引用类

const实际上保证的,并不是变量的值不得改动,而是变量指向的那个内存地址不得改动。 const只能保证这个指针是固定的,至于它指向的数据结构是不是可变的,就完全不能控制了。

数组解构赋值

let [a, b, c] = [1, 2, 3];
//上面代码表示,可以从数组中提取值,按照对应位置,对变量赋值。
​
let [foo, [[bar], baz]] = [1, [[2], 3]];
foo // 1
bar // 2
baz // 3
​
let [ , , third] = ["foo", "bar", "baz"];
third // "baz"
​
let [x, , y] = [1, 2, 3];
x // 1
y // 3
​
let [head, ...tail] = [1, 2, 3, 4];
head // 1
tail // [2, 3, 4]
​
let [x, y, ...z] = ['a'];
x // "a"
y // undefined
z // []
​
let [x = 1] = [undefined];
x // 1
​
let [x = 1] = [null];
x // null

上面代码中,如果一个数组成员是null,默认值就不会生效,因为null不严格等于undefined。

对象解构赋值

let {foo:aa,bar="hi"} = { foo:"123"}
console.log(foo)//报错
console.log(aa)123
console.log(bar )//hi

foo是匹配的模式,baz才是变量。真正被赋值的是变量baz,而不是模式foo

如果p也要作为变量赋值,可以写成下面这样。

let obj = {
  p: [
    'Hello',
    { y: 'World' }
  ]
};
​
let { p, p: [x, { y }] } = obj;
x // "Hello"
y // "World"
p // ["Hello", {y: "World"}]

字符串扩展

查找字符
let str = 'Hello Brother!';

//includes 是否包含参数字符串
str.includes('Br'); //true

//startsWith  开头是否存在参数字符串
str.startsWith('Hello') //true

//endsWith 结尾是否存在参数字符串
str.endsWith('er!')//true
重复字符
re.repeat(2); //"Hello Brother!Hello Brother!"

re.repeat(-2); // Invalid count value
re.repeat(Infinity); // Invalid count value
//小数会取整 
re.repeat(1.9) // "Hello Brother!"
re.repeat(-0.9) // ""
补全字符
//补全开头 padStart 补齐尾部 padEnd
let pd = 'Brother!'; 
pd.padStart(14,'Hello '); //"Hello Brother!"
//第一个参数为补齐的最大长度(整串字符) 第二个参数为补齐缺省的字符串

//如果原始字符长度大于等于最大长度,返回原字符串
pd.padStart(7,'Hello ')// 'Brother!'
pd.padStart(8,'Hello ')// 'Brother!'

//如果最大长度小于补齐长度,则去除超出部分
pd.padStart(9,'Aay ')//'ABrother!'

//如果缺省第二个参数则 默认使用空格补齐
pd.padStart(9)//' Brother!'
转义符
//以 x 开头,会被当做 16 进制

 `x23` // #

 //以 u 开头,会被当做 unicode  字符
 `u004F` //"O"

//如果无法编译将会报错
ES2018 放松了对`标签模板`里面的字符串转义的限制,无法转义的返回`undefined`;

模板字符串

let obj={
  name:"ww",
  age:"18"
   }
​
let  tag = "<div><span>"+obj.name +"</span></div>";
let  tpl= `<div><span>${obj.name}</span></div>` 
// 反引号 左上角 ESC键下方
​
let  fn= function (info){
    return info
    }
let  tpl= `<div><span>${obj.name}</span></div><div><span>${obj.age}</span></div>
    <div>
    <span>${fn("你好")}</span>
    <span>${1+1}</span>
    </div>

函数参数解构赋值

一,

function fn(param="ss",age=15){ console.log(param - age); } fn();//ss - 15 fn("nihao",18)//nihao - 18

二,

 function fn({name ="ls", age}={}) { console.log(name - age);

} fn();//ls - undefind

fn("nihao",18)//nihao - 18

三, rest 参数(... 剩余参数)

> 使用形式 `...arg` 实数以数组的形势赋给变量
> reset 参数后不能再有形参,否则报错
function fn (a,...arg){
    return arg;
}
fn(0,2,3,4,5)//[2,3,4,5]

function foo (a,...arg,b){
    return arg;
}
//ught SyntaxError: Rest parameter must be last formal parameter
只要函数参数使用了默认值、解构赋值、或者扩展运算符,那么函数内部就不能显式设定为严格模式,否则会报错。
/ 报错
function f(a, b = a) {
  'use strict';
  // code
}

// 报错
const foo = function ({a, b}) {
  'use strict';
  // code
};

// 报错
const fn = (...a) => {
  'use strict';
  // code
};

const obj = {
  // 报错
  fn({a, b}) {
    'use strict';
    // code
  }
};

函数扩展

形参指定默认值
> 形参 不能再次使用 let 和 const 声明
> 形参不能重名
> 函数 length 不包含设置默认值和后面的形参个数
> 使用 `...arg` 中的参数 length 也不包含
const fn = (x, y = 'Owen') =>( console.log(x,y));
fn(1) // 1 "Owen"

//默认参数 惰性求值
let x = 99;
function foo(y = x + 1) {
  console.log(y);
}
foo() // 100
x = 100;
foo() // 101
//调用一次计算一次
事实上 每次调用函数,如果不传递参数, 形参默认传递 `undefined`
 // 默认参数最好定义再尾部,因为使用形参默认参数,那么那个位置的形参必传

function f(x, y = 5, z, ...arg) {
  return [x, y, z];
}

f() // [undefined, 5, undefined]
f(1) // [1, 5, undefined]
f(1, ,2) // 报错
f(1, undefined, 2) // [1, 5, 2]

//length 不包含设置默认值 和后面的形参 的个数,
f().length // 1
作用域
> 函数中的 变量无法访问  默认值
> 函数中的形参名不能和默认名一样
//函数变量无法访问默认值
function f(y = x) {
  let x = 2;
  console.log(y);
}

f() // ReferenceError: x is not defined

//函数中的形参名不能和默认名一样
//参数x = x形成一个单独作用域。实际执行的是let x = x,由于暂时性死区的原因,这行代码会报错
function f(x = x) {
  console.log(x);
}
f()//  x is not defined

var x = 1;
function foo(x, y = function() { x = 2; }) {
  var x = 3;
  y();
  console.log(x);
}

foo() // 3
x // 1
由于 var 声明的 x 和函数形参 x 不再同一个作用域 , 因此调用 y() x值不变;
如果 去掉 var , 那么 x 就指向 形参 x ,调用 y() x = 2。
 
箭头函数
>使用 ` () => ` 定义函数
注意:
- this 指向函数定义时所绑定的普通函数,不会被(bind,call,apply)更改,也不会被调用时的上下文改变。
let fn = () =>console.log(this);
let obj = {name:"Owen"};

fn.call(obj) //window

fn.bind(obj)
fn() //window

fn.apply(obj)  //window
 
 
 //可以通过改变宿主环境来改变 this 指向
 
 function foo (){
 
return () =>{ 
  console.log(this);

  return ()=> {console.log(this)};
  }
}
foo.call(obj)() //{name: "Owen"}
foo.call(obj)()() //{name: "Owen"} {name: "Owen"}
- 外层没有普通函数 ,严格模式和非严格模式下它的this都会指向window(全局对象)。

- 不可以当作构造函数,也就是说,不可以使用new命令,没有`prototype`属性,不支持`new.target`,否则会抛出一个错误。
- 参数和箭头之间不能换行
- 不可以使用arguments对象,该对象在函数体内不存在。如果要用,可以用 rest 参数代替。

- 不可以使用yield命令,因此箭头函数不能用作 Generator 函数。
//定义简单函数
let fn = () => 'Owen';
fn()// 'Owen'

let foo = r => r;
foo('Owen') // 'Owen'

let f = (num1,num2) => num1 + num2;
f(1,2)//3

//如果返回一个对象需要小括号包裹,f否则会报错
let f = (name,age) => ({name,age});
f('Owen',18)//{name: "Owen", age: 18}


//如果代码部分大于一条语句,那么需要 大括号包裹,使用return 返回值

let fn1 = r => {
    let a = 1;
    console.log(a);
    return r + a;

}

不推荐使用场景

var obj = {
  gender:"man",
  getSex: () =>  {console.log(this.gender)}
}
obj.getSex() //undefined
//this -> global
 
原文地址:https://www.cnblogs.com/gaoguowen/p/9889916.html