【面试必备】 【ES6】学Vue前必须掌握的内容(上)
变量声明
- 采用 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); -> 1
console.log(arr); -> ['a', 'b']
console.log(arr[0]); -> a
console.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 <=> a== null ? undefined : a.b //三元运算符:条件?满足的:不满足的
a?.[x] <=> a==null ? undefined : a[x]
a?.b() <=> a==null ? undefined : a.b() //如果是不满足的情况下且a.b不是函数不可调用就报错
a?.() <=> a==null ? undefined : a() //如果是不满足的情况下且a不是函数就报错
⑤ 字符串扩展:
模板字符串
字符串${变量}字符串
其他扩展
includes(str)
:判断是否包含指定的字符串startsWith(str)
:判断是否以指定字符串开头endsWith(str)
:判断是否以指定字符串结尾repeat(count)
:重复指定的次数
⑥ Number扩展:
- 八进制0o表示,二进制0b;
Number.isFinite(n)
:判断是否为有限大的数。比如Infinity
这种无穷大的数,返回的就是 false。Number.isNaN(n)
:判断是否为 NaN。Number.isInteger(n)
:判断是否为整数。Number.parseInt(str)
:将字符串转换为对应的数值。Math.trunc(n)
:去除小数部分。
总结给大家推荐一个实用面试题库
1、前端后端面试题库 (面试必备) 推荐:★★★★★
地址:前端面试题库
2、前端技术导航大全 推荐:★★★★★
地址:前端技术导航大全
3、开发者颜色值转换工具 推荐:★★★★★
地址 :开发者颜色值转换工具
【面试必备】 【ES6】学Vue前必须掌握的内容(上)的更多相关文章
- 大厂HR面试必备ES6中的深入浅出面试题知识点
ESMAScript6简介,ES6是JavaScript语言的下一代标准,目的是让JavaScript语言可以写复杂的大型应用程序,成为企业级语言.那么ECMAScript和JavaScript的关系 ...
- 如何封装$on,$emit,$off——学vue前你必须懂得封装!
let evevtListenr = {} 封装$on const $on = (eventName,cb)=>{ if(!evevtListenr[eventName]){ ...
- AI面试必备/深度学习100问1-50题答案解析
AI面试必备/深度学习100问1-50题答案解析 2018年09月04日 15:42:07 刀客123 阅读数 2020更多 分类专栏: 机器学习 转载:https://blog.csdn.net ...
- Java面试必备知识
JAVA面试必备知识 第一,谈谈final, finally, finalize的区别. 第二,Anonymous Inner Class (匿名内部类) 是否可以extends(继承)其它类,是否可 ...
- Python自动化面试必备 之 你真明白装饰器么?
Python自动化面试必备 之 你真明白装饰器么? 装饰器是程序开发中经常会用到的一个功能,用好了装饰器,开发效率如虎添翼,所以这也是Python面试中必问的问题,但对于好多小白来讲,这个功能 有点绕 ...
- 为什么43%前端开发者想学Vue.js
根据JavaScript 2017前端库状况调查 Vue.js是开发者最想学的前端库.我在这里说明一下我为什么认为这也是和你一起通过使用Vue构建一个简单的App应用程序的原因. 我最近曾与Evan ...
- 一起学Vue之计算属性和侦听器
概述 在Vue开发中,模板内的表达式非常便利,但是设计它们的初衷是用于简单运算的.在模板中放入太多的逻辑会让模板过重且难以维护.当你想要在模板中多次引用相同表达式时,就会更加难以处理.所以,对于任何复 ...
- 面试必备的10道MySQL题
MySQL 事务,是我们去面试中高级开发经常会被问到的问题,很多人虽然经常使用 MySQL,SQL 语句也写得很溜,但是面试的时候,被问到这些问题,总是不知从何说起.下面我们先来了解一下什么是 MyS ...
- Java常用英语汇总(面试必备)
Java常用英语汇总(面试必备) abstract (关键字) 抽象 ['.bstr.kt] access vt.访问,存 ...
- [Vue源码]一起来学Vue模板编译原理(一)-Template生成AST
本文我们一起通过学习Vue模板编译原理(一)-Template生成AST来分析Vue源码.预计接下来会围绕Vue源码来整理一些文章,如下. 一起来学Vue双向绑定原理-数据劫持和发布订阅 一起来学Vu ...
随机推荐
- 学习ASP.NET Core Blazor编程系列二十——文件上传(完)
学习ASP.NET Core Blazor编程系列文章之目录 学习ASP.NET Core Blazor编程系列一--综述 学习ASP.NET Core Blazor编程系列二--第一个Blazor应 ...
- Socket爬虫:Python版
简述:较为底层的爬虫实现,用于了解爬虫底层实现的具体流程,现在各种好用的爬虫库(如requests,httpx...等)都是基于此进行封装的. PS:本文只作为实现请求的代码记录,基础部分不做过多阐述 ...
- Linux c 检测U盘挂载路径方法
思路: 1.使用df -h |grep mnt shell 命令查找到挂载路径信息 本代码是将结果存入文件中,再从文件中解析出路径信息.也可使用fopen直接从管道中读取信息 2.解析出信息最后的/m ...
- 一类(One-Class)分类器
本文摘自博客和论文,参考文献请看文末. 一类分类技术概念 与传统的分类技术不同,一类分类技术仅采用隶属于一个类别的样本来训练分类器,其通常被用于某种极端场景,即训练样本仅包含正常样本,而异常样本不可得 ...
- Pytorch:单卡多进程并行训练
1 导引 我们在博客<Python:多进程并行编程与进程池>中介绍了如何使用Python的multiprocessing模块进行并行编程.不过在深度学习的项目中,我们进行单机多进程编程时一 ...
- 痞子衡单片机排行榜(2022Q4)
痞子衡单片机排行榜(2022Q4) 继2020年开办的<痞子衡嵌入式半月刊>之后,从2023年1月份开始痞子衡将为大家带来新项目<痞子衡单片机排行榜>(一年分四季,每个季度发布 ...
- BIGO 如何做到夜间同时运行 2.4K 个工作流实例?
点亮 ️ Star · 照亮开源之路 GitHub:https://github.com/apache/dolphinscheduler 精彩回顾 近期,BIGO 的大数据研发工程师许名勇在社 ...
- Linux xsync命令脚本
功能:在主机上分发文件到其他机器 在主机machine136上进行如下操作(master) 1.安装 rsync yum install -y rsync 2.bin下创建 xsync 转自:(82条 ...
- 学习Java Day11
今天学习了二维数组:
- java2022.7.9
知识点