全文总计10500字(含代码),文字约6500字,预计阅读时间为20分钟,实践加练习约为45分钟
新增特性:严格模式
为代码提供了更加严格的审查机制吧一些容易出错的机制扼杀掉,后台增加更多的宝座体制--让程序员书写的代码更加可靠
看如下代码


在全局中使用的变量都默认的带有一个window

变量先声明再使用例如我故意写错一位没开启严格模式就是


他会自动定义不需要声明


就会产生报错,不声明就无法使用
矩形构造函数
静默失败:ES5之前 很多失败的情况下,让程序员无法定位错误
比如:
<script>
var emp={ename:'doudou',age:19}
// 冻结对象:可以防止内容被修改
Object.freeze(emp);
// 修改一下试试
emp.age=30;
// 显示结果
console.log(emp);
script>
打印结果去没有改变,又没有报错所以非常让人抓狂


就可以出现报错了

先来看一个示例
如下图:

理论上来说有些属性只能看不能改
但是现在能随意修改

我们先来看一下Object


JS中万物皆对象,函数也是一种特殊的构造函数
就像
var emp =new Object()
而{ }只是上面对象创建方式的一个语法糖
所以我们要配置对象的话就是要用到对象属性的defineProperty(定义)属性(prototype)
参数一:对象
参数二:属性名
参数三:具体配置项
Object.defineProperty(对象,'属性名',{具体配置})

所以我们添加上对象后就是

添加之后我们发现是不能修改刚才定义的数据的

添加上严格模式可能更明确:如图

就会报错提示:这个数据是锁定的
秋山在玩王者荣耀的时候要求人脸识别所以完成实名认证后获得了信息所以要获取一下
<script>
var emp = {
name: "qiushan",
age: 21,
sex: "0",
Id_car: "430772xxxxxxxxxxxx0910",
phone: "130xxxx5607",
};
for(var key in emp){
console.log(key,emp[key]);
}
script>
获取了信息之后要遍历一下我们只需要基本信息,其他的不让遍历
所以我们要禁止获取身份证和手机号,就可以这样写:
<script>
var emp = {
name: "qiushan",
age: 21,
sex: "0",
Id_car: "430772xxxxxxxxxxxx0910",
phone: "130xxxx5607",
};
Object.defineProperty(emp,'Id_car',{
enumerable: false,
// 是否可遍历/枚举:否
})
for(var key in emp){
console.log(key,emp[key]);
}
script>
注意:虽然遍历/枚举不可获取数据但是还是能正常读出来的


所以这就可用于从服务器拿到了数据,这些数据是要循环遍历的,然而又写选项在没有达到某些条件之前不会显示,或者后端接口少的情况下,条数据包含多条不相关的数据等用来屏蔽遍历插入等
上面说了,属性对的配置,但是上面和之前说的方法只能,一下配置一条所以我们接下来聊聊一线配置多条属性
格式:
Object.defineProperties(数组/对象,{
属性名:{配置项目}
})
某公司的后台OA系统从数据库获取的数据如下
var emp = {
ename:"ashan",
salary:14000,
phone:'153xxxx0192',
eid:21
}
要求:
phone和eid不能改
salary和eid不能遍历
接下来就需要使用:enumerable(无法枚举遍历)和writable(无法更改)
所以代码为:
<script>
var emp = {
ename: "ashan",
salary: 14000,
phone: "153xxxx0192",
eid: 21,
};
// 希望:phone和eid不能改
// salary和eid不能遍历
Object.defineProperties(emp, {
// 属性名:{配置项目}
phone: {
writable: false,
},
eid: {
writable: false,
enumerable: false,
},
salary: {
enumerable: false,
},
});
script>
接下来我们测试一下吧

结果;

有的时候在日常开发中,大多都是多人协作,两个程序员之间可能会出现的情节如下
<script>
// 开启严格模式
'use strict';
// 由于是多人协作
// ------>下面是阿山的同事写的<--------
// 创建用户信息
var emp={
ename:"shanhai",
age:"28"
}
// 配置年龄不可被修改
Object.defineProperty(emp,'age',{
// 不可修改
writable:false,
})
// ------>下面是阿山写的<--------
Object.defineProperty(emp,'age',{
writable:true
});
emp.age=67
console.log(emp);
script>

这数据不久被重写了嘛,但是这样可能会影响到后续的开发,所以需要控制是否能重写
<script>
// 开启严格模式
'use strict';
// ------>下面是阿山写的<--------
// 创建用户信息
var emp={
ename:"shanhai",
age:"28"
}
// 配置年龄不可被修改
Object.defineProperty(emp,'age',{
// 不可修改
writable:false,
// 控制是否能重写配置
configurable:false,
// 不可重写配置
})
// ------>下面是阿山的同事写的<--------
Object.defineProperty(emp,'age',{
writable:true
});
emp.age=67
console.log(emp);
script>
现在我们就可以看到无法修改了

举例:qq空间的多人协作

简单来说就是允许插入的方式和拒绝某种方式的插入
比如:
var emp={}
创建一个对象后插入数据的方式有很多种
如:
emp.ename='阿山'
//点语法
emp['phone']='10086'
// 方括号语法
例如:让emp下面的手机号无法被修改等
Object.defineProperty(emp, 'phone', {
writable: true,
});
不允许`某种方式插入就为writable的值就为false反之则为true
看示例:计算矩形面积的函数
<script>
// 矩形的对象
var r1={
length:10,
height:5,
area:function(){
return this.length*this.height
}
}
console.log(r1.area());
script>
调用结果:

作者提供的一些简化语法,让程序员书写代码增加幸福感 – 像吃糖一样
语法糖的宗旨:省略复杂的固定的代码
比如:上面的代码简化
area:function(){
return this.length*this.height
}
可以用语法糖写为
area(){
return this.length*this.height
}
能让无参数传参的回调函数去括号
函数的括号作用是调用,如果有实参则可以传参,但是为了方便,作者提供了get关键字,不传参的回调函数可以在前面加上get来实现不用小括号调用函数

改写之后功能是正常的

但是要传参的回调函数添加get就没办法用了,用了的话你就是个大聪明,第一编辑器会报错其次,你怎么传参呢?

报错

get:计算属性
之前我们说过了get使用了的话可以简化很多的操作
下面我们来对比一下
<script>
// 不使用语法糖
var r2 = { width: 10, length: 20 };
Object.defineProperty(r2,"area",{
value(){
return this.width*this.length
}
});
console.log(r2.area());
// 使用get
// 计算属性:使用时不用加小括号
Object.defineProperty(r2,"area2",{
get (){
return this.width*this.length
}
})
console.log(r2.area2);
script>
body>
接下来我们在控制台里面看一下区别
我们发现get调用的属性默认显示三个点

悬停显示的调用属性,当点击之后直接就算出参数了而之前没使用get属性的值却显示为回调函数

<script>
// 计算半径
// 计算周长
var r1={
width:100,
height:50
}
Object.defineProperties(r1,{
area:{
get(){
return this.width*this.height*3.14
}
},
zc:{
get(){
return 2*this.width*2
}
}
});
console.log(r1);
script>
首先我们来先看一个demo
假设我们接到了一个用户修改信息的前端页面简化的js代码如下
<script>
var emps={
emane:"sahn",
age:123
}
// 逻辑错误:年龄的值不可能为200岁
emps.age=200
console.log(emps);
script>
我们可以看到上面的示例中明显有个逻辑性的错误
所以我们现在不能随便往里面改,我们要检测一下,否则甲方可能会找麻烦
所以我们可以使用set属性
set : 设置 当调用这个参数(给与set赋值)的时候,也就是使用这个方法(回调函数…)就会调用下面的方法如下图

如下图简单来说相当于下面的结构
下图上面的是没使用set下面的是使用了set的

所以我们可以写为:
<script>
var emps = {
emane: "sahn",
age: 123,
};
Object.defineProperty(emps, "age", {
//set:设置 检测赋值的操作
set: function (value) {
// value 就是传入的值
if ((value) > 1 && value <= 100) {
console.log('写入了:',value);
} else {
console.log("传入值错误")
}
},
});
emps.age = 200;
emps.age = 10;
emps.age = 70;
script>
这时我们发现可以了但是打印的时候却变成了undefinde

存储数据(创建一个新的值)**// 由于是专门配合age使用的所以我们习惯添加下划线前缀
Object.defineProperty(emps,'_age',{
// 用define属性添加的属性默认是不可写入的所以要改为写入
writable:true
});
创建完毕后把数据转存作为中转过来

但是我要读取这个数据不能去读_age吧

所以我们的代码可以这样写
<script>
var emps = {
emane: "sahn",
age: 123,
};
// 由于age被修改为检查站,只能具备检测功能,不具备存储数据功能
// 所以必须提供一个额外的属性来存储数据
// 由于是专门配合age使用的所以我们习惯添加下划线前缀
Object.defineProperty(emps,'_age',{
// 用define属性添加的属性默认是不可写入的所以要改为写入
writable:true
});
Object.defineProperty(emps, "age", {
//set:设置 检测赋值的操作
get(){
return this._age
},
set: function (value) {
// value 就是传入的值
if ((value) > 1 && value <= 100) {
console.log('写入了:',value);
this._age=value
} else {
console.log("传入值错误")
}
},
});
// 读取数据
emps.age = 200;
emps.age = 10;
emps.age = 70;
console.log(emps.age);
script>
核心点在于

接下来可以尝试完成下面的练习题
练习1:
DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<meta http-equiv="X-UA-Compatible" content="IE=edge" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>Documenttitle>
head>
<body>
<script>
var emp = {
ename: "ashan",
salary: 13000,
};
Object.defineProperties(emp, {
// ?a
});
// 要求工资合法范围为1000-30000员
emp.salary = 40000;
// 报错薪资不合法
emp.salary = 15000;
// 正常工资
console.log(emp);
console.log(emp.salary);
script>
body>
html>

DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Documenttitle>
head>
<body>
<script>
var emp={
ename:'qiushan',
height:176
}
Object.defineProperties(emp,{
// ?
})
// 身高范围100-200
emp.height=300;
emp.height=180
console.log(emp);
console.log(emp.height);
script>
body>
html>

案例答案如下(不需要付费下载):案例下载

之前讲解的精准属性配置:可以对 对象中的每个属性进行配置
对象的操作有四种:增删改查
所以保护对象的方式就是阻止代码的增删改,但是如果不能查了,代码也就失去意义了
// 阻止新增属性
// preventExt 阻止
// ensions 扩展
// 不允许增
Object.preventExtensions(emp);
// 给秋山添加一个女朋友
emp.grilFriend = "山海";
// 不允许增删:只能读
// seal: 密封
Object.seal(emp);
// 删除
delete emp.salary;
// 不允许增删改
// freeze:冻结
Object.freeze(emp);
// 这样就只能读取了