ES6 一些零碎的知识点

String prototype repeat(count):返回一个重复当前字符串若干次数的新字符串 varstr =& 039;abc& 039;;str
  • String.prototype.repeat(count):返回一个重复当前字符串若干次数的新字符串
varstr ='abc';str.repeat(3);// abcabcabc
  • Number 对象
    • Number.parseInt(string[, radix]):根据给定的进制数把一个字符串解析成整数
    • Number.parseFloat(string):把一个字符串解析为一个浮点数
Number.parseInt ===parseInt// trueNumber.parseFloat ===parseFloat// true
  • Math 对象
    • Math.trunc(value):将数字的小数部分去掉,只留整数部分
    • Math.cbrt(x):返回任意数字的立方根
    • Math.hypot([value1[,value2, …]]):返回它的所有参数的平方和的平方根
Math.trunc(12.02);// 12Math.cbrt(27);// 3Math.hypot(3,4);// 5

新的运算符

  • ES7 指数运算符: **
2**3;// 83**2;// 9
  • 扩展运算符

扩展运算符(spread)是三个点 ...。它好比rest参数的逆运算,将一个数组转为用逗号分隔的参数序列。

console.log(1, ...[2,3,4],5);// 1 2 3 4 5
vararr1 = [12,"hello"];vararr2 = [false,"world"];vararr3 = [...arr1, ...arr2];console.log(arr3);// [12, "hello", false, "world"]

函数相关

  • 函数的 rest 参数(形式为“…变量名”):用于获取函数的多余参数,这样就不需要使用arguments对象了

rest 参数搭配的变量是一个数组,该变量将多余的参数放入数组中。

// test 1functionf1(...values){console.log(values);// [1, 2, "percy", true]}f1(1,2,"percy",true);// test 2functionf2(num1, ...values){console.log(num1);// 1console.log(values);// [2, "percy", true]}f2(1,2,"percy",true);// test 3// rest 参数之后不能再有其他参数(即只能是最后一个参数),否则会报错functionf3(num1, ...values, bool){// 报错,Uncaught SyntaxError: Rest parameter must be last formal parameterconsole.log(num1);console.log(values);console.log(bool);}f3(1,2,"percy",true);

对象相关

  • 更简洁的对象字面量写法

ES6允许直接写入变量和函数,作为对象的属性和方法。

// 属性letname ="percy";letage =21;// 方法letsayName =function(){console.log(this.name);};letsayAge = () => {console.log(this.age); };// 创建对象letuser = { name, age, sayName, sayAge, sayAll() {console.log(`name:${this.name},age:${this.age}`); }};console.log(user);// Object {name: "percy", age: 21}user.sayName(); // percyuser.sayAge(); // undefined// 要是不理解上一行为什么是 undefined,可以去看看箭头函数是如何对待 this 的user.sayAll(); // name:percy,age:21
  • 属性名表达式
letobj = {// // ES6 新增写法 [1+2+'a'+'b']:"hell"};// 传统写法obj.foo = true;// ES6 新增写法obj['a'+'bc'] =123;console.log(obj);// Object {3ab: "hell", foo: true, abc: 123}
  • Object.is(value1, value2):用来判断两个值是否是同一个值

传统的两种相等比较有一些缺陷

  • ==:先对它两边的操作数做隐式的类型转换,再进行比较
  • ===:认为 +0 和 -0 相等,NaN 和 NaN 不相等

而 Object.is() 就是为弥补这些缺陷设计出来的!

""==false;// trueObject.is("",false);// false+ 0===-0;// trueNaN===NaN;// falseObject.is(+0,-0);// falseObject.is(NaN,NaN);// true
  • Object.assign(target, …sources):把任意多个的源对象 自身的可枚举属性 浅拷贝给目标对象,然后返回目标对象
letperson1 = { name1: "percy", age1: "21", isStudent: true};// 设置 age1 属性为不可枚举Object.defineProperty(person1,"age1", { enumerable:false});letperson2 = { name2: "zyj", age2: 22, sayName: function(){console.log(this.name2); }};// 设置 sayName 属性(或方法)为不可枚举Object.defineProperty(person2,"sayName", { enumerable:false});letperson3 = { name3: "bob", age3: 23, sayAge: function(){console.log(this.age3); }}letpersons =Object.assign({ name:"persons"}, person1, person2, person3);console.log(persons);// persons = {// age2: 22,// age3: 23,// isStudent: true,// name: "persons",// name1: "percy",// name2: "zyj",// name3: "bob",// sayAge: function() {// console.log(this.age3);// }// }

Object.assign 方法实行的是 浅拷贝,而不是深拷贝。也就是说,如果源对象某个属性的值是对象,那么目标对象拷贝得到的是这个对象的引用。

// 继续上面的代码persons.sayAge === person3.sayAge; // true
  • ES6 中,共有 5 种方法可以遍历对象的属性
    • for…in:循环遍历对象自身的和继承的可枚举属性(不含 Symbol 类型的属性)
    • Object.keys(obj):返回一个数组,包括对象自身的(不含继承的)所有可枚举属性(不含 Symbol 类型的属性)
    • Object.getOwnPropertyNames(obj):返回一个数组,包含对象自身的所有属性(不含 Symbol 类型的属性,不包含继承属性,但是包括不可枚举属性)
    • Object.getOwnPropertySymbols(obj):返回一个数组,包含对象自身的所有 Symbol 类型的属性(不包括继承的属性)
    • Reflect.ownKeys(obj):返回一个数组,包含对象自身的所有属性(包含 Symbol 类型的属性,还有不可枚举的属性,但是不包括继承的属性)

以上的5种方法遍历对象的属性,都遵守同样的属性遍历的次序规则

  • 首先遍历所有属性名为数值的属性,按照数字排序
  • 其次遍历所有属性名为字符串的属性,按照生成时间排序
  • 最后遍历所有属性名为Symbol值的属性,按照生成时间排序

从 ES6 起,对象的属性名有两种类型: 一种是原来就有的字符串另一种就是新增的Symbol类型。凡是属性名属于 Symbol 类型,就都是独一无二的,可以保证不会与其他属性名产生冲突。

// 为 obj 设置 2 个继承属性Object.prototype.inherit1 ="inherit111";Object.prototype[Symbol('inherit2')] ="inherit222";// a,b 为 Symbol 类型的属性名leta =Symbol('a');letb =Symbol('b');letobj = { [a]: 'aSymbol', [b]: 'bSymbol', name: "percy", age: 20, c: "cEnumFalse", d: "dEnumFalse"};// 设置 c,d 为不可枚举的属性Object.defineProperties(obj, { c: { enumerable: false}, d: { enumerable: false}});// test 1vararr = [];for(letvalueinobj) { arr.push(value); }console.log(arr);// ["name", "age", "inherit1"]// test 2console.log(Object.keys(obj));// ["name", "age"]// test 3console.log(Object.getOwnPropertyNames(obj));// ["name", "age", "c", "d"]// test 4console.log(Object.getOwnPropertySymbols(obj));// [Symbol(a), Symbol(b)]// test 5console.log(Reflect.ownKeys(obj));// ["name", "age", "c", "d", Symbol(a), Symbol(b)]
  • 谈谈 __proto__ 属性

__proto__属性(前后各两个下划线), 用来读取或设置当前对象的 prototype 对象(原型对象),该属性没有写入 ES6 的正文,而是写入了附录,原因是 __proto__ 前后的双下划线,说明它本质上是一个内部属性,而不是一个正式的对外的API,只是由于浏览器广泛支持,才被加入了 ES6。标准明确规定,只有浏览器必须部署这个属性,其他运行环境不一定需要部署,而且新的代码最好认为这个属性是不存在的。因此, 无论从语义的角度,还是从兼容性的角度,都不要使用这个属性,而是使用下面的 Object.setPrototypeOf()(写操作)、 Object.getPrototypeOf()(读操作)、 Object.create()(生成操作)代替。

  • Object.getPrototypeOf(object):(ES 5.1)返回指定对象的原型对象
  • Object.setPrototypeOf(obj, prototype):(ES 6)将一个指定的对象的原型设置为另一个对象或者null
  • Object.create(proto, [ propertiesObject ]):(ES 5.1)创建一个拥有指定原型和若干个指定属性的对象
letobj = { name: "percy", age: 20};letobjProto = { where: "objProto", sayName: function(){console.log(this.name); }};console.log(Object.getPrototypeOf(obj));// Object {}console.log(Object.getPrototypeOf(objProto));// Object {}Object.setPrototypeOf(obj, objProto);Object.setPrototypeOf(objProto,null);console.log(Object.getPrototypeOf(obj));// Object {where: "objProto"}console.log(Object.getPrototypeOf(objProto));// nullletcreateObj =Object.create(objProto, { name: { value:"I am create!"} });createObj.sayName(); // I am create!
未登录用户
全部评论0
到底啦