Day-26对象方法及相关内容

Object的方法

 

实例方法 属于new出来的object对象 (万物皆对象)所有的对象都有的方法

hasOwnProperty() 当前对象上是否具备对应的属性(boolean值)*

function Person(){
   this.name = 'jack'
}
let person =  new Person()
person.age = 18
console.log(person.hasOwnProperty('age'))//true
//判断当前的原型对象是否具备对应的属性
console.log(Person.prototype.hasOwnProperty('age'))//false

isPrototypeOf() 这个属性是否存在于当前的原型链 *

//这个属性是否存在于当前的原型链上
console.log( person.isPrototypeOf('name'));

__defineGetter__ __defineSetter__ 定义get方法和set方法

// 定义get 和set方法 (computed)
person.__defineGetter__("name",function(){
   console.log('获取数据');
})
person.__defineSetter__("name",function(){
   console.log('设置数据');
})
//调用get
console.log(person.name);
//调用set
person.name = 'tom'

propertyIsEnumerable 判断是否为枚举类型

//判断当前的属性是否是枚举类型
console.log(person.propertyIsEnumerable('name'));
实例属性 所有的对象都拥有的属性

__proto__对象原型 (隐式原型)指向对应的构造函数的prototype

console.log(person.__proto__);

constructor指向对应的构造函数

console.log(person.constructor);
静态方法 使用Object.出来的方法(只有Object.方法名调用)

create 创建一个对象

let obj = {name:'jack'}
//创建一个对象
let createObj =  Object.create(obj)
//将对应的属性放在原型上
console.log(createObj);

assign 将后面的对象拷贝到第一个对象上

// assign 将多个对象拷贝到一个对象上
let newObj = {}
Object.assign(newObj,obj,{age:18})
console.log(newObj);

entries keys values

//entries keys values
console.log(Object.keys(newObj)); //key组成的数组
console.log(Object.values(newObj)); //value组成的数组
console.log(Object.entries(newObj)); //二维数组

is 判断俩个对象是否是一个对象

let obj1 = {name:'jack',age:18}
// is
console.log( Object.is(newObj,obj1));//false

freeze() 冻结对象 preventExtensions() 使对象不能扩展 seal() 使用对象密封

isFrozen 判断是否冻结 isSealed判断是否密封 isExtensible是否可扩展

//冻结对象
Object.freeze(obj1)
//判断对象是否冻结
console.log(Object.isFrozen(obj1));
//密封对象
Object.seal(obj1)
//判断对象是否密封
console.log(Object.isSealed(obj1));
//使对象不可扩展
Object.preventExtensions(obj1)
//判断对象是否可扩展
console.log(Object.isExtensible(obj1));

setPrototypeOf 在原型上设置属性 getPrototypeOf 获取原型上的全部属性 相当于拿到原型对象

//在原型上设置内容 对象  属性名 属性值
let obj2 = {}
Object.setPrototypeOf(obj2,{
   name:'tom'
})
console.log(obj2.name);
//在原型上获取内容 (拿到原型上的所有的内容 拿到原型对象)
console.log(Object.getPrototypeOf(obj2));

getOwnPropertyDescriptor 获取属性详情 getOwnPropertyDescriptors 获取所有的属性详情

//获取对应的属性的详情信息
console.log(Object.getOwnPropertyDescriptor(obj3,'name'));
//获取所有属性的详情
console.log(Object.getOwnPropertyDescriptors(obj3));

 

getOwnPropertyNames 获取所有的属性名 getOwnPropertySymbols 获取所有的key为symbol值的属性

//获取所有的属性名字 返回的是数组
console.log(Object.getOwnPropertyNames(obj3));
//返回对应的属性名为symbol类型的属性组成的数组
console.log(Object.getOwnPropertySymbols(obj3));
defineProperty 定义属性(*)(vue2的底层实现)

属性详情没有传入 (传入是一个对象类型 但是这个里面你传入的 undefined)

 

let obj = {}
//给obj对象添加对应的属性
//对象 key属性名 详情信息(ECMA规定的一个对象 属性对象 只可以设置不可读取 JS引擎) 被称为数据属性
Object.defineProperty(obj,'name',{
value:'jack',
writable:false ,//可以不可以重新赋值
configurable:false, //能不能删除
enumerable:true //能不能遍历
})
//value属性
console.log(`obj`, obj);
//writable属性
obj.name = "hello"
delete obj.name
console.log(`obj`, obj);
for(var key in obj){
console.log(obj[key]);
}
//定义一个age属性 他的值为18 他可以修改 可以删除 可以遍历
Object.defineProperty(obj,'age',{
writable:true,
configurable:true,
enumerable:true,
value:18
})
数据属性(当前属性没有的情况下)
value 表示当前值 默认情况 undefined
writable 是否可以赋值 默认情况为 false
enumerable 是否可以遍历 默认情况是 false
configurable 是否可以删除 默认情况是 false
访问器属性 (当前属性已经有了)
enumerable 是否可以遍历 默认情况是 false
configurable 是否可以删除 默认情况是 false
set 函数 (writable)
get 函数 (value)
使用访问器属性
var name = 'jack'
let obj = {name}
Object.defineProperty(obj,'name',{
configurable:true,
enumerable:true,
set(value){ //设置 set
console.log('设置方法调用了'+value);
name = value
},
get(){ //获取 get
console.log('获取方法调用了');
return name
}
})
obj.name = '张三' //调用set方法
console.log(obj.name); //调用get方法
console.log(obj);
解决循环引用问题 *
let obj = {_name:'jack'}
Object.defineProperty(obj,'name',{
configurable:true,
enumerable:true,
set(value){ //设置 set
console.log('设置方法调用了'+value);
this._name = value
},
get(){ //获取 get
console.log('获取方法调用了');
return this._name
}
})
obj.name = '张三' //调用set方法
console.log(obj.name); //调用get方法
console.log(obj);
defineProperties 定义多个属性
//defineProperties 定义多个属性
Object.defineProperties(obj,{
sex:{
writable:true,
configurable:true,
enumerable:true,
value:'男'
},
height:{
writable:true,
configurable:true,
enumerable:true,
value:185
}
})

利用观察者和Object.defineProperty 实现 vue2中的双向数据绑定功能(***)

vue2的中双向数据绑定
<!DOCTYPE html>
<html lang="en">

<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<meta http-equiv="X-UA-Compatible" content="ie=edge">
<title>Document</title>
</head>

<body>
<div id="app">
<input type="text" v-model="message">
<p>{{message}}</p>
</div>
<script src="./lib/vue.js"></script>
<script>
new Vue({
el: "#app",
data: {
message:""
}
})
</script>
</body>

</html>
js原生实现对应的v-model双向数据绑定
<!DOCTYPE html>
<html lang="en">

<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<meta http-equiv="X-UA-Compatible" content="ie=edge">
<title>Document</title>
</head>

<body>
<div id="app">
<!-- 利用观察者模式 监听对应的input -->
<input type="text" v-model="message">
<!-- 设置对应的在data里面的message -->
<p>{{message}}</p>
</div>
<script>
var el = document.querySelector('#app')
var data = {_message:"tom"}
var template = el.innerHTML //拿到这个盒子里面所有的html代码
//渲染方法封装
function rander(){
//找到对应的在template的{{}}包起来的东西把替换为对应的变量的值再渲染到页面上
el.innerHTML = template.replace(/\{\{\s?[\w.]+\s?\}\}/g,(str)=>{
str = str.substring(2,str.length-2) //截取删除对应的{{}}
return data[str] //返回对应的数据进行替换
})
//获取所有的加了v-model的input框
Array.from(el.getElementsByTagName("input"))
.filter(input=>input.getAttribute('v-model')) //获取对应的有v-model的input
.forEach(item=>{ //遍历这些input
let value = item.getAttribute('v-model')//拿到对应v-model的值
//添加对应的事件给input框
item.oninput = function(){//事件监听
//读取v-model属性值
value = this.getAttribute('v-model')
//设置对应的data里面的value值 给定值为input框里面的值
data[value] = this.value
}
//将对应的数据重新设置给对应的input框
item.value = data[value]
//防止焦点丢失 聚焦
item.focus()
})
}
Object.defineProperty(data,'message',{
get(){
return this._message //返回data里面的数据
},
set(value){
this._message = value //将对应的值设置到data去
rander() //重新渲染
}
})
//设置对应的message的值 调用对应的渲染方法进行渲染
data.message = "hello"
</script>
</body>

</html>

对象的深拷贝和浅拷贝

浅拷贝 一个对象只拿第一层值 到了第二层如果还是对象拿到就是地址(拷贝第一层的值)

 

实现浅拷贝(第一层地址不共享 第二层开始地址共享)
Object.assign
let obj1 = {name:'jack'}
let obj2 = {age:18,likeFood:['苹果','香蕉']}
//将obj2拷贝给obj1
let obj3 = Object.assign(obj1,obj2)
console.log(obj3);
obj3.name = 'tom'
console.log(obj1.name);//拷贝了值
obj3.likeFood.push('橘子')
console.log(obj3);
console.log(obj2);
// likeFood这个对象地址是由obj3和obj2共享的 拷贝是对应的地址
console.log(obj3.likeFood === obj2.likeFood);//true
数组concat方法
//数组的方法
let arr = [{obj:{
age:18
}}]
let arr2 = arr.concat()
console.log(arr2[0]==arr[0]);//true
arr2[0].name = 'hello'
console.log(arr[0].name);
数组的截取方法 slice
//数组截取方法
let arr3 = arr.slice()
arr3[0].age = 30
console.log(arr[0].age);
console.log(arr3[0].age === arr2[0].age);
lodash.js插件 clone方法
使用for循环遍历第一层
注意事项

浅拷贝不是赋值 (浅拷贝会产生一个新的对象 是赋值只是指向同一个对象而已)

深拷贝 一个对象会拿对应所有层级的值 也就是对应的第二层的对象他只获取里面的值(就是拷贝的对象和之前的对象没有一个对象地址是相等的)
JSON.parse 结合 JSON.stringify 实现
let obj = {likes:['睡觉']}
//深拷贝
let obj1 = JSON.parse(JSON.stringify(obj))
console.log(obj.likes == obj1.likes)//false
递归操作
lodash.deepClone
posted @ 2022-06-29 09:10  板哥是老几  阅读(26)  评论(0)    收藏  举报