ES6笔记(对象的is、 assign、keys、valus、entries等方法)

1、Object.is

与 === 行为基本一致,除了NaN, +0与-0

//===
console.log(1===1); //true
console.log(1==='1'); //false
console.log(1===true); //false
console.log(0===false); //false
console.log({}==={}); //false ;注意:空对象作比较,比较的是地址
console.log(NaN===NaN);//false NaN跟谁都不相等 
console.log(+0===-0);//true


//Object.is()
console.log(Object.is(1,1));//true
console.log(Object.is(1,'1'));//false
console.log(Object.is(1,true)); //false
console.log(Object.is(1,false)); //false
console.log(Object.is({},{})); //false
console.log(Object.is(NaN,NaN)); //true
console.log(Object.is(+0,-0)); //false
2、Object.assign
用于将源对象( source )的所有可枚举属性复制到目标对象( target )

对象的属性描述符:可读、可写、可配置、可枚举

obj.assign( { a : 10 }, { b : 20 }, { c : 30 } ); //{ a : 10 }放在第一个就是目标对象,从第二个参数开始就是源对象(可以有多个)

//把obj2和obj3拷贝覆盖到obj
var obj={a:10},obj2={b:20,a:100},obj3={c:30,a:200}
//{a:200,b:20,c:30}
var res=Object.assign(obj,obj2,obj3);
obj.d=40;
console.log(obj);//{a: 200, b: 20, c: 30, d: 40}
console.log(res);//{a: 200, b: 20, c: 30, d: 40}
console.log(res === obj);//true 返回值跟obj相等 


//自己实现assign
var obj={a:10},obj2={b:20,a:100},obj3={c:30,a:200}
function myAssign(dst,...src){
	for(var key in src){
		for(var key2 in src[key] ){
			dst[key2]=src[key][key2]
		}
	}
	return dst;
}
var res=myAssign(obj,obj2,obj3);
console.log(obj);//{a: 200, b: 20, c: 30}
console.log(res);//{a: 200, b: 20, c: 30}
console.log(res === obj);//true 返回值跟obj相等 

Object.assign特性:
1,如果传数值,返回值会把数值转换为对象
2,目标对象为null,undefined会报错
3,源对象为null, undefined会被忽略
4,复制字符串,布尔,值这3种基本类型时,只有字符串会被当做
数组形式复制到目标对象
5,不能枚举的属性 不会被拷贝
6,object.assign执行的是浅拷贝(只是拷贝源对象的引用)
7,嵌套的对象同名键会被直接覆盖
8,同键名(相同索引)的数组项 后面的把前面的覆盖

//返回object
var res=Object.assign(10);
console.log(typeof res);  //object


//undefined,null放在目标对象会报错 ,放在源对象会被忽略
Object.assign(undefined); //报错
Object.assign(obj,undefined);


//字符串会被当成数组形式复制到目标对象,布尔,值会被忽略
var v1=true,v2='abcd',v3=10;
var res=Object.assign({},v1,v2,v3);
console.log(res);// {0: "a", 1: "b", 2: "c", 3: "d"}


//不能枚举的属性 不会被拷贝
var obj={
	a:10
}
Object.assign(obj,Object.defineProperty({},"b",{  //定义一个对象b,他的属性值是不可枚举的
	enumerable:false,
	value:100
}),Object.defineProperty({},"c",{   //定义一个对象c,他的属性值是可枚举的
	enumerable:true,
	value:200
}))
console.log(obj);//{a: 10, c: 200}


//浅拷贝(相当于引用同一个内存地址),源对象改变,它也会跟着改变
var obj={
	'user':{
		'name':'abc'
	}
}
var res=Object.assign({},obj);
obj.user.age='20';
console.log(res) //也会有age


//嵌套的对象同名键会被直接覆盖
var obj={
	'url':{
		'baidu':'http://www.baidu.com'
	}
}
var obj2={
	'url':{
		'taobao':'http://www.taobao.com'
	}
}
Object.assign(obj,obj2);
console.log(obj) //url变为taobao


//相同索引的数组项,后面的把前面的覆盖
var res=Object.assign([10,100,1000],[1,2]);
console.log(res);//[1, 2, 1000]
Object.assign用途:
1,为对象添加属性
2,为对象添加方法
3,克隆对象
4,合并对象
    合并多个对象--》目标对象
    合并多个对象--》空对象
    插件开发中的配置选项
//添加属性和方法
function CreatObj(name,age){
	//等价于{name:name,age:age}
	Object.assign(this,{name,age}); //因为用this拷贝,所以要构造函数调用
}
//在原型链上拷贝方法
//等价于CreatObj.prototype.shoInfo=function(){}
Object.assign(CreatObj.prototype,{
	showInfo(){
	  return this.name
}
})
var obj=new CreatObj('aaa',20)
console.log(obj.name,obj.age,obj.showInfo());//aaa 20 aaa

--------------------------------------------------

//克隆对象
function cloneObj(src){ //克隆源对象,把源对象复制到空对象{}里
	return Object.assign({},src)
}
var srcObj={
	a:10,
	b:20
}
var res=cloneObj(srcObj);
console.log(res);//{a: 10, b: 20} 
console.log(res === srcObj);//false res原来是个空对象,由源对象赋值进去的

--------------------------------------------------

//合并对象
//把多个源对象合并到目标对象

let merge=(dst,...src)=> Object.assign(dst,...src);//传参叫不定参数,assign里叫展开运算符
var obj={a:10}
merge(obj,{b:20,a:100},{b:30,a:1000,c:200}) 
console.log(obj);//{a: 1000, b: 30, c: 200}  

//把多个源对象合并到空对象
let merge=(...src)=> Object.assign({},...src)
console.log(merge({a:10},{b:20}));//{a: 10, b: 20}

--------------------------------------------------

//插件开发中经常干的事情:定制参数
//jq参数合并功能   $.extend({},default,options)
function processConf(options){ //options为定制参数
	//把传进来的和默认参数合并
	var defaults={ //当不传入参数时为默认参数
		a:10,
		b:20
	}
	var opts=Object.assign({},defaults,options);
	return opts
}
console.log(processConf());//{a: 10, b: 20}
console.log(processConf({a:100,b:200,c:'aaa'}));//{a: 100, b: 200, c: "aaa"}
3、对象的其它方法
①Object.getOwnPropertyDescriptor( 对象名, 属性名 )
②Object.keys: 返回一个数组,成员是参数对象自身的( 不含继承的 )
   所有可遍历属性的键名( 注意与for...in的区别, for..in会考虑继承属性 )
③Object.values: 返回一个数组,成员是参数对象自身的( 不含继承的 )的值
④Object.entries: 返回一个数组,成员是参数对象自身的( 不含继承的 )的键值对
⑤__proto__
⑥Object.setPrototypeOf( object, prototype );设置原型对象
⑦Object.getPrototypeOf( obj );获取原型对象
//获取对象属性的描述符:Object.getOwnPropertyDescriptor( 对象名, 属性名 )
var obj={
	'userName':'aaa'
}
//定义对象的属性和配置描述符
Object.defineProperty(obj,'userAge',{
	enumerable:false,
	value:10,
	writable:false,
	configurable:false
})
//获取对象属性的描述符
console.log(Object.getOwnPropertyDescriptor(obj,'userName'));//是否可枚举,可配置...
//读取对象的键名,由于'userAge'的属性enumerable设置为false,所以读取不出来,且不考虑继承过来的属性
console.log(Object.keys(obj));//["userName"]

---------------------------------------------------

//Object.keys() 不会考虑原型链上的,只会考虑自身的属性
function CreateObj(name,age){
	this.name=name;
	this.age=age;
}
CreateObj.prototype.sex='man';
function Son(name,age){
	CreateObj.call(this,name,age); //通过对象冒充把属性拷贝到子对象
}
Son.prototype=CreateObj.prototype;//即使原型链继承过来,但是Object.keys也不会返回出来

var s=new Son('aaa',20);
console.log(Son.prototype === CreateObj.prototype);//true
console.log(s.prototype === CreateObj.prototype);//false
console.log(s.sex);//man
console.log(Object.keys(s))//["name", "age"] 不会考虑原型链上的,只会考虑自身的属性

for(var key in s){ //for in 自身可遍历的属性,会考虑从父类继承过来的的原型上的属性
	console.log(key)  //name age sex
}

---------------------------------------------------

//values、entries
var obj={
	'userName':'aaa'
}
//定义对象的属性和配置描述符
Object.defineProperty(obj,'userAge',{
	enumerable:false,
	value:10,
	writable:false,
	configurable:false
})
console.log(Object.values(obj));//["aaa"] 返回属性的值
console.log(Object.entries(obj));//userName aaa 返回属性的键和属性的值
//设置原型对象Object.setPrototypeOf(object,prototype); 
function CraeteObj(){
//	this.userName="aaa"
}
CraeteObj.prototype.showUserName=function(){
	return this.userName
}

CraeteObj.prototype.userName='bbb';

var obj=new CraeteObj();
console.log(obj.__proto__);//对象的隐式原型__proto__指向了构造函数的原型对象  注意:每个函数都有原型对象,箭头函数是没有的
console.log(obj.__proto__===CraeteObj.prototype);//true

// obj.__proto__=null;//undefined 把实例的隐式原型设置为null,实例就访问不到原型对象上的属性和方法
//等价于
//Object.setPrototypeOf(obj,null);//undefined
//console.log(obj.userName);

//获取原型对象
console.log(Object.getPrototypeOf(obj)===CraeteObj.prototype) //true 等价于 CraeteObj.prototype

//强行设置obj的隐式原型等于obj2
var obj2={
	age:10
};
//obj.__proto__=obj2
//等价于
Object.setPrototypeOf(obj,obj2);
console.log(obj.age);//10


猜你喜欢

转载自blog.csdn.net/qq_14993375/article/details/79739024