热门标签 | HotTags
当前位置:  开发笔记 > 编程语言 > 正文

【面试必备】【ES6】学Vue前必须掌握的内容(上)

变量声明⭐采用let和const分别声明变量和常量。不用var所以不存在变量提升。解构⭐①数组解构[]等号左边允许存在默认值。变量的取值按照顺序。之前的写法vararr[


变量声明 ⭐


  • 采用 let 和 const 分别声明变量和常量。
  • 不用var所以不存在变量提升

解构 ⭐


① 数组解构[ ]

     等号左边允许存在默认值。变量的取值按照顺序。  

//之前的写法
var arr=[1,2];
var a=arr[0];
var b=arr[1];
//ES6
let [a,b]=[1,2];
console.log(a,b) -> 1 2
let [c,d]=[3]
console.log(c,d) -> 3 undefined
let [f=4,g=5,h=6]=[,undefined,null];
console.log(f,g,h) -> 4 5 null

② 对象解构{}

     根据键值取值。

let obj={name:'hua',age:18
}
//不同名,则把左边的属性的值赋给右边自定义的变量
let {name:n,age:a}=obj;
console.log(n,a) -> 'hua' 18
console.log(name,age) ->打印报错 未声明
//同名的可以将name:name省略成name
let {age,name}=obj;
console.log(name,age) -> 'hua' 18

③ 字符串解构

     此时字符串被转换成一个类似于数组的对象。

let str='hello World';
let [a,b,c]=str;
console.log(a,b,c,typeof(a)) -> h e l string


扩展 


① 函数的扩展 ⭐  


res参数(剩余参数)

 用于获取函数的多余参数,会将多余的实参放进一个数组里。

function fn(a,...arr){console.log(a); -> 1console.log(arr); -> ['a', 'b'] console.log(arr[0]); -> aconsole.log(arr[2]); -> undefined
}
fn(1,'a','b');//方法中的定义了4个参数,但调用函数时只使用了3个参数,ES6 中并不会报错。

注意,res参数之后不能再有任何参数。函数的length属性(指明函数形参的个数)不包括res参数

(function(a){}).length //1
(function(...a){}).length //0

严格模式

规定只要函数参数使用了默认值、解构赋值或者扩展运算符,那么函数内部就不能显示设定为严格模式,会报错。

function fn(a,b=1){ //报错'use strict';
}

 两种方式可以避免这种限制:


  • 设定全局性的严格模式;
  • 把函数包在一个无参数的立即执行函数里。

name属性

具名函数返回函数原本的名字,匿名函数返回实际的函数名

function fn(){}
let fun=function(){}
fn.name //fn
fun.name //fun (ES5中返回空字符串)

箭头函数 ( 参数 ) => { 函数体 } 

注意要点:


  • 不会创建自己的this,只会从自己的作用域链的上一层继承this;⭐
  • 不能作为构造的实例化对象,即不能用new;
  • 不能使用argument函数内置对象;
  • 当只有一个参数时,小括号可以省略;
  • 当函数体只有一条语句且为return,可以省略return和大括号;
  • 不能使用yield命令,因此不能作为Generator函数。

由于箭头函数this指向的特殊性,箭头函数不适用于定义对象的方法,且该方法内部包括this。

s = 21;
const obj = {s: 42,f: () => console.log(this.s)//继承作用域的上一层的this,指向全局
};
obj.f() // 21

② 数组的扩展 ⭐


Array.from()

可将类似数组的对象和可遍历的对象(包括新增的数据结构Set、Map)


伪数组:有索引,有长度,但是没有方法


let arrayLike={'0':'a','1':'b','2':'c',length:3
};
const arr=Array.from(arryLike);
console.log(arr); //['a','b','c']
//length:2->['a','b'] length:4->['a','b','c',undefined]

实际应用开中,我们常见的伪数组就是DOM操作中返回的元素对象集合,以及函数的内置arguments对象。都能用Array.from()方法将伪数组转为真正的数组。

let arrayLike=document.querySelectorAll('button');
let a=document.getElementsByTagName('button');
console.log(arrayLike,a);//NodeList(5) HtmlCollection(5)
const arr=Array.from(arrayLike);
console.log(arr);//(5)

⭐补充一下,DOM操作中三种方式返回的伪数组类型有些不同:

  • querySelectorAll():NodeList类型,获取子节点操作中的childNodes属于该类型。即返回的集合中包含元素节点和文本节点(文字、空格)等;
  • getElementsBytagName()和getElementsByClassName()返回的是HtmlCollection类型,获取子节点操作中的children就属于该类型.即返回的集合中只有元素节点。


Array.of() 

将一组值转换为数组。

console.log(Array.of(1,2,3)); //[1,2,3]
console.log(Array.of(1,2,3).length); //3

 Array.of() 返回由参数组成的数组,如果没有参数就返回一个空数组。这就弥补了数组构造函数中参数个数不同导致行为有差异的问题。

//没有参数时,一致
Array() //[]
Array.of() //[]
//一个参数时,一个是长度,一个是值
Array(2) //[empty × 2] length:2
Array.of(2) //[2]
//多个参数时,一致
Array(1,2) //[1,2]
Array.of(1,2) //[1,2]

③ 对象的扩展 ⭐  


Object.defineProperty


 Object.defineProperty(obj, prop, descriptor) 定义新属性或修改原有的属性


let obj={name:'hua',age:18
}
console.log(obj); //{name: 'hua', age: 18}
/* 传统方式
obj.sex='man';
obj.age=19; */
Object.defineProperty(obj,'sex',{value:'man'
});
Object.defineProperty(obj,'age',{value:19
});
console.log(obj); //{name: 'hua', age: 19, sex: 'man'}

 第三个参数,以对象的形式书写


  • value: 设置属性的值,默认为undefined;

  • writable: 值是否可以重写,当属性是由该方法新创建的时候,默认值为false;

    console.log(obj); //{name: 'hua', age: 18}
    Object.defineProperty(obj,'sex',{value:'man',writable:true, //当属性是由该方法新创建的时候,默认值才为false
    });
    Object.defineProperty(obj,'sex',{value:1
    });
    Object.defineProperty(obj,'age',{value:20,writable:false
    });
    console.log(obj); //{name: 'hua', age: 20, sex: 1}
    obj.sex=0;
    obj.age=30;
    console.log(obj); //{name: 'hua', age: 20, sex: 0}

  • enumerable: 目标属性是否可以被枚举,当属性是由该方法新创建的时候,默认值为false;

    console.log(Object.keys(obj)); //['name', 'age']
    Object.defineProperty(obj,'sex',{value:'man',enumerable: true
    });
    console.log(Object.keys(obj)); //['name', 'age', 'sex']
    Object.defineProperty(obj,'age',{enumerable:false
    });
    console.log(Object.keys(obj)); //['name', 'sex']

  • configurable: 目标属性是否可以被删除或再次修改特性,当属性是由该方法新创建的时候,默认值为false。

    Object.defineProperty(obj,'sex',{value:'man', configurable:true
    });
    console.log(obj); //{name: 'hua', age: 18, sex: 'man'}
    delete obj.sex;
    console.log(obj); //{name: 'hua', age: 18}
    delete obj.name;
    Object.defineProperty(obj,'age',{configurable:false
    });
    delete obj.age;
    console.log(obj); //{age: 18}

    Object.defineProperty(obj,'sex',{value:'man', configurable:false
    });
    Object.defineProperty(obj,'sex',{value:1, writable:true
    });
    console.log(obj); //Error:Cannot redefine property: sex


Object.freeze


  Object.freeze()方法作用就是冻结一个对象,即让该对象无法修改。可以提升性能


const a=1;
//a=2; //报错
const obj={b:2};
obj.b=3;
console.log(obj.b); //3

我们都知道,用const声明基本数据类型是无法进行修改的,但声明的对象的属性是可以修改的,因为赋给的变量里存的是该对象的地址。这时就可以使用Object.freeze()方法来冻结。

 被冻结后的对象:


  • 不能添加新属性;
  • 不能修改、删除原有的属性;
  • 不能修改原型;
  • 不能修改已有属性的可写性writable、可枚举性enumerable和可配置性configurable。

let obj={name:'hua',age:18
}
console.log(obj); //{name: 'hua', age: 18}
Object.freeze(obj);
obj.sex='man';
obj.age=19;
console.log(obj); //{name: 'hua', age: 18}
console.log(Object.freeze(obj))//{name: 'hua', age: 18}

//该方法返回的就是传入的对象本身,所以一般不用接收返回值。也可以冻结数组,毕竟数组的本质也是对象。

注意,该方式属于浅冻结。当冻结的对象里还有对象时,内层的对象仍可以被修改

let obj={name:'hua',deep:{age:18}
};
Object.freeze(obj);
obj.name=123;
obj.deep.age=19;
console.log(obj.name,obj.deep); //hua {age:19}

 解决办法:封装一个深冻结函数,随时调用。

function deepFreeze(obj){//获取所有属性let proName=Object.getOwnPropertyNames(obj);//遍历proName.forEach(item=>{let pro=obj[item];//如果某个属性的属性值是对象,则递归调用if(pro instanceof Object && pro!==null){deepFreeze(pro);} })return Object.freeze(obj);
}deepFreeze(obj);
console.log(obj.name,obj.deep); //hua 18

Object.setPrototypeOf(),Object.getPrototypeOf()

之前,实现对象的继承是通过原型链实现的。ES6提供了更多原型对象的操作。

Object.setPrototypeOf()方法的作用与__proto__相同,用来设置一个对象的原型对象,并返回参数对象本身。

let obj={ x:1 };
let proto={ y:function(){return 2} };
Object.setPrototypeOf(obj,proto);
proto.z=3;
console.log(obj.x, obj.y(), obj.z); //1 2 3
console.log(Object.setPrototypeOf(obj,proto)); // {x:1}

//将proto对象设为obj对象的原型,所以obj对象能够获取proto对象的属性

Object.getPrototypeOf方法与Object.setPrototypeOf方法配套,用于读取一个对象的原型对象。

console.log(Object.getPrototypeOf(obj)); // {y:f,z:3}

  • 如果方法的第一个参数不是对象,就会自动转为对象。但是返回的它本身,所以不会产生任何效果。
  • 如果第一个参数是undefined或null,就会报错,因为它们无法转换为对象。

④ 运算符的扩展⭐​  


扩展运算符 ... 


扩展运算符可以将数组或者对象转为用逗号分隔的参数序列。  可以看作是res参数的逆运算。 


let arr=[1,2,3];
...arr //1,2,3
console.log(...arr); //1 2 3

 输出没有逗号是因为逗号被console.log方法当作参数分隔符了,所以不会输出逗号。

用途1:合并数组
let arr1 = [1, 2, 3];
let arr2 = [4, 5, 6];
// 方法1
let arr3 = [...arr1, ...arr2];
console.log(arr3); // [1,2,3,4,5,6]
// 方法2
arr1.push(...arr2);
console.log(arr1); // [1,2,3,4,5,6]

用途2:将伪数组或可遍历的对象转为数组
let pa = document.getElementsByClassName('li');
let arr = [...pa]; // 利用扩展运算符,将伪数组转为真正的数组
//pa.push('a'); 报错 伪数组不支持
arr.push('a');
console.log(arr); //[li,li,a]
//方法2
let a=Array.from(pa);
a.push('a');

用途3:避免指向同一个地址
//对象是引用数据类型,赋给的变量存的是该对象的地址,所以
let str1=[1,2];
let str2=str1;
//这两个变量存的是同一个对象的地址,通过任何一个变量对该数组进行改变,该数组都会发生相应的改变,
//这时就可以通过扩展运算符
let str2=[...str1]; //为str2开辟一个新的内存地址,就不会影响str1了

链判断运算符?.

引入的原因:在读取对象内部的某个属性时,安全的做法是需要一层层的判断属性的上层对象是否存在。而这样层层判断十分麻烦,因此引入了链判断运算符" ?. "。

//引入前
let name = (message && message.user && message.user.name)||'default';
//引入后
let name = message?.user?.name || 'default';

当左侧的对象为null或undefined时,就不再往下运算,而是直接返回undefined。 

常见形式:

a?.b <&#61;> a&#61;&#61; null ? undefined : a.b //三元运算符&#xff1a;条件&#xff1f;满足的&#xff1a;不满足的a?.[x] <&#61;> a&#61;&#61;null ? undefined : a[x]a?.b() <&#61;> a&#61;&#61;null ? undefined : a.b() //如果是不满足的情况下且a.b不是函数不可调用就报错a?.() <&#61;> a&#61;&#61;null ? undefined : a() //如果是不满足的情况下且a不是函数就报错

⑤ 字符串扩展&#xff1a;


模板字符串⭐


字符串${变量}字符串



其他扩展 


  • includes(str)&#xff1a;判断是否包含指定的字符串
  • startsWith(str)&#xff1a;判断是否以指定字符串开头
  • endsWith(str)&#xff1a;判断是否以指定字符串结尾
  • repeat(count)&#xff1a;重复指定的次数


⑥ Number扩展&#xff1a;


  • 八进制0o表示&#xff0c;二进制0b&#xff1b;
  • Number.isFinite(n)&#xff1a;判断是否为有限大的数。比如Infinity这种无穷大的数&#xff0c;返回的就是 false。
  • Number.isNaN(n)&#xff1a;判断是否为 NaN。
  • Number.isInteger(n)&#xff1a;判断是否为整数。
  • Number.parseInt(str)&#xff1a;将字符串转换为对应的数值。
  • Math.trunc(n)&#xff1a;去除小数部分。

 


 




总结给大家推荐一个实用面试题库


 1、前端后端面试题库 &#xff08;面试必备&#xff09;            推荐&#xff1a;★★★★★

地址&#xff1a;前端面试题库


2、前端技术导航大全      推荐&#xff1a;★★★★★

地址&#xff1a;前端技术导航大全


3、开发者颜色值转换工具   推荐&#xff1a;★★★★★

地址 &#xff1a;开发者颜色值转换工具


推荐阅读
  • 本文讨论了一个关于cuowu类的问题,作者在使用cuowu类时遇到了错误提示和使用AdjustmentListener的问题。文章提供了16个解决方案,并给出了两个可能导致错误的原因。 ... [详细]
  • 如何自行分析定位SAP BSP错误
    The“BSPtag”Imentionedintheblogtitlemeansforexamplethetagchtmlb:configCelleratorbelowwhichi ... [详细]
  • 本文主要对比了Proxy和Object.defineProperty两种对象属性操作方式的优劣,并介绍了它们各自的应用场景。Proxy具有直接监听对象和数组变化、多种拦截方法以及新标准的性能优势等特点,而Object.defineProperty则兼容性好,支持IE9,并且无法用polyfill磨平浏览器兼容性问题。根据具体需求和浏览器兼容性考虑,选择合适的方式进行对象属性操作。 ... [详细]
  • Iamtryingtomakeaclassthatwillreadatextfileofnamesintoanarray,thenreturnthatarra ... [详细]
  • 向QTextEdit拖放文件的方法及实现步骤
    本文介绍了在使用QTextEdit时如何实现拖放文件的功能,包括相关的方法和实现步骤。通过重写dragEnterEvent和dropEvent函数,并结合QMimeData和QUrl等类,可以轻松实现向QTextEdit拖放文件的功能。详细的代码实现和说明可以参考本文提供的示例代码。 ... [详细]
  • IhaveconfiguredanactionforaremotenotificationwhenitarrivestomyiOsapp.Iwanttwodiff ... [详细]
  • 本文介绍了Redis的基础数据结构string的应用场景,并以面试的形式进行问答讲解,帮助读者更好地理解和应用Redis。同时,描述了一位面试者的心理状态和面试官的行为。 ... [详细]
  • Java容器中的compareto方法排序原理解析
    本文从源码解析Java容器中的compareto方法的排序原理,讲解了在使用数组存储数据时的限制以及存储效率的问题。同时提到了Redis的五大数据结构和list、set等知识点,回忆了作者大学时代的Java学习经历。文章以作者做的思维导图作为目录,展示了整个讲解过程。 ... [详细]
  • SpringBoot uri统一权限管理的实现方法及步骤详解
    本文详细介绍了SpringBoot中实现uri统一权限管理的方法,包括表结构定义、自动统计URI并自动删除脏数据、程序启动加载等步骤。通过该方法可以提高系统的安全性,实现对系统任意接口的权限拦截验证。 ... [详细]
  • 本文分享了一个关于在C#中使用异步代码的问题,作者在控制台中运行时代码正常工作,但在Windows窗体中却无法正常工作。作者尝试搜索局域网上的主机,但在窗体中计数器没有减少。文章提供了相关的代码和解决思路。 ... [详细]
  • 目录实现效果:实现环境实现方法一:基本思路主要代码JavaScript代码总结方法二主要代码总结方法三基本思路主要代码JavaScriptHTML总结实 ... [详细]
  • 阿,里,云,物,联网,net,core,客户端,czgl,aliiotclient, ... [详细]
  • 本文介绍了如何在给定的有序字符序列中插入新字符,并保持序列的有序性。通过示例代码演示了插入过程,以及插入后的字符序列。 ... [详细]
  • 1,关于死锁的理解死锁,我们可以简单的理解为是两个线程同时使用同一资源,两个线程又得不到相应的资源而造成永无相互等待的情况。 2,模拟死锁背景介绍:我们创建一个朋友 ... [详细]
  • 计算机存储系统的层次结构及其优势
    本文介绍了计算机存储系统的层次结构,包括高速缓存、主存储器和辅助存储器三个层次。通过分层存储数据可以提高程序的执行效率。计算机存储系统的层次结构将各种不同存储容量、存取速度和价格的存储器有机组合成整体,形成可寻址存储空间比主存储器空间大得多的存储整体。由于辅助存储器容量大、价格低,使得整体存储系统的平均价格降低。同时,高速缓存的存取速度可以和CPU的工作速度相匹配,进一步提高程序执行效率。 ... [详细]
author-avatar
hgo6786689
这个家伙很懒,什么也没留下!
PHP1.CN | 中国最专业的PHP中文社区 | DevBox开发工具箱 | json解析格式化 |PHP资讯 | PHP教程 | 数据库技术 | 服务器技术 | 前端开发技术 | PHP框架 | 开发工具 | 在线工具
Copyright © 1998 - 2020 PHP1.CN. All Rights Reserved | 京公网安备 11010802041100号 | 京ICP备19059560号-4 | PHP1.CN 第一PHP社区 版权所有