Object的相关内容
概述:
Object是顶层的构造,万物皆对象,所有的对象都是Object的子类。Object的方法所有的对象都能共享。
Object实例方法(原型方法)
使用实例对象调用的方法称为实例方法。所有实例都是Object的子类,所以所有的实例都能调用Object的实例方法。
已经废弃的方法
defineGetter 定义get
defineSetter 定义set
lookupSetter 导出对应的set方法
lookupGetter 导出对应get方法
class Person{ constructor(){ this.age = 18 } } //调用对应的__defineGetter let person = new Person() //定义get 访问对应的属性的时候调用的方法 属性名 handler person.__defineGetter__('age',function(){ console.log('getter调用了'); return '18' }) console.log(person.age); //定义对应的set 用于设置的时候 person.__defineSetter__('username',function(value){ console.log('setter调用了 传入的值'+value); // this.username = value 循环调用问题 递归死循环 }) person.username = 'jack' console.log(person); //获取对应的get方法 指定的属性 let get = person.__lookupGetter__('age') let set = person.__lookupSetter__('username') console.log(get); console.log(set);
hasOwnProperty 判断对象上是否具备属性(不会原型中获取)*
class Person{ constructor(){ this.age = 18 } } Person.prototype.username = 'jack' let person = new Person() person.sex = '女' //判断对象上是否具备属性 返回布尔类型 console.log(person.hasOwnProperty('age')); //true console.log(person.hasOwnProperty('sex')); //true console.log(person.hasOwnProperty('username')); //false
isPrototypeOf 判断当前对象(构造函数的原型对象)是否处在对应参数对象的原型链上 返回布尔类型 *
class Son extends Person{ constructor(){ super() } } //判断当前对象(构造函数)是否处在对应参数对象的原型链上 返回布尔类型 console.log(Object.prototype.isPrototypeOf(person)); //true let son = new Son() console.log(Person.prototype.isPrototypeOf(son)); //true
propertyIsEnumerable 指定属性是否可以枚举(如果对象没有指定的属性,则此方法返回 false )
// 返回boolean类型 属性是否是可以枚举(可以遍历 for-in遍历) let obj = { arr:[1,2,3], o:{key:1}, v:123, f:()=>{}, b:false } //判断当前属性是否可以枚举 可以遍历 console.log(obj.propertyIsEnumerable('v')); //true console.log(obj.propertyIsEnumerable('arr')); //true console.log(obj.propertyIsEnumerable('o')); //true console.log(obj.propertyIsEnumerable('f')); //true console.log(obj.propertyIsEnumerable('b')); //true
所有的内置属性都是false(symbol做为对象的key被设置在底层) 所有的自定义属性返回的都是true
valueOf 提取对应的值 toString 转为string字符串 toLocaleString 转为本地的字符串
// valueOf提取对应的值 console.log(new Object().valueOf()); // toString 转为字符串类型 引用类型出现的结果[object Object] console.log(new Object().toString()); //toLocalString 转为本地格式的字符串 千位分隔 console.log(Number(123456789).toLocaleString());
Object的实例属性
__proto__ 隐式原型
let obj = new Object() console.log(obj.__proto__)
constructor 构造器
let obj = new Object() console.log(obj.constructor) //指向对应的构造函数
Object的静态方法
通过类名通过,只能被Object类名调用。
assign 将后面的对象拷贝到第一个对象里面 返回的是一个新的对象 这个对象和原本第一个对象的地址一致(实现浅拷贝)(*)
// 将后面的对象给到前面的对象 assign 返回一个新的对象 新的对象会和第一个对象的地址一样 let target = {} let obj = Object.assign(target,{name:'jack'},{age:18}) console.log(obj); console.log(target);
create 根据对应传入的对象创建同类型的对象 创建的新对象的原型里面包含了对应传入对象 (*)
//create 创建一个对象 let obj1 = {name:"张三"} let obj2 = Object.create(obj1) console.log(obj2); //将对应obj1加到对应的obj2的原型上 console.log(obj2 == obj1); class Person{ constructor(){ this.name = 'tom' } } let person = Object.create(Person) //根据传入的对象的类型来创建对应的对象 console.log(person); //函数 Class本质就是构造函数
keys values entries 获取对应对象的所有的key 和 value 以及相关键值对 (*)
//keys values entries 返回的都是一个迭代器 let obj = { name: 'jack', age:18, sex:'男' } //获取所有的key let objKeys = Object.keys(obj) //返回所有key组成的伪数组 //获取所有的value let objValues = Object.values(obj) //返回所有key组成的伪数组 //获取所有的键值对 let objEntries = Object.entries(obj) //返回所有key组成的伪数组 console.log(objKeys); console.log(objValues); console.log(objEntries); //这三个获取到的数组都可以进行遍历 objEntries.forEach(arr=>{ console.log(`key:${arr[0]} value : ${arr[1]}`); })
is 判断俩个对象是否是一个 (*)
//is console.log(Object.is(NaN,NaN)); //true //assign 实现浅拷贝 let obj1 = Object.assign(obj) console.log(Object.is(obj1,obj)); //true console.log(Object.is({},{})); //false console.log(Object.is(null,null)); //true console.log(Object.is(null,undefined)); //false
冻结(只读) freeze 是否冻结 isFrozen (*)
//使对象冻结 不能进行修改 (只读 包含不可扩展 以及密封) Object.freeze(obj) obj.age = 20 //不能进行修改 console.log(obj); delete obj.name //无用操作 //打印当前对象是否冻结 console.log(Object.isFrozen(obj)); //true
密封 (不能添加和删除属性) seal 是否密封 isSealed (*)
//使对象密封 不能进行delete操作 以及不能添加新的属性 Object.seal(obj) delete obj.name //无用操作 console.log(obj); //打印当前对象是否密封 console.log(Object.isSealed(obj)); //true
不可扩展 (不能添加)preventExtensions 是否可扩展 isExtensible (*)
//使对象不能扩展 不能添加新的属性 Object.preventExtensions(obj) obj.username = '张三' //无用操作 console.log(obj); //打印当前对象是否可扩展 console.log(Object.isExtensible(obj)); //false
getPrototypeOf 获取指向的原型对象 setPrototypeOf 设置新的原型对象(*)
// getPrototypeOf 原型获取 // setPrototypeOf 原型设置 将对应的第二个参数赋值给对应的第一个参数的原型 //在原型上进行设置 目标对象 key:value 传入对应的key和value //第一个为目标对象 第二个为原型对象 let obj = {} Object.setPrototypeOf(obj,{ username:'jack', age:18 }) console.log(obj.username);//obj的这个原型上进行设置 console.log(obj.age);//obj的这个原型上进行设置 let obj1 = new Object() console.log(obj1.username); //undefined //getPrototypeOf 获取指向的原型对象 let pro = Object.getPrototypeOf(obj) let obj1Pro = Object.getPrototypeOf(obj1) console.log(pro); //{username:'jack',age:18} console.log(pro == Object.prototype);//false console.log(obj1Pro == Object.prototype);//Object.prototype true
getOwnPropertyDescriptor 获取属性详情对象 getOwnPropertyDescriptors 获取所有的属性详情对象 (*)
let obj = { name:'jack' } //getOwnPropertyDescriptorc 获取属性的详情信息 返回一个属性对象(es的内置对象) let property = Object.getOwnPropertyDescriptor(obj,'name') console.log(property);
//获取所有的属性详情信息 返回也是一个对象 这个对象里面包含对应的key 值为对应的属性对象 let objs = Object.getOwnPropertyDescriptors(obj) console.log(objs);
getOwnPropertyNames 获取所有属性名组成的数组(不包含symbol值属性名)
getOwnProperSymbols 获取属性名为symbol值的属性组成的数组
//获取所有的属性名 组成一个数组或者是伪数组 console.log(Object.getOwnPropertyNames(obj)); let sy = Symbol() obj[sy] = 'hello'//属性名为symbol的属性 //获取所有属性名为symbol值的属性 console.log(Object.getOwnPropertySymbols(obj));
defineProperty 定义一个属性 ( vue2的底层实现 ***)
let obj = {} //给对象添加属性 // defineProperty 定义一个属性 参数是对象 属性名 属性对象 // (属性对象 value 对应的值 writeable 是否可以修改 enumerable 是否可以遍历 configurable 删除可以删除) Object.defineProperty(obj,'name',{ value:'jack', writable:true, //可以修改 enumerable:true, //可以遍历 for in configurable:true //可以删除 }) console.log(obj); //多一个name属性 obj.name = 'hello' //跟writable属性相关为false就不能修改 delete obj.name //跟configurable相关 为false 不能删除 console.log(obj); for(let key in obj){ console.log(key); //enumerable为false 就不能进行遍历 }
属性对象的基础属性
value 值
writeable 是否可以设置
enumerable 是否可以遍历
configurable 是否可以删除
属性对象的访问器属性 (已经存在的情况才可以调用)
get 表示获取(函数)
set 表示设置 (函数)
enumerable 是否可以遍历
configurable 是否可以删除
//以访问器属性来写(后面的俩个内容可以不写默认为false) Object.defineProperty(obj,'age',{ set(value){ //设置值的时候调用 value等于后面传递的值 console.log('set执行了'); mockObj.age = value }, get(){ //获取值的时候 console.log('get执行了'); return mockObj.age }, // enumerable:true, //可以遍历 for in // configurable:true //可以删除 }) console.log(obj.age); //调用了get的返回值 obj.age = 20 //调用了set方法 console.log(obj.age); //调用了get的返回值 delete obj.age console.log(obj.age); console.log(obj);
vue2是由对应的Object.defineProperty和观察者模式实现
defineProperties 定义多个属性
// defineProperties 定义多个属性 对象 属性对象 let object = { } Object.defineProperties(object,{ name:{ writable:true, value:"张三", enumerable:true, configurable:true }, sex:{ // writable:true, // value:"男", enumerable:true, configurable:true, get(){ return '男' }, set(value){ console.log('设置方法调用了') } } }) console.log(object);
vue2双向数据绑定实现
v-model来实现双向数据绑定
<div id="app"> <input type="text" v-model="message"> {{message}} </div> <script src="./lib/vue.js"></script> <script> new Vue({ el: "#app", data: { message:"你好啊" } }) </script>
底层实现(模拟实现)
<div id="app"> <input type="text" v-model="message"> {{message}} <input type="text" v-model="title"> {{title}} </div> <script> class Vue { constructor(option) { this.option = option //通过对应的el属性传入的选择器选择对应的元素 this.el = document.querySelector(option['el']) //提取data this.data = option['data'] //虚拟对象 this.mockData = {} //获取初始的模板 this.template = this.el.innerHTML this.rander() //初次渲染 this.wacth() //调用监听 } rander() { let that = this //读取{{}}包起来的内容 替换 //{{}} this.el.innerHTML = this.template.replace(/\{\{[\w.]+\}\}/g, function (v) { //表示匹配的内容 // v {{message}} ==> 你好啊 let key = v.substr(2, v.length - 4) return that.data[key] //调用get }) //读取对应的input的v-model属性 //找所有的input框 在input在所有有对应的v-model属性 将他里面的value值变了 Array.from(this.el.querySelectorAll('input')) //得到所有代理v-model属性的input框 .filter((input) => input.attributes['v-model']) //接着遍历 .forEach(vmInput => { //给对应的value进行赋值 vmInput.value = that.data[vmInput.getAttribute('v-model')]//调用get //给对应的input框添加事件 oninput事件 vmInput.oninput = function () {//观察者 that.data[vmInput.getAttribute('v-model')] = this.value//调set vmInput.focus() //获取焦点 } }) } //监听 wacth() { let _this = this Object.keys(this.data).forEach(key => { _this.mockData[key] = _this.data[key] //初始赋值操作 Object.defineProperty(_this.data, key, { get() { return _this.mockData[key] }, set(value) { _this.mockData[key] = value _this.rander() } }) }) } } new Vue({ el: "#app", data: { message: title:'你好' } }) </script>