让前端飞

对象的属性、方法

2019-10-22  本文已影响0人  大大的小小小心愿

一、对象实例的属性和方法

对象实例常用的属性、方法如下:

名称 描述 参数 返回 属性/方法
constructor (1)保存当前对象的构造函数 ,指向原始的 Object() 函数;
(2)一个类可有多个构造函数,可根据参数个数不同或参数类型不同去区分
/ / 属性
hasOwnProperty(propertyName) 用来判断该属性是否在当前对象实例中,而不是在对象的原型链中 接收一个字符串参数表示属性名 boolean 方法
isPrototypeOf(obj) 判断当前对象 是否在 传入的对象的原型链上 接收一个对象 boolean 方法
propertyIsEnumerable(prototypeName) 判断该属性是否可被 for...in 枚举 接收一个属性 boolean 方法
toString() 返回对象的字符串表示 / String 方法
valueOf() 返回对象的原始值 / / 方法

以下是具体是使用方法:
1、constructor

let person = {
    name: '大大的小小小心愿', 
    age: '25'
}
console.log(person);             // obj
console.log(person.constructor); // function String

2、hasOwnProperty(propertyName)

let person = {
    name: '大大的小小小心愿', 
    age: '25'
}
let arr1 = [];
console.log(person.hasOwnProperty("age"))            // true
console.log(person.hasOwnProperty("hasOwnProperty")) // false
console.log(arr1.hasOwnProperty("length"))           // true

3、isPrototypeOf(obj)

    function MyObject3(){};
    let obj3 = new MyObject3();
    console.log(Object.prototype.isPrototypeOf(obj3));                     // true
    let obj33333 = {}
    console.log('obj33333 ===', Object.prototype.isPrototypeOf(obj33333)); // true

4、propertyIsEnumerable

   let obj4 = {
        name:'objName'
    }
    for (const key in obj4) {
        console.log(key);  // name
    }
    console.log(obj4.propertyIsEnumerable("name"));        // true
    console.log(obj4.propertyIsEnumerable("constructor")); // false

5、toString()

    let obj5 = {};
    let date5 = new Date();
    console.log(obj5.toString());   // '[object Object]'
    console.log(date5.toString());  // 'Tue Oct 22 2019 11:07:10 GMT+0800 (中国标准时间)'

6、valueOf()

    let obj6 = {
        name:'obj6'
    }
    let val6 = [1];
    const date6 = new Date();
    console.log(obj6.valueOf());  // {name: "obj6"}
    console.log(val6.valueOf());  // [1]
    console.log(date6.valueOf()); // 1571713630704

二、属性的类型

  • 分类:JavaScript 中属性分为两种 - 数据属性、访问器属性;
  • 特性:ES5定义的描述属性的各种特征,是内部值无法直接访问;
  • 区别:
    数据属性 - 拥有 Get、Set 方法,无 [[Writable]]、[[Value]] 两个特性
    访问器属性 - 拥有 [[Writable]]、[[Value]] 两个特性,无 Get、Set 方法
1、属性的特性:用两对中括号表示 ( [[ ]] )
名称 描述 默认值 备注
[[Configurable]] 表示是否可以通过 delete 操作符来删除属性 true /
[[Enumerable]] 表示是否能通过 for...in 语句枚举 实例默认为 true,原型链中默认 false /
[[Writable]] 表示 属性值是否可以修改 true 数据属性特性
[[Value]] 表示 属性的名称 undefined 数据属性特性
[[Get]] 读取属性时调用的函数 undefined 访问器属性特性
[[Set]] 写入属性时调用的函数 undefined 访问器属性特性
2、读取、操作特性

1、特性:

名称 描述 参数 备注
[[Configurable]] 表示是否可以通过 delete 操作符来删除属性 true /
[[Enumerable]] 表示是否能通过 for...in 语句枚举 实例默认为 true,原型链中默认 false /
[[Writable]] 表示 属性值是否可以修改 true 数据属性特性
[[Value]] 表示 属性的名称 undefined 数据属性特性
[[Get]] 读取属性时调用的函数 undefined 访问器属性特性
[[Set]] 写入属性时调用的函数 undefined 访问器属性特性

2、读取、操作特性

名称 描述 参数 备注
defineProperty(obj, proname, defineProperty) 修改某个属性的特性 1、obj:操作对象;
2、proname:需被定义的属性;
3、defineProperty:特性的修改
/
defineProperties(obj, defineProperty) 修改多个属性的特性 1、obj:操作对象;
2、defineProperty:多个属性的特性修改
/
getOwnPropertyDescriptor(obj, defineProperty) 获取属性特性的描述 1、obj:操作对象;
2、defineProperty:需获取特性的属性
/

使用方法:
defineProperty:

let obj311 = {};
Object.defineProperty(obj311, 'name', {
    value: 'name',       // 属性的名称
    configurable: true,  // 是否能通过 delete 操作符 删除属性
    writable: true,      // 属性值是否可以修改
    enumerable: false,   // 是否能通过 for..in 枚举出属性,默认 实例 true,原型链 false
})
console.log(obj311);
console.log(Object.getOwnPropertyDescriptor(obj311, 'name'));  // {value: "name", writable: true, enumerable: false, configurable: true}

defineProperties:

let obj321 = {};
Object.defineProperties(obj321, {
    "name": {
        value: 'name',
        configurable: true,
        writable: true,
        enumerable: true,
    },
    "age": {
        value: 20,
        enumerable: true,
        configurable: true,
        writable: true
    }
})
console.log(obj321.name);
console.log(obj321.age);
console.log(Object.getOwnPropertyDescriptor(obj321, 'name')); // {value: "name", writable: true, enumerable: true, configurable: true}
console.log(Object.getOwnPropertyDescriptor(obj321, 'age'));  // {value: 20, writable: true, enumerable: true, configurable: true}

getOwnPropertyDescriptor :

let obj331 = {
    _age: 10,
    type:'小孩'
}; 
Object.defineProperty(obj331, 'age' , {
    get:function(){
        return this._age;
    },
    set:function(newV){
        this._age = newV;
        this.type = newV > 17 ? '成年人' : '小宝宝';
        this.age = newV;  // 访问属性本身,会无限递归导致内存泄漏。
    }
})
obj331.age = 2;
console.log(Object.getOwnPropertyDescriptor(obj331, 'type'));  // Object  {value: "小宝宝", writable: true, enumerable: true, configurable: true}
console.log(Object.getOwnPropertyDescriptor(obj331, 'age'))    // Object  {get: ƒ, set: ƒ, enumerable: false, configurable: false}

注:
1、访问器属性 Get、Set 不能用 this 访问属性本身,会导致无限递归,从而引发内存泄漏。
2、特性修改只能修改一次,再次修改会报错。(Get、Set 作为方法,除外。)

三、ES5 新增方法:

名称 描述 参数
create() 创建对象 \
keys(obj) 获取给定对象的所有可用枚举的自身的属性名,返回一个数组 obj:需获取属性的对象
getOwnPropertyNames(obj) 获取对象所有属性,包括可枚举和不可枚举所有属性 obj:需获取属性的对象

使用方法:
create():

let obj = Object.create();
obj.name = 'myname';

let obj421 = Object.create(Object.prototype, {
    name: {
        value: 'Jack'
    }
})
console.log(obj421.name);  // Jack ,且继承了 Object 的原型

keys(obj):

function objFn421(){
    this.laskName = 'Black'
}
function objChildFn421(firstName){
    this.firstName = firstName;
}
objChildFn421.prototype = new objFn421();

let sonObj421 = new objChildFn421("Jack");
console.log(Object.keys(sonObj421)); // [Jack]   并没有返回从prototype继承而来的lastName和不可枚举的相关属性
console.log(sonObj421);

getOwnPropertyNames(obj):

console.log('Object.getOwnPropertyNames =====>') 
function objFn431(){
    this.laskName = 'Black';
}

function childFn431(firstName){
    this.firstName = firstName;
}
childFn431.prototype = new objFn431();

let sonObj431 = new childFn431('Rost');
Object.defineProperty(sonObj431, 'age', {
    enumerable: false
})
console.log(Object.keys(sonObj431));                // ["firstName"]
console.log(Object.getOwnPropertyNames(sonObj431)); // ["firstName", "age"]

四、对象限制型方法:

名称 描述 备注
preventExtensions(obj) 防止对象扩展 用来限制对象的扩展,设置后 将无法添加新属性
①、可阻止对象属性扩展
②、对象属性可删除
④、无法添加新属性 指 无法在自身添加新属性,原型链上 仍可添加新属性。
⑤、可通过 Object.isExtensible(obj):判断一个对象是否可扩展,默认 true
seal(obj) 密封对象 使对象无法添加、删除已有属性,也无法修改 enumerable、writable、configurable 特性
①可以修改属性值
②该方法返回被封密 的对象
③可通过 Object.isSealed(obj):判断对象是否被封密
freeze(obj) 冻结对象 该方法用来冻结一个对象,被冻结的对象无法添加、修改、删除属性值,无法修改属性的特性值,即该对象无法被修改
①、无法删除、修改自身属性;原型链上的属性可以修改、添加
②、可通过 Object.isFrozen(obj):判断一个对象是否被冻结,默认 false

使用方法:
1、Object.preventExtensions(Object):
   (1)使用

function ObjFn511(name){
    this.name = name;
}
let person511 = new ObjFn511('Jack');
Object.preventExtensions(person511);

console.log(person511.name);  // Jack

person511.age = 20;
console.log(person511.age);   // undefined 

delete person511.name;
console.log(person511.name);  // undefined

ObjFn511.prototype.pro_age = 15;
console.log(person511, person511.pro_age);  // 15

   (2)判断对象是否可扩展 isExtensible()

console.log(Object.isExtensible(person511));  // false

2、Object.seal(obj):
   (1)使用

function PersonFn521(name){
    this.name = name;
}
let person521 = new PersonFn521('Seal');
let person522 = Object.seal(person521);
console.log(person522)  // PersonFn521 {name: "Seal"}

delete person521.name;
console.log(person521.name);  // Seal

   (2)判断对象是否被封密 isSealed()

console.log(Object.isSealed(person521)) // true

3、Object.freeze():
   (1)使用

function PersonFn531(name){
    this.name = name;
}
let person531 = new PersonFn531('Freeze');

Object.freeze(person531);

person531.name = 'newName';
PersonFn531.prototype.age = 20;
console.log(person531.name);    // Freeze
console.log(person531.age);     // 20

   (2)判断一个对象是否被冻结 isFrozen()

console.log(Object.isFrozen(person531)); // true

参考文献:https://blog.csdn.net/weixin_30701575/article/details/96721871

https://www.cnblogs.com/shiningly/p/9482283.html?utm_source=debugrun&utm_medium=referral

上一篇 下一篇

猜你喜欢

热点阅读