ES5
1.严格模式
1.定义:比传统js运行机制要求更严格的模式
2.语法
1.在整个js文件或script标签内启用严格模式
在js文件或script标签内第一行: "use strict" // 新项目都要用严格模式
2.仅在单个函数内启用严格模式
在函数内的第一行:"use strict" // 旧项目改造时,要逐个功能向严格模式迁移
3.要求
1. 禁止给未声明的变量赋值:
2. 将静默失败升级为错误:
静默失败: 即修改不成功,又不报错!
3. 不建议使用arguments, arguments.callee(调用当前函数名)
4. 普通函数调用和匿名函数自调中的this不再指向window!而是undefined
2.对象的保护
1.保护属性
1.数据属性
1.定义:直接存储属性值的属性
2.保护方法:每个数据属性不再是一个简单的变量,而是一个拥有四大特定的小对象
3.查看一个属性的四大特性
Object.getOwnPropertyDescriptor(obj,"属性名")
返回值:{
value: 实际存储属性值,
writable: true/false, 控制只读
enumerable: true/false, 控制能否被for in遍历到,但是,用.依然可以访问到!
configurable: true/false, 控制:
控制能否删除该属性和修改其他特性,一旦该为false,不可逆!
}
4.修改四大特性保护数据属性:
Object.defineProperty(obj,"属性名",{
要修改的特性:值,
... : ...,
})
问题: 一次只能修改一个属性的四大特性
解决: 同时修改多个属性的四大特性:
Object.defineProperties(obj, {
属性名:{
四大特性:值,
... : ...
},
属性名:{
四大特性:值,
... : ...
},
...
})
注意:如果要修改的属性不存在,则自动创建, 自动创建的属性,四大特性默认值都为false
问题:只能用固定的三种特性保护属性,无法用自定义规则灵活保护属性了
练习:创建一个对象,并对对象中的属性进行修改
var eric = { id: 1001,//只读 ename: "Eric",//禁止删除 salary: 12000//禁止遍历 } //设置id只读 //设置ename禁止删除 //设置salary禁止遍历,双保险 Object.defineProperties(eric, { id: { writable: false, configurable: false }, ename: { configurable: false }, salary: { enumerable: false, configurable: false } }); //获得一个属性的四大特性: var id_attrs = Object.getOwnPropertyDescriptor(eric, "id"); console.log(id_attrs);
2.访问器属性
1.定义:不直接存储属性值,仅提供对其它数据属性的保护
2.创建:
1. 定义隐藏的数据属性,起别名,实际存储数据
问题: 使用enumerable隐藏的属性,防for in,但防不住. 别人可用eric._age绕过访问器属性,直接篡改受保护的属性。
解决: 使用局部变量,代替隐藏的数据属性!
2.定义访问器属性,从受保护的数据属性中读取或修改数据
Object.defineProperties(eric,{
age:{//访问器属性
get(){return _age},
set(val){
if(val>=18&&val<=65)
_age=val;
else
throw new RangeError("年龄必须介于18~65之间");
},
enumberable:true,
configurable:true
},
})
3.使用:访问器属性的用法和普通属性完全一样!
只不过: 在试图获取属性值时,自动调用get,在试图修改属性值时,自动调用set
参数val自动获得等号右边的新值
内部属性: 不能用.访问的属性: class _ _proto_ _
2.防篡改(保护结构)
1. 防扩展: 禁止向对象中添加新属性:
语法: Object.preventExtensions(obj)
原理: 每个对象内都有一个隐藏的内部属性extensible
默认true
preventExtensions将extensible改为false
2. 密封: 即禁止扩展,又禁止删除!
语法: Object.seal(obj)
原理: 即修改对象的extensible为false
又自动修改每个属性的configurable为false!
3. Object.create()
定义: 仅基于一个现有父对象,创建他的子对象,并为子对象扩展新的自有属性
使用场合: 今后,如果只基于父对象,也想创建子对象时
语法: var child=Object.create(father,{//Object.defineProperties
属性名:{四大特性}
... : ...
});
4.call/apply/bind
相同:如果函数中的this不是想要的,都可替换
不同:
call/apply: 强行调用一个函数,并临时替换函数中的this为指定对象
call: 要求传入函数的参数必须单独传入
apply: 要求传入函数的参数必须放在数组中整体传入
apply可先打散数组参数为单个元素,再传参
bind: 基于一个现有函数,创建一个一模一样的新函数,并永久绑定this为指定对象
总结: 如果是临时调用一个函数,用call/apply
如果"创建"一个新函数,永久绑定this时
所有回调函数中的this,要想替换都用bind
因为回调函数不是立刻执行,且不止执行一次!
3.数组API
1.判断
every(): 判断数组中是否所有元素*都*符合要求
some(): 判断数组中是否包含符合要求的元素
语法: 仅以every()
var bool=arr.every(function(elem,i,arr){
//elem自动获得当前元素值
//i 自动获得当前位置
//arr 自动获得当前数组->this
return 针对当前元素执行的判断条件
})
执行过程: every会遍历每个元素,反复调用回调函数,只有所有函数调用都返回true,结果才返回true
练习:给定两个数组,分别判断两个数组是否全由偶数组成和判断数组是否为升序排列
var arr1 = [1, 2, 3, 4, 5];
var arr2 = [2, 4, 6, 4, 2];//练习8分钟
//判断哪个数组全由偶数组成:
console.log(
arr1.every(function (elem) {
return elem % 2 == 0;
}),//false
arr2.every(function (elem) {
return elem % 2 == 0;
})//true
);
//判断哪个数组是升序排列:
console.log(
arr1.every(function (elem, i, arr) {
return i < arr.length - 1 ? elem <= arr[i + 1] : true;
}),//true
arr2.every(function (elem, i, arr) {
return i < arr.length - 1 ? elem <= arr[i + 1] : true;
}) //false
);
2.遍历API:对数组中每个元素执行相同的操作
forEach(): 对原数组中每个元素执行相同操作
map(): 依次取出原数组中每个元素,执行相同操作后,放入新数组中返回。
语法:
arr.forEach(function(elem,i,arr){
arr[i]=新值;
});
arr.map(function(elem,i,arr){
return 新值;
}) //return的新值会放入新数组中相同位置
练习:创建一个数组,先将数组中的数组都乘2,再将原数组乘2存到一个新数组
var arr=[1,2,3,4,5]; //将原数组中的值都乘2 arr.forEach(function(elem,i,arr){ arr[i]=elem*2; }); console.log(arr); //将原数组乘2存到新数组中 var evens=arr.map(function(elem){ return elem*2; }); console.log(evens);
3.过滤和汇总
过滤: 选取出原数组中符合条件的元素,组成新数组返回
var subs=arr.filter(function(elem,i,arr){
return 判断条件
}); //如果当前判断为true,则放入新数组返回
汇总: 将数组中每个元素统计汇总出一个最终的结果
var result=arr.reduce(function(prev,elem,i,arr){
//prev: 截止目前的临时汇总值
return prev+elem;
},base)
以base值为基数,累加arr中每个元素值
练习:创建一个数组1,对数组1中的数字进行求和,再创建一个数组2,并对数组1和数组2加一块求和
var class1 = [2, 5, 3, 2, 5]; var sum = class1.reduce(function (prev, elem) { return prev + elem }); var class2 = [1, 3, 5, 2, 1]; sum = class2.reduce(function (prev, elem) { return prev + elem }, sum); console.log(sum);

浙公网安备 33010602011771号