JavaScript - day21

23 阅读2分钟

一、保护对象

保护对象的属性和方法

1.1 四大特性(不能防止添加)

var zs = {
            "id" : 1001,
            "name" : '张三',
            "salary" : 5000
        }
        console.log(Object.getOwnPropertyDescriptor(zs,"id"));
        //{value: 1001, writable: true, enumerable: true, configurable: true}
  • value: 1001 实际保存值的地方
  • writable: true 控制着是否可以被修改 - 默认值:都为true
  • enumerable: true 控制着是否可以被for in循环遍历到 - 默认值:都为true
  • configurable: true 控制着是否可以被删除 - 默认值:都为true,总开关:一旦设置为false,其他特性不可以在修改,而且它本身也是一旦设置为false,不可逆

1.2 修改四大特性

Object.defineProperty(对象名,"属性名",{
        修改四大特性//调用一次方法只能保护一个属性的四大特性
})
Object.defineProperties(对象名,{
        "属性名":{修改四大特性},
        ...
})
<script>
    // 保护对象的四大特性
    var zs = {
        "id" : 1001,
        "name" : '张三',
        "salary" : 5000
    }
    console.log(Object.getOwnPropertyDescriptor(zs,"id"));//{value: 1001, writable: true, enumerable: true, configurable: true}
    Object.defineProperty(zs,"id",{
        writable : false,//不能修改
        configurable : false//不能删除
    })
    Object.defineProperty(zs,"name",{
        configurable : false//不能删除
    })
    Object.defineProperty(zs,"salary",{
        enumerable : false,//不能被for in遍历
        configurable : false//不能删除
    })

    zs.id = 1002
    console.log(zs);//id : 1001
    delete zs.id
    console.log(zs);//删除不了了
    for (var i in zs) {
        console.log(zs[i]);//遍历不到salary
    }

    Object.defineProperties(zs,{
        "id" : {
            writable : false,//不能修改
            configurable : false//不能删除
        },
        "name" : {
            configurable : false
        }
    })
</script>

1.3 三个级别

  • 防扩展:防止添加 Object.preventExtensions(obj);
  • 密封:防止添加和删除 Object.seal(obj);
  • 冻结:防止添加和删除和修改 Object.freeze(obj);
<script>
    // 保护对象的三个级别
    var zs = {
        "id" : 1001,
        "name" : '张三',
        "salary" : 5000
    }
    // 防扩展:防止添加
    /* Object.preventExtensions(zs)
    zs.age = 18
    console.log(zs);//{id: 1001, name: '张三', salary: 5000} */

    // 密封:防止添加和删除
    /* Object.seal(zs)
    zs.age = 18
    delete zs.id
    console.log(zs);//{id: 1001, name: '张三', salary: 5000} */

    // 冻结:防止添加删除修改
    Object.freeze(zs)
    zs.age = 18
    delete zs.id
    zs.salary = 6000
    console.log(zs);//{id: 1001, name: '张三', salary: 5000}
</script>

1.4 动态数据

<div id="div"></div>
<script>
    // 做出动态数据
    var zs = {
        "name" : "张三"
    }
    div.innerHTML = zs.name
    Object.defineProperty(zs,"name",{
        get : () => {
            console.log('获取数据会进行拦截');
        },
        set : v => {
            console.log('设置数据会进行拦截');
            div.innerHTML = v//v是拦截到的新数据
        }
    })
    zs.name = 'lily'//页面也会变成lily
</script>

二、深浅拷贝

2.1 数组的深浅拷贝

<script>
    // 数组的深浅拷贝
    var arr = [1,2,3,4,5]
    // 浅拷贝
    var arr1 = arr;
    console.log(arr);//[1, 2, 3, 4, 5]
    console.log(arr1);//[1, 2, 3, 4, 5]
    arr1.length--
    console.log(arr);//[1, 2, 3, 4]
    console.log(arr1);//[1, 2, 3, 4]
    // 深拷贝
    var arr2 = arr.slice()
    // var arr2 = [...arr]//...是去掉数组的[]
    console.log(arr);//[1, 2, 3, 4]
    console.log(arr2);//[1, 2, 3, 4]
    arr2.length--
    console.log(arr);//[1, 2, 3, 4]
    console.log(arr2);//[1, 2, 3]
</script>

2.2 对象的深浅拷贝

<script>
    // 对象的深浅拷贝
    var zs = {
        "name" : "张三"
    }
    // 浅拷贝
    var zs1 = zs
    console.log(zs);//{name: '张三'}
    console.log(zs1);//{name: '张三'}
    zs1.name = '张三1'
    console.log(zs);//{name: '张三1'}
    console.log(zs1);//{name: '张三1'}

    // 深拷贝
    // var zs2 = {...zs}//...是去掉对象的{}
    var zs2 = JSON.parse(JSON.stringify(zs))//JSON.stringify()是加上{},JSON.parse()是去掉()
    console.log(zs);//{name: '张三1'}
    console.log(zs2);//{name: '张三1'}
    zs2.name = '张三2'
    console.log(zs);//{name: '张三1'}
    console.log(zs2);//{name: '张三2'}
</script>

三、Error对象:错误

4.1 浏览器自带4种错误类型

  • 语法错误:SyntaxError - 一定是你的符号写错了
  • 引用错误:ReferenceError - 没有创建就去使用了
  • 类型错误:TypeError - 不是你的方法,你却去使用了
  • 范围错误:RangeError - 只有一个API会碰到:num.toFixed(d);//d取值范围:0~100之间

4.2 错误处理

语法:

try{
       只放入你可能出错的代码
}catch(err){
       发生错误后才会执行的代码
       alert(err);//err就是我们的错误提示:只不过是英文的
       alert("中文的错误提示,来提示用户");
}
  • try...catch...的性能非常差,几乎是所有代码里最差的,放在try中的代码效率会被降到最低
  • 可以用一个技术代替他:分支结构
<script>
   // 错误处理
   var num = parseFloat(prompt('请输入一个数字:'));
   var d = parseInt(prompt('请输入要保留的小数位数'));
   // 方法一 try...catch...
   /* try {
       console.log(num.toFixed(d));
   } catch (err) {
       console.log(err);
       console.log('小数位数必须为0-100');
   } */
   // 方法二  分支语句
   if (d >= 0 && d <= 100) {
       console.log(num.toFixed(d));
   } else {
       console.log('小数位数必须为0-100');
   }
   console.log('后续代码');
</script>

4.3 抛出自定义错误

throw new Error("自定义错误消息");

4.4 ES5:严格模式

  • 开启:"use strict"; - 写在任何一个作用域的顶部都可以
<script>
   /* a = 1;
   console.log(a);//a */
   "use strict"
   a = 1;
   console.log(a);//Uncaught ReferenceError: a is not defined
</script>
  • 作用:
    1. 禁止了全局污染,使用变量之前必须先创建变量
    2. 将静默失败升级为了错误

四、柯里化函数

function add(a){
       return function(b){
               return function(c){
                       console.log(a+b+c);
               }
       }
}
add(3)(5)(7);//15