Object 相关属性,方法
1.Object.create() 以对象为原型创建新对象
var o{
a:1,
b:2
}
var o1 = Object.create(o)//以o为原型创建o1
2.Object.assign 合并,浅复制对象,返回值是复制后的目标对象,注意只能复制对象属性,不能复制原型链属性,也不能复制不可枚举属性
例子:
var o={a:1};
var o1={b:2};
var o3={c:3};
var o4={d:4};
var o5=Object.assign(o,o1,o3,o4);
console.log(o===o5)//true
3.Object.defineProperty('对象','对象属性',{
}) 注意:用Object.defineProperty设置属性,不能重复定义这个属性,就只能定义一次,不写的话默认是false,所以这个属性只是个只读属性
如果不用Object.defineProperty,设置属性,用o.a=1;这样a属性的默认值是true,value是1
例子:
Object.defineProoerty('obj','b',{
configurable:true, //允许被删除
enumerable:true,//可枚举属性 ,不可枚举是不能暴露给别人,例如不能遍历
writable:true , //可修改属性
value:'5'
})//给obj对象添加了一个b属性
3.1 Object.defineProperties可以一次给对象定义多个属性
例如:
Object.defineProperties(o,{
b:{
enumerable:true,
configurable:true,
value:1
},
c:{
writable:true,
configurable:true,
value:2
}
})
3.2propertyIsEnumerable 判断对象的某个属性是否是可以枚举
Object.defineProperty(o2,"b",{
enumerable:false,
value:3
})
console.log(o2.propertyIsEnumerable("b"))//返回false
4.Object.getOwnPropertyDescriptor('对象名',属性):获取该对象下的这个属性的描述对象
var desc=Object.getOwnPropertyDescriptor(o,"c");
console.log(desc);
//{value: 2, writable: true, enumerable: true, configurable: true}
5.Object.getOwnPropertyDescriptors('对象') :或取对象的所有属性的描述
注意:获取属性,不是属性值
var o={a:{b:1}} ,a是属性,{b:1}是属性值,6,7,8都是获取的属性
6.Object.getOwnPropertySymbols('对象'):获取对象中的symbol()属性
7.Object.getOwnPropertyNames(‘对象’):获取对象中的所有对象属性,包括不可枚举属性,但是不包括symbol()属性,返回的是一个数组形式
8.Reflect.ownKeys('对象') 获取对象的所有对象属性,包括不可枚举属性和symbol属性
9.Object.entries() 将对象转化成迭代器,返回一个二维数组,转成迭代器可以存在map与set中
例子
var o={a:1,b:2,c:3};
console.log(Object.entries(o));//[[a,1],[b,2],[c,3]]
数组也行
var arr=[1,2,3,4];
console.log(Object.entries(arr));
//[[0,1],[1,2],[2,3],[3,4]] 通过索引与值分开
10.Object.fromEntries 将迭代器转对象
11.Object.freeze(对象)冻结对象 ,就是将对象设置成不可删除,不可修改 不可添加的
12,Object.isFrozen(对象):判断对象是否被冻结 返回一个布尔值
13.Object.seal(对象) :封锁对象 可以修改。不能删除,不能扩展(添加)
Object.isSealed(对象) 判断是否被封锁
14.Object.preventExtensions(对象) 设置不可扩展对象,可以修改,可以删除,不能扩展(添加)
Object.isExtensible(o) 判断对象是否被设置不可扩展
15.Object.getPrototypeof(对象) 查看对象的原型链 相当于 对象.__proto__
例如:
var o={a:1}
var o1 =Object.create(o)
o1.b=2
console.log(o1)//{b:2}
console.log(Object.getPrototypeOf(o1))
//{a:1}输出o1上一层原型链o
console.dir(Object.getPrototypeOf(Object.getPrototypeOf(o1)));//Object
16.Object.setPrototypeOf(对象1,对象2) 把对象2设置成对象一的原型链
17.isPrototypeOf
o.isPrototypeOf(o1) //判断O1是否在o的原型链上
注意:不能随便强行嫁接别的原型链
17.对象.hasOwnProperty('属性名'),与Object.hasOwn (对象,'属性名')
18.Object.keys(对象) 只能获取可枚举的对象属性,返回一个数组
19.Object.values(对象)只能获取可枚举的对象属性值,返回一个数组
setter/getter 访问器属性
对象,有属性和方法
属性 属性名对应值 key value 可以用来存储数据,使用等号赋值
方法 属性名对应函数 可以执行函数。用来处理多条语句,可以传参,可以返回,不可存储值
例子:
var obj={
_a:1,
set a(value){
this._a=value
console.log('aaa');
},
get a(){
return this._a
}
}
obj.a=4 //在赋值的时候会执行set函数
console.log(obj.a); //在获取这个值得时候会调用get函数
例二:
var div=document.querySelector("div");
Object.defineProperty(div,"x",{
set(value){
if(!this.bool) return;
this._x=value;
this.style.left=value+"px";
},
get(){
if(!this._x) this._x=0;
return this._x;
}
})
div.onclick=function(){
div.bool=!div.bool;
}
setInterval(function(){
div.x++;
},16)
proxy 代理
原理:Proxy 可以理解成,在目标对象之前架设一层“拦截”,外界对该对象的访问,都必须先通过这层拦截,因此提供了一种机制,可以对外界的访问进行过滤和改写。Proxy 这个词的原意是代理,用在这里表示由它来“代理”某些操作,可以译为“代理器”
特点:可以通过代理的方法实现自己本身无法完成的事件
1.proxy的set,get与get set 区别
proxy 可以通过代理实现对多个属性的规范,而set,get只能实现单个属性的规范,例如实现一个对象的每个key必须是number并且小于6,就可以用proxy实现,而get,set方法只能实现一个,例如a属性
var p=new Proxy(o,{
set:function(target,key,value){
if(!Number.isInteger(target[key]))throw new TypeError('是一个非整数')
if(isNaN(value)||typeof value!=='number')throw new RangeError("这不是一个数值");
if(value<0 || value>99) throw new RangeError("超出数值范围!");
target[key]=value;
}
})
p.a=3;
// p.a=3.14
// p.a=-2;
// p.a="a";
console.log(o.a);
var s={
set a(value){
if (!Number.isInteger(value))throw new TypeError('是一个非整数')
if(isNaN(value) || typeof value!=="number") throw new RangeError("这不是一个数值");
if(value<0 || value>99) throw new RangeError("超出数值范围!");
this.x=value
},
get a(){
if(!this.x)return 0
return this.x
}
}
s.a=1
console.log(s.a);
2.proxy的has方法:判断对象中有没有哪个属性
例子;在对象原型链上的属性输出false,是自己的对象属性输出true
var o={a:1,b:2,c:3};
var o1=Object.create(o);
o1.d=5;
o1.e=6;
var p=new Proxy(o1,{
has:function(target,key){
if(!target.hasOwnProperty(key)) return false;
return key in target;
}
})
console.log("a" in p);//false
console.log("b" in p);//false
console.log("c" in p);//false
console.log("d" in p);//true
console.log("e" in p);//true
console.log("f" in p);//false
3.proxy的apply 方法
function fn(){
return [].reduce.call(arguments,(v,t)=>v+t);
}
var f=new Proxy(fn,{
apply(target,thisArg,argArray){
for(var i=0;i<argArray.length;i++){
if(typeof argArray[i]!=="number") throw new TypeError(`第${i+1}个参数不是数值`)
}
return fn.apply(thisArg,argArray);
}
})
var s=f(1,2,3,4,5,6,"a");
console.log(s)
对象的proxy 方法
1.definedProperty 目的:可以设置某个对象中除了value的属性一样的属性描述,不用在某一个都要再写一遍
var o={};
var p=new Proxy(o,{
defineProperty(target,key,desc){
desc.enumerable=true;
desc.configurable=false;
desc.writable=true;
return Object.defineProperty(target,key,desc);
}
})
Object.defineProperty(p,"a",{
value:1
})
delete o.a
console.log(o)
2.getOwnPropertyDescriptor 为了改变某个满足条件的属性的 definedProperty 中的某个值
var o={a:1,b:2};
var p=new Proxy(o,{
getOwnPropertyDescriptor(target,key){
var desc=Object.getOwnPropertyDescriptor(target,key);
if(/a/.test(key)){
desc.enumerable=false;
}
return desc;
}
})
console.log(Object.getOwnPropertyDescriptor(p,"a"));
//只要对象中有a属性,enumerable=false就会变成false
3. getPrototypeOf()
4. isExtensible() preventExtensions() ,为了在对象内部形成一个属性是否可以设置扩展
var o={a:1,b:2};
var p=new Proxy(o,{
isExtensible(target){
target.canEvolve=Reflect.isExtensible(target);
return Reflect.isExtensible(target);
},
preventExtensions(target){
target.canEvolve = false;
return Reflect.preventExtensions(target);
}
})
Object.preventExtensions(p);
var bool=Object.isExtensible(p);
console.log(o)//{a: 1, b: 2, canEvolve: false}
5.ownKeys() 为了或取所有对象属性,但是不包括symble(),与不可枚举的属性,与for in o 有什么区别呢???????
var o={a:1,b:2,c:3,[Symbol()]:4,};
Object.defineProperty(o,"e",{
configurable:true,
enumerable:false,
writable:true,
value:5})
var p=new Proxy(o,{
ownKeys(target){
var arr=Reflect.ownKeys(target);
return arr;
}
})
var keys=Object.keys(p);
console.log(keys)
6.setPrototypeOf()
var o={a:1,b:2};
var p=new Proxy(o,{
setPrototypeOf(target,proto){
Object.setPrototypeOf(proto,{length:0})
return Object.setPrototypeOf(target,proto);
}
})
Object.setPrototypeOf(p,{a:5})
console.log(o)
原型与原型链
1.每个函数都有个prototype,prototype里面有个constroctor函数
2.实例化类的constructor,它指向类名
例如:
var arr=[1,2,3,4]
var arr1=new arr.constructor()===new Array()
console.log(arr.constructor===Array); true
3.isPrototypeof()判断某个对象的原型链上是否有 某个对象
var o={a:1}
var o1={b:2}
Object.setPrototypeof(o1,o)
o.isPrototypeOf(o1) //true
柯力化与反柯力化
1.柯力化:作用:可以反复执行函数,函数前面不会清空的
function currying(fn,thisArg){
var arr=[];
return function (){
if(arguments.length>0){
arr.push.apply(arr,arguments);
return arguments.callee;
}else{
return fn.apply(thisArg,arr);
}
}
}
function getSum(){
var arr=Array.from(arguments);
console.log(this);
this.sum=arr.reduce((v,t)=>v+t);
return this.sum;
}
var f=currying(getSum);
var s=f(1,2,3)(4,5,6)(7,8)(9,10)()
console.log(s)
var o={sum:0};
var f=currying(getSum,o);
f(1,2,3);
f(3,4,5);
f(6,7);
var s=f();
console.log(s,o);
2.反柯力化: 目的把一个方法提取出来,例如字符穿的方法提取出来数组也可以用
Function.prototype.uncurrying=function (){
var that=this
return function(){
return Function.prototype.call.apply(that,arguments)
}
}
var str ='123'
var replace=str.replace.uncurrying()//str.replace.call(arr)
var arr=[1,2,3,4]
var arr=replace(arr,'1','a')
console.log(arr);//出来的是一个字符串