JavaScript ES5 对象方法

ES5

  1. 严格模式
    • 概念:比普通js运行机制要求更严格的新运行机制

    • 启用严格模式:在当前作用域的顶部:"use strict"

    • 新要求:
      (1)禁止给为声明过的变量赋值
      (2)静默失败升级为错误:旧js中,执行不成功但不报错,在严格模式下,会报错
      (3)普通函数调用中的this不再指向window,而是指向undefined
      若函数调用时,前边既没有.也没有new,则函数中的this改为指向undefined
      (4)禁用了arguments.callee
      概念:arguments.callee:在调用函数时,函数内部自动获取当前函数本身的关键词
      原因:arguments.callee解决了递归调用中的紧耦合问题,但因为递归算法本身存在大量重复的计算,效率极低,所以arguments.callee被禁用。
      解决:绝大多数的递归都使用循环来代替

使用arguments.callee实现斐波那契数列

<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="UTF-8">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <title>Document</title>
</head>
<body>
  <script>
    "use strict";
    
    //斐波那契数列:
    //1 1 2 3 5 8 13 21 34 55
    //1 2 3 4 5 6 7  8  9  10
    //前两个数都是1
    //从第三个数开始: 每个数都是相邻的前两个数的和
    //定义函数,计算出数列中第n个数是几?
    function fib(n){
      //如果n<3,直接返回1
      if(n<3){
        return 1
      }else{//从第三个数开始: 每个数都是相邻的前两个数的和
        //n位置的数=n-1位置的数+n-2位置的数
        //所以,想算出fib(n),必须先算出fib(n-1)和fib(n-2)
        return arguments.callee(n-1)+arguments.callee(n-2)
      }
    }
    console.log(fib(10))//55
  </script>
</body>
</html>
运行结果:
Uncaught TypeError: 'caller', 'callee', and 'arguments' properties may not be accessed on strict mode functions or the arguments objects for calls to them
    at fib (7_use_strict4.html:25)
    at 7_use_strict4.html:28

因为禁用arguments.callee所以报错

  1. 保护对象
    专门保护对象的属性和结构的机制

    • 保护属性
      (1)每个属性底层都是一个缩微的对象
      (2)获得属性底层的对象结构:var 变量名 = Object.getOwnPropertyDescriptor(对象名,"属性名")
      举例:获取eric对象
var eric={
    name:"ysx",
    age:25,
    hobby:"演戏"
}

var eric = Object.getOwnPropertyDescriptor(eric,"name");
console.log(eric);

在这里插入图片描述
(3)修改一个属性中的开关Object.defineProperty(对象名,"属性名",{开关名:true/false, ... : ... , })
属性底层结构放大:

name:{
	value:"ysx",//替当前属性保存属性值
	writeable:true,//控制是否可以修改当前属性值
	enumberable:true,//控制是否可用for遍历当前这个属性值,只防for,不防.
	configurable:true//控制是否可以删除当前属性,控制是否可以修改前两个开关
}

举例:修改属性中开关的状态进行测试

"use strict";

var eric={
    name:"ysx",
    age:25,
    hobby:"演戏"
}

var ericName = Object.getOwnPropertyDescriptor(eric,"name");
console.log(ericName);

Object.defineProperty(eric,"age",{
    writable:false
})
//修改了name属性为不可修改

//尝试修改name属性
eric.age = -1;

console.log(eric);
console.log(eric.age)

在严格模式下,会报错 静默升级
在这里插入图片描述
在非严格模式下:不会改变属性值
在这里插入图片描述
再打印当前的属性开关情况
var ericAge = Object.getOwnPropertyDescriptor(eric,"age"); console.log(ericAge);
在这里插入图片描述
(4)修改多个属性的开关
Object.defineProperties(对象名,{属性名:{开关名:true/false, ... : ... },属性名:{... : ... }})

  • 访问器属性(用自定义规则保护属性)
    自己不保存属性值,而是仅提供对另一个数据属性的保护
    (1)定义访问器属性
    举例:使用访问器属性保护员工年龄介于18~50之间
<!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>Document</title>
</head>
<body>
    <script>
        
var eric={
	ename:"埃里克",
	eage:25
}
//开始保护多个属性
Object.defineProperties(eric,{
	//创建_eage属性,将eage属性中的值转移,并隐藏_eage
	_eage:{
		value:eric.eage,
		writable:true,
		enumberale:false,
		configurable:false
	},
	//将原属性变成一个 访问器属性  作为真正属性的保镖
	eage:{
		//2个保镖,一个从_eage中读取数据返给外部,一个接收外部的数据进行判断
		//当set保镖,判断完毕,符合条件,返给_eage,不符合条件,报错

		//get保镖
		get:function(){
			return this._eage;
		},
		//get结束
		
		//set保镖
		set:function(value){
			if(value>=18 && value<=50){
				this._eage = value;
			}else{
				throw error("年龄out");
			}
		},
		//set结束
		enumberable:true,
		configurable:false
	}
})
console.log(eric);

//尝试修改eage的值
// eric.eage = 20;
console.log(eric.eage);
    </script>
</body>
</html>

在这里插入图片描述
在这里插入图片描述

  • 保护结构
    阻止用户向对象添加新属性或删除现有属性
    ES5提供了专门保护对象的办法:3个级别
    (1)防扩展 – 禁止当前对象强行添加新属性Object.preventExtensions(对象名)
    (2)密封 – 既禁止对象添加属性,又禁止删除现有属性Object.seal(对象名)
    1). 自动调用了preventExtentsions()
    2). 自动修改了每个属性的configurable为false
    (3)冻结 – 禁止删除属性,禁止修改属性,禁止添加属性
    1).自动调用了preventExtentsions()
    2).自动修改了每个属性的configurable为false
    3).自动修改每个属性的writable属性为false
  1. Object.create
    (1)在没有构造函数的情况下,也想创建子对象,继承指定的父对象,用Object.create()
    (2)var 子对象 = Object.create(父对象,{属性名:{开关名:true/false}}//添加属性)

  2. 替换this
    当函数中的this不是我们想要的时,替换this

(1)call() – 临时替换this
函数用来封装了方法,当有不同的对象重复使用方法时,临时替换this
call()内的第一个实参替换this
举例:2个员工使用同一个函数计算工资

function suan(base,reward1,reward2){
	let sum = base + reward1 + reward2;
	console.log(`${this.ename}的总工资为: ${sum}`);
}

var xiaoming = {ename:"Xiaoming"};
var Hanme = {ename:"Hanmei"};

//员工分别计算自己的工资
suan.call(xiaoming,5000,200,300);

在这里插入图片描述
(2)apply() – 当传参数较多,且为以数组传递时
apply()内的第一个实参替换this
举例:将员工的底薪,存在数组中,计算员工总工资

function suan(base,reward1,reward2){
	sum = base+reward1+reward2;
	console.log(`${this.ename}的总工资为:${sum}`);
}
var Hanmei = {ename:"Hanmei"};
var arr = [5000,600,630];

suan.apply(Hanmei,arr);

在这里插入图片描述
原理:
在这里插入图片描述

(3)函数副本
为对象创建一个专属的函数副本,并永久绑定this和部分实参值

var 函数副本 = 原函数.bind(替换的this对象,部分固定的实参值)

举例:为韩梅创建一个专属的jisuan()函数,并永久绑定this和底薪

function jisuan(base,reward1,reward2){
	sum = base+reward1+reward2;
	console.log(`${this.ename}的总工资是:${sum}`);
}
var Hanmeimei = {ename:"Hanmei"};
var Han = jisuan.bind(Hanmeimei,5000);

Han(500,600);

在这里插入图片描述
当反复使用一个函数,并永久替换this时,用bind()

  1. 数组函数(4类6个) —— 都自带for循环
    判断(2个) 遍历(2个) 过滤(1个) 汇总(1个)

(1)判断数组函数 —— 返回的结果是true/false
1)every() —— 判断数组中是否所有元素都符合要求

var bool=arr.every(function(elem,i,arr){
	return 判断条件
})

elem:当前正在遍历的元素
i:当前遍历到的位置
arr:当前正在遍历的数组

当返回false则不再遍历,表示当前数组不是所有元素都符合条件
遍历到最后返回true,表示当前数组所有元素都符合条件

2)some() —— 判断数组中是否包含符合要求的元素

var bool = arr.some(function(elem,i,arr){
	return 判断条件;
});

当遇到一个符合要求的元素,即返回true,不再循环
当循环到最后,返回false,则表明该数组内没有符合条件的元素

(2)遍历数组函数 —— 返回的是遍历结果
1)forEach() —— 遍历数组中每个元素值,执行相同的操作

arr.forEach(function(elem,i,arr){
	对当前元素值执行操作
});

举例:喊到

arr=["小A","小B","小C","小D"];
arr.forEach((elem,i,arr)=>{console.log(`${elem}到!`)})

在这里插入图片描述
2)map() —— 依次取出原数组的每个元素值,执行相同操作后,放入新数组返回

var 新数组 = arr.map(function(elem,i,arr){
	return 根据当前元素值加工后的一个新值
}); 

举例:取出原数组的值加10再返回新数组

var arr1 = [1,2,3,4,5];
var arr2 = arr1.map((elem,i,arr1)=>{
	return elem += 10;
});
console.log(arr2);

在这里插入图片描述
(3)过滤数组函数 —— 仅复制出原数组中符合条件的元素值,放入新数组返回

var 新数组 = arr.filter(function(elem,i,arr){
	return 判断条件;
});

举例:从数组中取出所有偶数

var arr1 = [1,2,3,4,5,6];
var arr2 = arr1.filter((elem,i,arr1)=>{
	return elem%2 == 0;
});
console.log(arr2);

在这里插入图片描述
注意:filter()后,原数组保持不变~

(4)reduce() —— 对原数组中的每个元素值进行统计,最终得出一个统计结果

var 结果 = arr.reduce(function(box,elem,i,arr){
	return box+elem;
},起始值);

box:临时汇总值
类似捐款箱,box的值是捐款箱里就有的钱

举例:统计一个数组中所有元素值的和

var arr1 = [10,20,30,40];
var total = arr1.reduce(function(box,elem,i,arr1){
	return box+elem
},500);
console.log(total);

在这里插入图片描述

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值