JavaScript~~Object 原型方法 和 Object方法

194 阅读8分钟

对象方法

一、Object原型方法

Object构造函数对应的原型中有很多方法,比较实用,如下:

console.log(Object.prototype)

1、hasOwnProperty

用于判断某个对象是否具有某个自带属性。自带属性,指的是自身就有的,而非继承来的,语法:

对象.hasOwnProperty(非继承属性) // 返回布尔值,true表示是,false表示否

例:

function Person(name, age) {
    this.name = name
    this.age = age
}
​
Person.prototype.sex = '男'var man = new Person('张三', 12)
​
console.log( man.hasOwnProperty('name') ); // true
console.log( man.hasOwnProperty('sex') ); // false
console.log( man.hasOwnProperty('height') ); // false

只有自己内非继承的属性才能返回true,继承的和不是自己的属性都是false。

2、isPrototypeOf(重点关注)

用于判断一个对象是否在另一个对象的原型链上。语法:

对象a.isPrototypeOf(对象b) // 判断对象a是否在对象b的原型链上,返回布尔值

例:

function Animal() {
​
}
​
var ani = new Animal()
​
function Bird() {
​
}
​
Bird.prototype = ani
​
var maque = new Bird()
​
console.log( Object.prototype.isPrototypeOf(maque) ); // true
console.log( ani.isPrototypeOf(maque) ); // true
var ani1 = new Animal()
console.log( ani1.isPrototypeOf(maque) ); // false

3、propertyIsEnumerable

用于判断是否可以从对象中遍历得到某个属性,语法:

对象.propertyIsEnumerable(属性名) // 返回布尔值

例:

function Person(name, age) {
    this.name = name
    this.age = age
}
​
Person.prototype.sex = '男'var man = new Person('张三', 12)
​
console.log( man.propertyIsEnumerable('name') ) // true - 自己的属性可以遍历
console.log( man.propertyIsEnumerable('sex') ) // false - 继承来的属性无法遍历

4、toString

用于将对象转成字符串,语法:

对象.toString() // 返回'[object Object]'
  // 顶级原型中的toString
var a = 10
console.log(a);
var a = new Number(10)
console.log(a);
var b = a.toString() // 数字对象中的toString
console.log(b);

var a = new Boolean(true) // 布尔类型中的toString
console.log(a);

var obj = {}
var str = obj.toString() // 顶级原型中的toString - [object Object]
console.log(str);

// 精准的检测对象类型的方法toString - 是顶级原型中的toString - 结果是 [object 数据在js中内置的构造函数的名称]
console.log(Object.prototype.toString.call(10)) // [object Number]
console.log(Object.prototype.toString.call(true)) // [object Boolean]
console.log(Object.prototype.toString.call('')) // [object String]
console.log(Object.prototype.toString.call(new Date)) // [object Date]
console.log(Object.prototype.toString.call(/a/)) // [object RegExp]

function Person(){}
var p = new Person()
console.log(Object.prototype.toString.call(p)) // [object Object]

console.log(Object.prototype);
var obj = {
    name: '张三',
    age: 12
}
console.log( obj.valueOf() );

5、其他

toLocaleStringvalueOf没有实际的效果,是为了让子原型能具备这些方法,来实现不同类型数据的功能。

toLocaleString给不同的数据调用会得到不同的数据:

// 对象调用
var obj = {name: '张三', age: 123456}
console.log( obj.toLocaleString() ); // [object Object]// 字符串调用
var str = 'abcdefg'
console.log( str.toLocaleString() );  // abcdefg// 数字调用
var num = 123456789
console.log( num.toLocaleString() ); // 123,456,789// 布尔值调用
var bool = true
console.log( bool.toLocaleString() ); // true// 时间日期对象调用
var date = new Date()
console.log( date.toLocaleString() ); // 2022/11/4 09:20:01

只有数字和时间日期对象调用的时候,能起到作用,其他类型的数据调用后,会默认调用toString方法转成字符串而已。

valueOf给不同类型的对象调用功能是不同的:

// 对象调用
var obj = {name: '张三', age: 123456}
console.log( obj.valueOf() ); // {name: '张三', age: 123456}// 字符串调用
var str = new String('abcdefg')
console.log( str.valueOf() );  // abcdefg// 数字调用
var num = new Number(123456789)
console.log( num.valueOf() ); // 123456789// 布尔值调用
var bool = new Boolean(true)
console.log( bool.valueOf() ); // true// 时间日期对象调用
var date = new Date()
console.log( date.valueOf() ); // 1667525014847

时间日期对象调用能获取到时间戳,其他类型的对象调用,会得到具体的值,相当于console.log(数组/对象)的值

二、Object方法

Object本身也有一些实用的方法:

console.dir(Object)

图示:

1、assign(重点关注)

用于将一个对象中可遍历的属性复制到另一个目标对象中,返回目标对象,语法:

var 新目标对象 = Object.assign(原目标对象, 被复制的对象)

例:

var obj = {
    name: '张三',
    age: 12
}
​
var pbj = {
    sex: '男',
    height: 180
}
​
pbj.__proto__.weight = 150 // 不可遍历属性无法复制
​
var qbj = Object.assign(obj, pbj) // 将pbj中的属性复制到obj中
​
console.log(obj); // {name: '张三', age: 12, sex: '男', height: 180}
console.log(qbj); // {name: '张三', age: 12, sex: '男', height: 180}
console.log(obj === qbj); // true

通常用于做浅克隆,将一个对象中的属性复制在另一个空对象中。

2、create(重点关注)

用于创建一个对象,并指定这个对象的原型,语法:

var 对象 = Object.create(指定的原型对象, {对象键值对的描述}) // 返回创建好的对象

参数1必填,例:

var obj = Object.create()

报错如下:

表示参数1必填,且参数必须是一个对象或null。

参数2是可选项,默认是空对象

例:

var obj = Object.create(null)
console.log(obj); // 这个对象没有原型

创建的是一个空对象,且这个对象没有原型,如下图:

var pro = {
    name: '张三'
}
​
var obj = Object.create(pro)
console.log(obj);

创建的是一个空对象,原型为pro对象,如下图:

参数2中的键,是对象要拥有的键,值必须是一个对象,用于对属性的描述,描述的对象语法如下:

{
  value: 123, // 属性的值
  writable: false, // 属性是否可修改
  enumerable: true, // 属性是否可遍历
  configurable: false, // 属性是否可删除
  get: undefined, // 访问属性值的时候执行什么程序
  set: undefined // 设置属性值的时候执行什么程序
}

例:

var obj = Object.create(null, {
    age: {
        value: 12,
        writable: true,
        enumerable: true,
        configurable: true,
    },
})
console.log(obj);

对象结果:

3、defineProperties

用于给对象添加或修改一个属性,语法:

Object.defineProperties(对象, {对象键值对的描述}) // 返回处理后的对象

例:

var pro = {
    name: '张三'
}
​
var obj = Object.defineProperties(pro, {
    age: {
        value: 12,
        writable: true,
        enumerable: true,
        configurable: true,
    },
})
console.log(obj);

对象结果:

4、defineProperty(重点关注)

用于监视对象某个属性被访问或被修改的操作,语法:

Object.defineProperty(对象, 属性名, {
    // 对象属性的描述
    writable: false, // 属性是否可修改
    enumerable: true, // 属性是否可遍历
    configurable: false, // 属性是否可删除
    get: undefined, // 访问属性值的时候执行什么程序
    set: undefined // 设置属性值的时候执行什么程序
})

例:

Object.defineProperty(obj, 'name', {
    writable: false, // 属性是否可修改
    enumerable: true, // 属性是否可遍历
    configurable: false, // 属性是否可删除
    get: function() { // 访问属性值的时候执行什么程序
        return// 当访问obj.name的时候会得到这个返回的值
    },
    set: function(val){ // 设置属性值的时候执行什么程序
        // 当给obj.name赋值的时候会在这里截获到他的值为val
    }
})
console.log( obj.name );
obj.name = '李四'

案例:数据和视图双向绑定

<body>
<input type="text">
</body>
<script>
function ViewModel(msg) {
    this.msg = msg
}
​
var vm = new ViewModel('哈哈')
​
var input = document.querySelector('input')
​
input.value = vm.msgObject.defineProperty(vm, 'msg', {
    configurable: false,
    enumerable: true,
    get: function() {
        return input.value
    },
    set: function(val) {
        input.value = val
    }
})
​
input.oninput = function() {
    vm.msg = this.value
}
​
</script>

改变文本框的值,对象的值会改变,改变对象的值,文本框的值也会改变。

5、entries

用于将对象中可遍历的键值对组成一个数组并返回,语法:

Object.entries(对象) // 返回数组

例:

var obj = {
    name: '张三',
    age: 12
}
​
Object.defineProperties(obj, {
    sex: {
        value: '男',
        enumerable: false,
    }
})
​
console.log(obj);
​
var arr = Object.entries(obj)
​
console.log(arr);

6、freeze

用于冻结一个对象,让对象不能新增、不能修改、不能删除、不能改原型,不能改属性的特性,语法:

var 对象 = Object.freeze(对象) // 返回被冻结的对象

例:

var obj = {
    name: '张三',
    age: 12
}
​
obj = Object.freeze(obj)
​
console.log(obj);obj.sex = '男'
console.log(obj);obj.name = '李四'
console.log(obj);
​
delete obj.age
console.log(obj);obj.__proto__ = {height: 180}
console.log(obj.height);

输出结果:

如果对象中的值,是一个对象,里面的小对象是没有被冻结的,也就说这种冻结只是浅冻结:

var obj = {
    name: '张三',
    age: 12,
    wife: {
        name: '翠花',
        age: 13
    }
}
obj = Object.freeze(obj) 
​
obj.wife.sex = '女'
​
console.log(obj);

结果:

若要深冻结,需要手动写递归函数实现:

var obj = {
    name: '张三',
    age: 12,
    wife: {
        name: '翠花',
        age: 13
    }
}
​
function deepFreeze(data) {
    for(var key in data) {
        if({}.toString.call(data[key]) === '[object Object]') {
            deepFreeze(data[key])
        }
    }
    return Object.freeze(data)
}
​
obj = deepFreeze(obj)
console.log(obj);
​
obj.wife.sex = '女'
console.log(obj);

冻结数据可以提高性能,一个数据确保后面都不会修改的话,就可以将他冻结。

7、fromEntries

跟entries的作用相反,将一个map格式的数组(多个键值对组成的数组)转成一个对象,语法:

Object.fromEntries(map格式的数据) // 返回键值对组成的对象

例:

var arr = [    ['name', '张三'], 
    [{age: 12}, '哈哈']
]
​
var obj = Object.fromEntries(arr)
​
console.log(obj);

结果:

可以将map转成对象。

8、getOwnPropertyDescriptors

获取对象中某个属性对应的描述对象。

// Object.getOwnPropertyDescriptors(对象) - 返回描述符
var obj = {
    name: '张三',
    age: 12
}
var obj = Object.create(null, {
    age: {
        value: 12
    }
})
// 获取obj的name属性的描述符
var descriptors = Object.getOwnPropertyDescriptors(obj)
console.log(descriptors);

9、getOwnPropertySymbols

将对象中所有symbol属性,组成一个数组。

10、getPrototypeOf

获取对象的原型对象。

// 语法:Object.getPrototypeOf(对象) - 返回原型对象
var obj = {
    name: '张三'
}
// 获取obj的原型
console.log( Object.getPrototypeOf(obj) );

11、hasOwn

判断一个属性是否属于某个对象,而不是被继承来的。跟hasOwnProperty的功能一样。

// 语法:Object.hasOwn(对象, 属性) - 返回布尔值
var obj = {
    name: '张三'
}
var bool = Object.hasOwn(obj, 'name')
console.log(bool);

12、is

用来判断两个数据是否相等,但是跟=====都不一样,基本类型数据,判断数据看起来是否相等,引用数据类型比较地址跟===一样,语法:

Object.is(数据1, 数据2) // 返回布尔值

例:

// 基本类型
var a = NaN
var b = NaN
console.log(a == b); // false
console.log( Object.is(a ,b) ); // true - 表面看起来一样var a = -0
var b = +0
console.log(a === b); // true
console.log( Object.is(a, b) ); // false - 表名看起来不一样// 引用类型
var a = {}
var b = {}
console.log(a === b); // false
console.log( Object.is(a, b) ); // false

13、isExtensible

用于判断一个对象是否可扩展(是否可以给对象添加属性)。冻结对象、密封对象不可以扩展。

// 语法:Object.isExtensible(对象) - 返回布尔值
console.log( Object.isExtensible(obj) );
Object.preventExtensions(obj)
console.log( Object.isExtensible(obj) );

14、isFrozen

用于判断一个对象是否被冻结。

console.log( Object.isFrozen(obj) ); // false
Object.freeze(obj)
console.log( Object.isFrozen(obj) ); // true

getOwnPropertyDescriptors - 获取对象属性的描述符
Object.getOwnPropertyDescriptors(对象) - 返回描述符
var obj = {
    name: '张三',
    age: 12
}
var obj = Object.create(null, {
    age: {
        value: 12
    }
})

15、keys(重点关注)

获取对象中所有键组成的数组。

// 语法:Object.keys(对象) - 返回数组
var obj = {
    name: '张三',
    age: 12,
    isMan: true
}
var arr = Object.keys(obj)
console.log(arr);

16、preventExtensions

用于将一个对象变得不可扩展。

// 语法:Object.preventExtension(对象) - 这个对象就不可以添加属性了
var obj = {
  name: '张三'
}

// 默认可以添加
obj.age = 12
console.log(obj);
// 将obj变的不可扩展
Object.preventExtensions(obj)
obj.sex = '男'
delete obj.name
obj.age = 13
console.log(obj);

17、setPrototypeOf

用于给对象设置原型。

// 语法:Object.setPrototypeOf(对象, 原型)
var obj = {
    name: '张三'
}

Object.setPrototypeOf(obj, {
    age: 12
})
console.log(obj);

18、seal

封闭一个对象,让对象不能添加新属性、不能删除键值对,但是可以修改,这一点与冻结有所区别, 语法:

Object.seal(要被封闭的对象) // 返回被封闭的对象

例:

var obj = {
    name: '张三'
}
​
Object.seal(obj)
​
delete obj.name
console.log(obj);
​
obj.age = 12
console.log(obj);
​
obj.name = '李四'
console.log(obj);

效果:

19、values(重点关注)

获取对象中所有值组成的数组。

// 语法:Object.values(对象) - 返回数组
var brr = Object.values(obj)
console.log(brr);