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);

 

posted @ 2020-11-23 11:20  you_rgb  阅读(166)  评论(0)    收藏  举报
//一下两个链接最好自己保存下来,再上传到自己的博客园的“文件”选项中