JavaScript面向对象之Object类型

大家都知道对象都是属于Object类型的。下面是一些详细总结,希望可以帮助到有需要的小伙伴。

JavaScript面向对象之Object类型

  1. 在JS中所有的对象都拥有同一个父级,就是Object.
  2. Object提供了属性和方法,在JS的所有对象里面都是可以被直接使用的。因为Js中所有对象都是继承于Object的。
  3. Object创建对象的两个方式:
    1. new Object
    2. 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函数的方法

Object.assign()

通过复制一个或多个对象来创建一个新的对象。

Object.create()

使用指定的原型对象和属性创建一个新对象。

Object.defineProperty()

给对象添加一个属性并指定该属性的配置。

Object.defineProperties()

给对象添加多个属性并分别指定它们的配置。

Object.entries()

返回给定对象自身可枚举属性的 [key, value] 数组。

Object.freeze()

冻结对象:其他代码不能删除或更改任何属性。

Object.getOwnPropertyDescriptor()

返回对象指定的属性配置。

Object.getOwnPropertyNames()

返回一个数组,它包含了指定对象所有的可枚举或不可枚举的属性名。

Object.getOwnPropertySymbols()

返回一个数组,它包含了指定对象自身所有的符号属性。

Object.getPrototypeOf()

返回指定对象的原型对象。

Object.is()

比较两个值是否相同。所有 NaN 值都相等(这与=不同)。

Object.isExtensible()

判断对象是否可扩展。

Object.isFrozen()

判断对象是否已经冻结。

Object.isSealed()

判断对象是否已经密封。

Object.keys()

返回一个包含所有给定对象自身可枚举属性名称的数组。

Object.preventExtensions()

防止对象的任何扩展。

Object.seal()

防止其他代码删除对象的属性。

Object.setPrototypeOf()

设置对象的原型(即内部 [[Prototype]] 属性)。

Object.values()

返回给定对象自身可枚举值的数组。

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、设置属性描述符

  1. ObjectdefineProperty()方法为对象定义新属性或修改现有属性,并返回该对象。

    Object.defineProperty(obj, prop, descriptor)
    
    • obj:要在其上定义属性的对象。prop:要定义或修改的属性的名称。
    • descriptor:将被定义或修改的属性描述符。返回值:被传递给函数的对象。
  2. Object.defineProperties()方法为对象定义一个或多个新属性或修改现有属性,并返回该对象。

    Object.defineProperties(obj,props)
    
    • obj:要在其上定义属性的对象。
    • props:要定义其可枚举属性或修改的属性描述符的对象。
    • 返回值:被传递给函数的对象。
(1) 属性描述符的可选键值
  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)属性描述符的可选键值
  1. 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)属性描述符的可选键值
  1. 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)属性描述符的可选键值
  1. 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()函数
    1. get()函数不能有参数,调用get()方法时,允许传递this关键字
    2. this表示当前的目标对象(不能调用对象自己的目标属性)
    3. 返回值 return this ,this后面不能加任何东西。(如:return this.name就是错的)
  • set()函数
    1. 修改值的过程要借助全局变量完成,修改 -> 赋值 -> 调用
    2. set()方法允许有参数
    3. set()方法在被调用时,允许传递this关键字
    4. 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. 禁止扩展:禁止为对象扩展新的属性或方法
  2. 密封对象:禁止扩展新的属性或方法,禁止配置现有的属性或方法的描述符,仅允许读写属性的
  3. 冻结对象:禁止对对象执行任何修改操作。
(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


青春就是用来拨开迷茫的雾,遇见真实的自己的。
我知道自己做的不好,但是历练过的,当真都被时间沉淀成了本事。
爱笑的女孩运气都不会差,加油吧
希望看到这篇博客的你,也可以鼓起勇气,去面对困难和挑战。

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值