当前位置: 移动技术网 > IT编程>开发语言>JavaScript > 荐 ES6知识点-下

荐 ES6知识点-下

2020年07月17日  | 移动技术网IT编程  | 我要评论

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种原始类型:、、、和。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

如对本文有疑问, 点击进行留言回复!!

相关文章:

验证码:
移动技术网