大家都知道对象都是属于Object类型的。下面是一些详细总结,希望可以帮助到有需要的小伙伴。
JavaScript面向对象之Object类型
- 在JS中所有的对象都拥有同一个父级,就是Object.
- Object提供了属性和方法,在JS的所有对象里面都是可以被直接使用的。因为Js中所有对象都是继承于Object的。
- Object创建对象的两个方式:
- new Object
- create Object
Object 构造函数创建一个对象包装器。
语法:
// 对象初始化器(Object initialiser)或对象字面量(literal)
{ [ nameValuePair1[, nameValuePair2[, ...nameValuePairN] ] ] }
// 以构造函数形式来调用
new Object([value])
参数:
nameValuePair1, nameValuePair2, ... nameValuePairN
成对的名称(字符串)与值(任何值),其中名称通过冒号与值分隔。
value
任何值
描述:
在JavaScript中,几乎所有的对象都是Object
类型的实例,它们都会从Object.prototype
继承属性和方法。Object
构造函数为给定值创建一个对象包装器。Object
构造函数,会根据给定的参数创建对象,具体有以下情况:
- 如果给定值是 null 或 undefined,将会创建并返回一个空对象
- 如果传进去的是一个基本类型的值,则会构造其包装类型的对象
- 如果传进去的是引用类型的值,仍然会返回这个值,经他们复制的变量保有和源对象相同的引用地址
当以非构造函数形式被调用时,Object
的行为等同于 new Object()
Object创建对象实例:
// 表示创建一个空对象
var obj1 = new Object(null);
var obj2 = new Object(undefined);
// 表示创建一个与给定值对应类型的对象
var obj3 = new Object(100);
console.log(obj3); // [Number: 100]
var num = new Number(100);
console.log(num); // [Number: 100]
// 当以非构造函数形式被调用时,Object等同于new Object()
var obj4 = Object(); // 函数调用
var obj5 = new Object(); // 构造函数调用
Object函数的属性
Object.length
值为1
Object.prototype
可以为所有Object类型的对象添加属性。
Object函数的方法
通过复制一个或多个对象来创建一个新的对象。
使用指定的原型对象和属性创建一个新对象。
给对象添加一个属性并指定该属性的配置。
给对象添加多个属性并分别指定它们的配置。
返回给定对象自身可枚举属性的 [key, value]
数组。
冻结对象:其他代码不能删除或更改任何属性。
Object.getOwnPropertyDescriptor()
返回对象指定的属性配置。
返回一个数组,它包含了指定对象所有的可枚举或不可枚举的属性名。
Object.getOwnPropertySymbols()
返回一个数组,它包含了指定对象自身所有的符号属性。
返回指定对象的原型对象。
比较两个值是否相同。所有 NaN 值都相等(这与和=不同)。
判断对象是否可扩展。
判断对象是否已经冻结。
判断对象是否已经密封。
返回一个包含所有给定对象自身可枚举属性名称的数组。
防止对象的任何扩展。
防止其他代码删除对象的属性。
设置对象的原型(即内部 [[Prototype]]
属性)。
返回给定对象自身可枚举值的数组。
1、属性描述符
JavaScript提供了一个内部数据结构,用于描述对象的值,控制其行为,例如该属性是否可写、是否可配置、是否可修改以及是否可枚举等。这个内部数据结构被称为“属性描述符”。
每个属性都有自己对应的属性描述符,保存该属性的元信息。
{
value: '卧龙学苑',
writable: false,
enumerable: true,
configurable: false,
get: undefined,
set: undefined
}
对象里目前存在的属性描述符有两种主要形式:数据描述符和存取描述符。
2、数据描述符
数据描述符是一个具有值的属性,该值可能是可写的,也可能不是可写的。数据描述符具有以下可选键值:
- value:该属性对应的值。可以是任何有效的JavaScript值(数值,对象,函数等)。默认为undefined。
- writable:当且仅当该属性的writable为true时,value才能被赋值运算符改变。默认为false
- configurable:当且仅当该属性的configurable为true时,该属性描述符才能够被改变,同时该属性也能从对应的对象上被删除。默认为false。
- enumerable:当且仅当该属性的enumerable为true时,该属性才能够出现在对象的枚举属性中。默认为false。
3、存取描述符
存取描迹符是由getter-setter函数对描述的属性。存取描述符具有以下可选键值:
-
get:给属性提供getter的方法,如果没有getter则为undefined。当访问该属性时,该方法会被执行,方法执行时没有参数传入,但是会传入this对象。
-
set:给属性提供setter的方法,如果没有setter则为undefined。当属性值修改时,触发执行该方法。该方法将接受唯一参数,即该属性新的参数值。
-
configurable:当且仅当该属性的configurable为true时,该属性描述符才能够被改变,同时该属性也能从对应的对象上被删除。默认为false。
-
enumerable:当且仅当该属性的enumerable为true时,该属性才能够出现在对象的枚举属性中。默认为false。
4、获取描述符
Object.getOwnPropertyDescriptor()方法返回指定对象上一个自有属性对应的属性描述符。
Object.getOwnPropertyDescriptor(obj, prop)
- obj:需要查找的目标对象。
- prop:目标对象内属性名称( String类型)。
- 返回值:如果指定的属性存在于对象上,则返回其属性描述符对象,否则返回undefined。
注意:如果该方法的第一个参数不是对象,会报错(TypeError )
var obj=0
obj.attr ='卧龙学苑;
/*
{value:“卧龙学苑" , writable: true, enumerable: true, configurable: true}
*/
console.log(Object.getOwnPropertyDescriptor(obj,'attr'));
举例:
/*
通过定义对象(属性或方法)这种方式
* 属性默认都是数据描述符
*/
var obj = {
name:'孙悟空'
}
/*
使用Object.getOwnPropertyDescriptor()方法获取指定属性的描述符
Object.getOwnPropertyDescriptor(obj,prop)
* obj - 表示指定属性对应的描述对象
* prop - 表示获取描述符的目标属性名称
* 返回值 - 其属性描述符对象
*
*/
var result = Object.getOwnPropertyDescriptor(obj,'name');
console.log(result);
// { value: '孙悟空', writable: true, enumerable: true, configurable: true }
console.log(result.value);
// 孙悟空
5、设置属性描述符
-
ObjectdefineProperty()方法为对象定义新属性或修改现有属性,并返回该对象。
Object.defineProperty(obj, prop, descriptor)
- obj:要在其上定义属性的对象。prop:要定义或修改的属性的名称。
- descriptor:将被定义或修改的属性描述符。返回值:被传递给函数的对象。
-
Object.defineProperties()方法为对象定义一个或多个新属性或修改现有属性,并返回该对象。
Object.defineProperties(obj,props)
- obj:要在其上定义属性的对象。
- props:要定义其可枚举属性或修改的属性描述符的对象。
- 返回值:被传递给函数的对象。
(1) 属性描述符的可选键值
-
value:表示目标属性对应的值。可以是任何有效的JavaScript值(数值,对象,函数等)。默认为undefined。
var obj= t;obj.p= 123; var attr = Object.getOwnPropertyDescriptor(obj, 'p'); console.log(attr.value);// 123 Object.defineProperty(obj, 'p', { value: 246}); console.log(obj.p)// 246
说明:直接定义对象的属性,该属性既可以读取,也可以修改。
实例:
var obj = {
// 定义对象的同时定义了该属性以及值(可修改、可删除以及可枚举的)
name:'张无忌'
}
/*
Object.defineProperty(obj,prop,desc)方法
* 作用:
* 用于定义目标对象的新属性
* 用于修改目标对象的已存在属性
* 参数
* obj - 表示目标对象
* prop - 表示目标对象的目标属性名称
* desc - 表述属性描述符,必须是对象格式
{
value:值
}
* 返回值 - 返回传递的对象
*/
Object.defineProperty(obj,'name',{
value:"周芷若"
});
console.log(obj.name); // 周芷若
/*
同样是为对象新增属性
1.如果直接使用“ 对象名.属性名 = 值” -> 可修改、可删除以及可枚举的
2.如果使用Object.defineProperty()方法新增属性
* 该新属性是不可修改、不可删除以及不可枚举的
*/
Object.defineProperty(obj,'age',{
value : 18
});
console.log(obj.age); // 18
var result = Object.getOwnPropertyDescriptor(obj,'age');
console.log(result);
// 一旦属性的值是不可修改的 - 如果执行修改操作时 -> 没有语法报错,但是无效
obj.age = 80;
console.log(obj.age); // 18 没有修改成80
obj.job = '教主';
var result2 = Object.getOwnPropertyDescriptor(obj,'job');
console.log(result2);
// { value: '教主', writable: true, enumerable: true, configurable: true }
(2)属性描述符的可选键值
-
writable: Boolean值,表示目标属性的值是否可以被修改。当且仅当该属性的writable为true时,value才能被赋值运算符改变。默认为false。
```js
var obj= t;
Object.defineProperty(obj, ‘attr’, {
value: ‘卧龙学苑’,
writable: false
);
console.log(obj.attr);//卧龙学苑
obj.attr = 100;
console.log(obj.attr);//卧龙学苑
```
实例:
var obj = {
sayMe : function(){
console.log('this is function')
}
}
var result = Object.getOwnPropertyDescriptor(obj,'sayMe'); // sayMe是方法名
console.log(result);
Object.defineProperty(obj,'sayMe',{
value : function(){
console.log('this is new function');
},
writable : false
});
obj.sayMe(); // this is new function
obj.sayMe = function(){
console.log('这是张无忌');
}
obj.sayMe(); // this is new function
(3)属性描述符的可选键值
-
configurable:Boolean值,表示目标属性的描述符是否可以被修改。当且仅当该属性的configurable为true时,该属性描述符才能够被改变,同时该属性也能从对应的对象上被删除。
默认为false.
var obj = Object.defineProperty(0, 'attr', { value: '卧龙学苑', configurable: false }); // TypeError: Cannot redefine property: attrObject.defineProperty(obj, 'attr', {value: 100}); Object.defineProperty(obj, 'attr', {writable: true}); Object.defineProperty(obj, 'attr', {enumerable: true}); Object.defineProperty(obj, 'attr', {configurable: true});
(4)属性描述符的可选键值
-
enumerable:Boolean值,表示目标属性是否可遍历。
当且仅当该属性的enurmerable为true时,该属性才能够出现在对象的枚举属性中。
默认为talse。
如果对象的属性的enumerable的值为false,以下三种操作取不到该属性:
- for…in语句
- Object.keys()方法
- JSON.stringify()方法
var obj= {}; object.defineProperty(obj, 'attr', { value: '卧龙学苑', enumerable: false }); for (var key in obj) { console.log(key); //没有任何输出 console.log(Object.keys(obj)); // [] console.log(JSON.stringify(obj));// " {} "
6、属性描述符的存取器
对象的属性除了可以直接定义以外,还可以使用存取器进行定义。其中
setter为存值函数,使用属性描述符中的set
getter为取值函数,使用属性描述符中的get
注意:
- get()函数
- get()函数不能有参数,调用get()方法时,允许传递this关键字
- this表示当前的目标对象(不能调用对象自己的目标属性)
- 返回值 return this ,this后面不能加任何东西。(如:return this.name就是错的)
- set()函数
- 修改值的过程要借助全局变量完成,修改 -> 赋值 -> 调用
- set()方法允许有参数
- set()方法在被调用时,允许传递this关键字
- this - 表示当前的目标对象(不能调用对象的当前目标属性)
var obi= Qbject.defineProperty(, 'attr', {
get: function (){
return '卧龙学苑';
},
set: function (value){
console.log('setter: ' + value);
}
);
console.log(obj.attr);/I"卧龙学苑"obj.attr = 100;// "setter: 100"
JavaScript中除了上逑存取器的写法之外,还提供了以下写法:
var obj= {
get attr() {
return '卧龙学苑';
},
set attr(value) {
console.log('setter : ' + value);
}
}
console.log(obj.attr);//"卧龙学苑"
obj.attr = 100;// "setter: 100"
实例:
var obj = {
name : '张无忌'
}
var value; // 全局变量
Object.defineProperty(obj,'name',{
// 获取指定的属性值
get : function(){ // 不能传参数 当获取或访问当前属性时,会调用get方法
console.log('this is get function');
// return 100; // 类似于数据描述符中的value
/*
类似于数据描述符中的value
* get方法在被调用时,不能传递任何参数
* get方法在被调用时,允许传毒this关键字
* this - 表示当前的目标对象(不能调用对象的当前目标属性)
*/
//return this; // { name: [Getter] } (Getter是类型)
return value; // 由于变量未初始化,调用时可能结果为undefined
},
/*
set方法用于定义当前目标属性的修改作用
* 该方法接收唯一的一个参数 -> 作为当前目标属性的新的值
* 通过属性修改操作指定的新的值 -> 作为形参对应的实参
*/
// 修改 -> 赋值 -> 调用
set : function(newValue){ // 借助全局变量修改值
console.log('this is set function' + value); // this is set function赵敏
/*
//console.log(this); // { name: [Getter/Setter] }
set方法在被调用时,允许传递this关键字
* this - 表示当前的目标对象(不能调用对象的当前目标属性)
// this.name = value; // 不能改变值
*/
value = newValue;
}
});
// console.log(obj.name);
/*
this is get function
周芷若
*/
console.log(obj.name); // undefined
// 修改属性的值
obj.name = '赵敏';
console.log(obj.name); // set()方法被调用,但值没有被改变
/*
this is set functionundefined
this is get function
赵敏
*/
// 注意get()方法:
/*
1. 不能传参,要传的话,只能传this (this表示目标对象)
2. 返回值 return this 就结束了,不能在this后面加东西了 如(this.name就是错的)
*/
7、防篡改是什么
定义的对象默认在任何时候、任何位置,无论有意义的还是无意义的都可以修改对象的属性或方法。而这些篡改可能会影响对象的内置属性或方法,从而导致对象的正常功能可能无法使用。
JavaScript在ECMAScript 5版本中新增了放置篡改对象的属性或方法的机制,共提供了以下三级保护方式:
- 禁止扩展:禁止为对象扩展新的属性或方法
- 密封对象:禁止扩展新的属性或方法,禁止配置现有的属性或方法的描述符,仅允许读写属性的
- 冻结对象:禁止对对象执行任何修改操作。
(1)禁止扩展
如果禁止为对象扩展新的属性或方法,需要修改对象属性的extensible为falseo
- Object.preventExtensions()方法用于设置指定对象不可扩展,即不能新增属性或方法。
- Object.isExtensible()方法判断一个对象是否是可扩展的(是否可以在它上面添加新的属性)。
var obj= {};
Object.preventExtensions(obj);
obj.attr='卧龙学苑';
console.log(Object.isExtensible(obj));// false
console.log(obj.attr);// undefined
实例:
var obj = {};
// 将对象设置禁止扩展
Object.preventExtensions(obj);
// 新增属性或方法无效 -> 语法没有报错
obj.name = '张无忌';
console.log(obj);
/*
Object.defineProperty()方法新增属性
* 结果 - 报错
* 信息 - Cannot define property name, object is not extensible 表示指定目标是不可扩展的
*/
Object.defineProperty(obj,'name',{
value : '周芷若'
});
console.log(obj);
/*
Object.isExtensible(obj)方法
* 作用 - 用于判断指定目标对象是否可扩展
* 返回值
* true - 表示指定目标是可扩展的
* false - 表示指定目标是不可扩展的
*/
var result = Object.isExtensible(obj);
console.log(result); // false
(2)密封对象
密封对象,就是指禁止为对象扩展新的属性或方法,并且禁止修改现有属性的描迹符。
- Obiectseal()方法用于封闭一个对象,阻止添加新属性并将所有现有属性标记为不可配置。当前
属性的值只要可写就可以改变。 - Obiect.isSealed(方法判断一个对象是否被密封。
//最简单的方法来生成一个密封对象,当然是使用Object.seal.
var sealed = {};
Object.seal(sealed);
Object.isSealed(sealed); // === true
//一个密封对象同时也是不可扩展的.
Object.isExtensible(sealed); // === false
实例:
var obj = {
name : '张无忌' // 默认是可修改的
};
console.log(Object.getOwnPropertyDescriptor(obj,'name'));
/*
将该对象进行密封
1.不能为该对象新增属性或方法
2.不能修改该对象的属性或方法的描述符
* configurable
* enumerable
*/
Object.seal(obj);
console.log(Object.getOwnPropertyDescriptor(obj,'name'));
/*
// 新增属性
obj.age = 18;
console.log(obj);
// 修改属性
obj.name = '周芷若';
console.log(obj);
*/
/*
Object.defineProperty(obj,'age',{
value : 18
});
*/
//通过描述符修改值
Object.defineProperty(obj,'name',{
value : '周芷若',
writable : false, // 表示不可修改
configurable : true, // 可以被删除
enumerable : false // 可以枚举
});
console.log(obj);
obj.name = '赵敏';
console.log(obj);
(3)冻结对象
冻结对象,就是指禁止对对象执行任何修改操作。
- Objectfreeze)方法用于冻结一个对象,冻结指的是不能向这个对象添加新的属性,不能修改其已有属性的值,不能删除已有属性,以及不能修改该对象已有属性的可枚举性、可配置性、可写性。该方法返回被冻结的对象。
- Obiect.isEcozen(方法判断一个对象是否被冻结。
// 使用Object.freeze是冻结一个对象最方便的方法.var frozen = { 1:81};
Object.isFrozen(frozen)//=== falseObject.freeze(frozen);
Object.isFrozen(frozen)//=== true
Object.isSealed(frozen)//一个冻结对象也是一个密封对象.
Object.isExtensible(frozen)//当然,更是一个不可扩展的对象.
实例:
var obj = {
name : '张无忌'
}
// 冻结对象
Object.freeze(obj);
/*
obj.age = 18; // 不能增加 { name: '张无忌' }
console.log(obj);
obj.name = '周芷若'; // 不能修改 { name: '张无忌' }
console.log(obj);
delete obj.name; // 不能删除 { name: '张无忌' }
console.log(obj);
*/
// 通过描述符修改
Object.defineProperty(obj,'age',{
value : 18
});
console.log(obj); // 报错:Cannot define property age, object is not extensible
青春就是用来拨开迷茫的雾,遇见真实的自己的。
我知道自己做的不好,但是历练过的,当真都被时间沉淀成了本事。
爱笑的女孩运气都不会差,加油吧
希望看到这篇博客的你,也可以鼓起勇气,去面对困难和挑战。