JS高级—07—对象;函数;数组;
一、对象
对象的属性的增删改查:
增:object.defineProperty(),obj.xxx; 删:delte obj.xxx; 改:object.defineProperty(),obj.xxx = xxxxxx; 查:Object.getOwnPropertyDescritors();//不管是否为enumable:false,都可以便利出来;
Object.keys() Object.hasOwnProperty()//不查原型;
in操作符//查原型
对象的属性的增删改查:
preventExtensions,不能添加新的属性;
seal:不能添加新的属性外,还不能修改原有属性,还不能删除原有属性;
freeze:不能添加新的属性外,还不能修改原有属性,还不能删除原有属性;还不能修改原有属性的value;
1.1概念
1.2定义对象的两种方式
除了这两种,还可以使用new 构造函数或
new 构造函数+原型;
1.3对对象属性的控制之数据属性描述符
当我们直接在一个对象上定义某个属性时: 指这种方式: const obj ={ name:"kobe" }
当我们通过属性描述符定义一个属性时: 指这种方式: Object.defineProperty = { obj, "age", { 18 } }
数据属性的
- 增configurable对象能否新增属性
- 删configurable对象属性能否删除
- 改 writeable对象的属性的值能否修改
- 查 enumable对象属性能够遍历
1.4对对象属性的控制之存取属性描述符
可以像闭包一样的,定义对象的私有属性;
1.5同时定义多个属性
1.6对象的其他方法
1.6.1关于对象属性的其他方法
有一些属性不能从forin或者object.keys()获取,因为他们的enumable属性设为false,
这个时候只能用getOwnPropertyDescriptors方法来获取;
对象的属性的数据的增删改查
preventExtensions,不能添加新的属性;
seal:不能添加新的属性外,还不能修改原有属性,还不能删除原有属性;
freeze:不能添加新的属性外,还不能修改原有属性,还不能删除原有属性;还不能修改原有属性的value;
object方法:
OBject.keys()获取对象的keys,返回一个数组:
Object.values()获取对象的values,返回一个数组:
Object.entries()获取对象的key和value,返回一个二维数组,比如[[name, why], [age, 18]]:
OBject.fromEntry()从一个entry转化为对象
判断两个值是否相等,和===很像,但有区别,区别在于NaN使用此方法判断是返回true,但使用===判断时返回false
2、object.assign()
1.6.2关于对象如何判断一个属性是否存在
Object.prototype.hobby = 'basketball' const mySymbol = Symbol('本对象上的可遍历symbol值') const mySymbol2 = Symbol('本对象上的不可遍历symbol值') const mySymbol3 = Symbol('Object.prototype定义的symbol值') Object.prototype[mySymbol3] = 'i am a symbol3333' const foo = { name:'kobe', age:18, [mySymbol]:'i am a symbol', } Object.defineProperty(foo,'address',{ configurable:true, enumerable:false, writable:true, value:'xxxxxxx' }) Object.defineProperty(foo,mySymbol2,{ configurable:true, enumerable:false, writable:true, value:'i am symbol2222222' }) console.log(Object.getPrototypeOf(foo)); // foo现在一共六个属性, // address属性不可枚举,hobby属性在原型上;mysymbol是可遍历的symbol值,mysymbol是不可遍历的symbol值; console.log(foo.hasOwnProperty('name')); // true console.log(foo.hasOwnProperty('address')); //true console.log(foo.hasOwnProperty(mySymbol)); //true console.log(foo.hasOwnProperty('hobby')); //false //担心hasOwnProperty被重写,可以用这个方法;console.log(Object.prototype.hasOwnProperty.call(foo,'name')) //true for (const key in foo) { console.log(key); //name age hobby }
console.log(Object.keys(foo)); //[ 'name', 'age' ] console.log(Object.getOwnPropertyNames(foo)); //[ 'name', 'age', 'address' ] console.log(Object.getOwnPropertySymbols(foo)); //[ Symbol(mySymbol), Symbol(mySymbol22222) ] console.log(Object.getOwnPropertyDescriptors(foo)); // name: { // enumerable: true,。。。。。。。。。 // }, // age: { value: 18, writable: true, enumerable: true, configurable: true }, // address: { // enumerable: false,。。。。。。。。 // }, // [Symbol(mySymbol)]: { // enumerable: true,。。。。。。。。 // }, // [Symbol(mySymbol22222)]: { // enumerable: false, // } // } //IN 刚好相反:会遍历到可枚举的东西,但是会遍历原型, SYMBOL不可以遍历 //总结:这四个都不可以遍历原型;
//OBject.keys(),遍历可枚举、不symbol、不原型;
//Object.prototype.hasOwnProperty会遍历到不可枚举的东西,但是不会遍历原型, SYMBOL可以遍历 这个方法和getOwnPropertyDescriptors很像,只不过这个只是单纯的判断是否存在,只是单纯的反回boolean; // Object.getOwnPropertyNames 可以遍历不可枚举的东西,但是不会遍历原型,不能symbol // Object.getOwnPropertySymbols 可以遍历不可枚举的symbol;不遍历原型;之遍历symbol; // Object.getOwnPropertyDescriptors 会遍历到不可枚举的东西,不会遍历原型, 遍历symbol 这个方法就是上面两个的合体;
1.6.3关于对象判断的它原型是什么?
obj1 instanceOf function1 : 简单说:见名知意,判断obj1是否是构造函数function1的实例对象;复杂说:判断一个构造函数function1,其函数原型是否出现在obj2的原型链上;
Object.isPrototypeOf(): 上面的是判断一个构造函数,本方法判断一个对象,这就是区别;或者看方法的名字,obj isPrototypeOf XXX,obj对象是不是XXX的原型对象;
Object.getPrototypeOf(): 获取对象的原型 注意:和obj.__proto__一样,都是取对象原型,但是.__proto__不是ecma规范
Object.setPrototypeOf(): 设置对象的原型 注意:和Object.create()的区别,Object.create(xxx)是创建一个以xxx为原型的对象并返回;
1.6.3typeof和instanceof联合使用判断数据类型
typeof基本数据类型判断不出null,引用数据类型判断不出array和实例对象;
typeof(xxx) : 判断数据类型,返回值有number、string、boolean、function、undefined、object 六个。
但是typeof判断null、array、object以及函数实例对象时,它返回的都是object;剩下四个,分别可以用xxx === null xxx instanceof Array xxx instanceOf Object xxx instanceOf 某个构造函数名 判断;
function foo(params) {
}
//问题:这三个都是onject;
console.log(typeof(foo)); //function
console.log(typeof([]));// object
console.log(typeof(null));// object
console.log(typeof(new foo()));// object
//解决:
console.log(null === null ); //true
console.log(foo instanceof Function ); //true
console.log((new foo()) instanceof Function); //这个是false,因为这是foo的实例对象
console.log((new foo()) instanceof foo); //true
二、函数与构造函数
2.1函数与构造函数
函数,既是函数又是对象,所以可以叫七函数对象; 所以既有函数原型foo.prototype又有对象原型foo.__proto__; 我们可以在函数对象 的函数原型上定义方法foo.prototype.bar = ()=>{},这样成了函数实例对象的方法; 我们可以在函数对象 的本身上定义方法foo.bar= function(){},这样成了函数的静态方法,可以通过foo.bar()直接调用,类似于类的静态方法; 我们也可以在函数对象的 对象原型上定义方法foo.__proto__.bar=()=>{},这样所以通过new Function()构造出来的实例都可以用这个方法了。
当我们new一个函数的时候,这个函数就是构造函数,一般默认将构造函数名大写;
我们现在可以通过构造函数来创建一个原型;
后面学习了原型后,我们可以通过构造函数+原型的方式更好的创建对象;
构造函数的this指向了新创建出来的ao对象,即new绑定规则;
构造函数会默认返回这个对象,默认返回!
2.2函数的补充
2.2.1参数默认值
2.2.2函数的剩余参数
2.3箭头函数
箭头函数没有this外,还没有显式原型,所以不能通过new来构造一个箭头函数;