欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页  >  IT编程

荐 ES6知识点-下

程序员文章站 2022-03-13 20:24:01
ECMAScript 6(简称ES6)是于2015年6月正式发布的JavaScript语言的标准,正式名为ECMAScript 2015(ES2015)。它的目标是使得JavaScript语言可以用来编写复杂的大型应用程序,成为企业级开发语言...

ES6知识点-下

上一篇传送门 链接: ES6知识点-上.

字符串API

indexOf ()

查找字符串中是否包含某一个子字符串

参数1:需要查询的目标字符串

参数2:开始查询的索引(不写默认为0)

返回值:如果找到 返回第一个目标子串的索引 如果没找到 就返回 -1

注意:indexOf对大小写敏感

var str="Hello world!"
document.write(str.indexOf("Hello") + "<br />")
document.write(str.indexOf("World") + "<br />")
document.write(str.indexOf("world"))

//0
//-1
//0

includes()

检测字符串或者数组中是否包含某一个子字符串或者元素

参数1:需要查询的目标字符串

参数2:就是开始查询的索引(如果不写 默认从0开始)

返回值:布尔类型 找到返回true 没找到返回false

[1, 2, 3].includes(2);     // true
[1, 2, 3].includes(4);     // false
[1, 2, 3].includes(3, 3);  // false
[1, 2, 3].includes(3, -1); // true
[1, 2, NaN].includes(NaN); // true

两者区别

  1. 返回值 :indexOf方法返回 找到的第一个子字符串位置索引 includes找到就返回true
  2. 如果数组里面包含NaN 但是我们又正好需要查数组里有没有NaN 那么indexOf就没用了 就只能用includes
  3. 如果数组里面包含空值 那么使用indexOf判断就会出错 是能使用includes

箭头函数

ES6标准新增了一种新的函数:Arrow Function(箭头函数)。

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

基础语法

通常函数的定义方法

var fn1 = function(a, b) {

  return a + b

}

function fn2(a, b) {

  return a + b

}

使用ES6箭头函数语法定义函数,将原函数的“function”关键字和函数名都删掉,并使用“=>”连接参数列表和函数体

  1. 函数体只有一句话时返回值可以省略return函数体可以省略{}
(a,b)=>a+b
  1. 如果箭头函数没有参数 或者有多个参数 那么参数的()就不能省略
// 无参

var fn1 = function() {}

var fn1 = () => {}

 

// 单个参数

var fn2 = function(a) {}

var fn2 = a => {}

 

// 多个参数

var fn3 = function(a, b) {}

var fn3 = (a, b) => {}

 

// 可变参数

var fn4 = function(a, b, ...args) {}

var fn4 = (a, b, ...args) => {}
  1. 如果箭头函数的函数体有多条代码 那么就不能省略{} 以及返回值也不能省略return
var fn3 = function(a, b) {
    console.log(a,b);
    return a+b
}

var fn3 = (a, b) => {
    console.log(a,b);
    return a+b
}
  1. 如果函数体只有一句话 并且 返回值也是对象 name这个返回值必须用()包起来

​ 因为函数体使用的是{} 对象也是{}

var info = (name,age) => ({
    name:name,
    age:age
})
  1. 如果对象只有一个键值对 那么不会报错 但是也没有正确的值

因为js引擎解析的时候 {} 默认解析为函数体结构 函数体代码 name:name

var p = (name)=>{
    name:name;
}

console.log(p("lili"));//undefined

ES6中的this指向

普通函数的this指向

this就是谁调用 this就指向谁 this是在调用的时候确定的

function a(){
    var user = "乐乐";
    console.log(this.user); //undefined
    console.log(this); //Window
}
a();

上面说的this最终指向的是调用它的对象,这里的函数a实际是被Window对象所点出来的

相当于 window.a()

对象里面的this指向

对象里面的方法 它里面的this指向就是当前这个对象

var o = {
    user:"乐乐",
    fn:function(){
        console.log(this.user);  //乐乐
    }
}
o.fn();

这里的this指向的是对象o,因为你调用这个fn是通过o.fn()执行的,那自然指向就是对象o,但是强调一点,this的指向在函数创建的时候是决定不了的,在调用的时候才能决定,谁调用的就指向谁,一定要搞清楚这个。

错误示范

var o = {
    user:"乐乐",
    birth:1998,
    age:2020-this.birth,
    fn:function(){
        console.log(this.age);  //NaN
    }
}
o.fn();

这个错误示范很形象的对应了上面的那句话 this的指向在函数创建的时候是决定不了的

当创建这个o对象的时候 this 是指向 window 的 age:2020-this.birth这句话里面的this.birth就变成了window.birth值是undefined,2020-undefined可想而知结果就是NaN。而且 在对象里面调用对象的方法是不现实的。

定时器里面的this指向

如果没有特殊的指向 那么 里面setTimeout和setInterval的回调函数德this一定是指向window

构造函数里面的this

构造函数实例化对象的this

function Fn(){
    this.user = "乐乐";
}
var a = new Fn();
console.log(a.user); //乐乐

这里之所以对象a可以点出函数Fn里面的user是因为new关键字可以改变this的指向,将这个this指向对象a,为什么我说a是对象,因为用了new关键字就是创建一个对象实例,我们这里用变量a创建了一个Fn的实例(相当于复制了一份Fn到对象a里面),此时仅仅只是创建,并没有执行,而调用这个函数Fn的是对象a,那么this指向的自然是对象a,那么为什么对象a中会有user,因为你已经复制了一份Fn函数到对象a中,用了new关键字就等同于复制了一份。

构造函数当成普通函数调用的this

function Fn() {
    this.user = "乐乐";
    return this.user
}
console.log(Fn());//乐乐

特殊情况

var o = {
    a:10,
    b:{
        a:12,
        fn:function(){
            console.log(this.a); //undefined
            console.log(this); //window
        }
    }
}
var j = o.b.fn;
j();

这里this指向的是window,是不是有些蒙了?其实是因为你没有理解一句话,这句话同样至关重要。

this永远指向的是最后调用它的对象,也就是看它执行的时候是谁调用的,虽然函数fn是被对象b所引用,但是在将fn赋值给变量j的时候并没有执行所以最终指向的是window。

symbol

ES5中包含5种原始类型:字符串数字布尔值nullundefined。ES6引入了第6种原始类型——Symbol

ES5的对象属性名都是字符串,很容易造成属性名冲突。比如,使用了一个他人提供的对象,想为这个对象添加新的方法,新方法的名字就有可能与现有方法产生冲突。如果有一种机制,保证每个属性的名字都是独一无二的,这样就从根本上防止了属性名冲突。这就是ES6引入Symbol的原因,本文将详细介绍ES6中的Symbol类型

创建

Symbol 值通过Symbol函数生成。这就是说,对象的属性名可以有两种类型:一种是字符串,另一种是Symbol类型。凡是属性名属于 Symbol 类型,就都是独一无二的,可以保证不会与其他属性名产生冲突

let firstName = Symbol();
let person = {};
person[firstName] = "火车";
console.log(person[firstName]); // "火车"

[注意]Symbol函数前不能使用new命令,否则会报错。因为生成的 Symbol 是一个原始类型的值,不是对象

//Uncaught TypeError: Symbol is not a constructor
let firstName = new Symbol();

Symbol函数接受一个可选参数,可以添加一段文本来描述即将创建的Symbol,这段描述不可用于属性访问,但是建议在每次创建Symbol时都添加这样一段描述,以便于阅读代码和调试Symbol程序

let firstName = Symbol("first name");
let person = {};
person[firstName] = "火车";
console.log("first name" in person); // false
console.log(person[firstName]); // "火车"
console.log(firstName); // "Symbol(first name)"

Symbol的描述被存储在内部[[Description]]属性中,只有当调用Symbol的toString()方法时才可以读取这个属性。在执行console.log()时隐式调用了firstName的toString()方法,所以它的描述会被打印到日志中,但不能直接在代码里访问[[Description]]

【类型检测】

Symbol是原始值,ES6扩展了typeof操作符,返回"symbol"。所以可以用typeof来检测变量是否为symbol类型

let symbol = Symbol("test symbol");
console.log(typeof symbol); // "symbol"

使用

由于每一个Symbol值都是不相等的,这意味着Symbol值可以作为标识符,用于对象的属性名,就能保证不会出现同名的属性。这对于一个对象由多个模块构成的情况非常有用,能防止某一个键被不小心改写或覆盖

所有使用可计算属性名的地方,都可以使用Symbol

let firstName = Symbol("first name");
// 使用一个需计算字面量属性
let person = {
    [firstName]: "火车"
};
// 让该属性变为只读
Object.defineProperty(person, firstName, { writable: false });
let lastName = Symbol("last name");
Object.defineProperties(person, {
    [lastName]: {
        value: "match",
        writable: false
    }
});
console.log(person[firstName]); // "火车"
console.log(person[lastName]); // "match"

在此示例中,首先通过可计算对象字面量属性语法为person对象创建了个Symbol属性firstName。后面一行代码将这个属性设置为只读。随后,通过Object.defineProperties()方法创建一个只读的Symbol属性lastName,此处再次使用了对象字面量属性,但却是作为object.defineProperties()方法的第二个参数使用

[注意]Symbol 值作为对象属性名时,不能用点运算符

var mySymbol = Symbol();
var a = {};

a.mySymbol = 'Hello!';
a[mySymbol] // undefined
a['mySymbol'] // "Hello!"

由上面结果看出,a.mySymbol和a[‘mySymbol’]里的mySymbol是字符串类型的属性名,a[mySymbol]里的mySymbol才是Symbol类型的属性名。虽然都叫mySymbol,但值不相同

尽管在所有使用可计算属性名的地方,都可以使用Symbol来代替,但是为了在不同代码片段间有效地共享这些Symbol,需要建立一个体系

共享体系

有时希望在不同的代码*享同一个Symbol,例如,在应用中有两种不同的对象类型,但是希望它们使用同一个Symbol属性来表示一个独特的标识符。一般而言,在很大的代码库中或跨文件追踪Symbol非常困难而且容易出错,出于这些原因,ES6提供了一个可以随时访问的全局Symbol注册表

Symbol.for()

如果想创建一个可共享的Symbol,要使用Symbol.for()方法。它只接受一个参数,也就是即将创建的Symbol的字符串标识符,这个参数同样也被用作Symbol的描述

let uid = Symbol.for("uid");
let object = {};
object[uid] = "12345";
console.log(object[uid]); // "12345"
console.log(uid); // "Symbol(uid)"

Symbol.for()方法首先在全局Symbol注册表中搜索键为"uid"的Symbol是否存在。如果存在,直接返回已有的Symbol,否则,创建一个新的Symbol,并使用这个键在Symbol全局注册表中注册,随即返回新创建的Symbol

后续如果再传入同样的键调用Symbol.for()会返回相同的Symbol

let uid = Symbol.for("uid");
let object = {
    [uid]: "12345"
};
console.log(object[uid]); // "12345"
console.log(uid); // "Symbol(uid)"
let uid2 = Symbol.for("uid");
console.log(uid === uid2); // true
console.log(object[uid2]); // "12345"
console.log(uid2); // "Symbol(uid)

在这个示例中,uid和uid2包含相同的Symbol并且可以互换使用。第一次调用Symbol.for()方法创建这个Symbol,第二次调用可以直接从Symbol的全局注册表中检索到这个Symbol

Set()构造函数

关于Set()函数

Set是一个构造器,类似于数组,但是元素没有重复的

  1. 接收数组或者其他iterable接口的数据 用于初始化数据
let a=new Set([1,32,424,22,12,3,2,2,1]);
console.log(a)//[ 1, 32, 424, 22, 12, 3, 2 ]
  1. 实现数组去重
let b=[1,2,3,4,51,51,2,23,2];
let c=new Set(b);
b=[...c];
console.log(b);//[ 1, 2, 3, 4, 51, 23 ]
  1. Set内默认NaN是相等的 遵循的是’===’
let d=new Set();
d.add(NaN);
d.add(NaN);
console.log(d);//[NaN]

Set()的方法

  1. add()增加一个成员 返回set结构本身

  2. delete()删除一个成员 返回bool

  3. has()判断里面是否存在某个元素,返回bool

  4. clear()清楚所有成员,没有返回值

let e=new Set();
let f=e.add(1);
console.log(e,f);//[1] [1]
let g=f.has(1);
console.log(g);//true
f.add(3);
console.log(f)//[1,3]
let h=f.delete(3);
console.log(h,f)//true [1]
f.clear();
console.log(f)//[]

Array.from()可以将set转换为数组

let i=new Set([1,2,3,4,5]);
console.log(Object.prototype.toString.call(Array.from(i)));//[object Array]

遍历方法

for…of

keys()

values()

entries()

forEach

let a=new Set([11,22,33,44]);
for(let i of a){
    console.log(i)
}// 11 22 33 44
for(let i of a.values()){
    console.log(i)
}//11 22 33 44
for(let i of a.keys()){
    console.log(i)
}//11 22 33 44
for(let i of a.entries()){
    console.log(i)
}//[11,11] [22,22] [33,33] [44,44]
a.forEach((key,value)=>{
    console.log(key,value)
})//11 11   22 22  33 33  44 44

本文地址:https://blog.csdn.net/qq_42079388/article/details/107370996

相关标签: ES6