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

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值