目录
1.4.1Object.defineProperty(obj,prop,descriptor)
1.4.2Object.defineProperties(obj,props)
1.5.1Object.getOwnPropertyDescriptor(obj, prop)
1.5.2Object.getOwnPropertyDescriptors(obj)
1.6.1Object.getOwnPropertyNames(obj)
1.6.2Object.getOwnPropertySymbols(obj)
1.7.1Object.getPrototypeOf(ovject)
1.7.2Object.setPrototypeOf(obj,prototype)
1.8.1Object.hasOwn(instance,prop)
2.1.1Object.prototype.valueOf()
2.1.2Object.prototype.toString()
2.1.3Object.prototype.toLocalString()
2.2.1Object.prototype.propertyIsEnumerable(prop)
2.1.2Object.prototype.hasOwnProperty(prop)
2.2.1Object.prototype.isPrototypeOf(object)
1.4精准添加/修改对象属性
1.4.1Object.defineProperty(obj,prop,descriptor)
参数:obj:要定义或者要修改属性的对象,prop:要定义或者要修改的属性,descriptor:要定义或者要修改的属性描述符。
返回值:被传递给函数的对象。也就是说obj和返回的对象是同一个引用。
Object.defineProperty()
方法会直接在一个对象上定义一个新属性,或者修改一个对象的现有属性,并返回此对象。
这里我们先了解一下属性,属性分为两种,一种是数据属性,还有一种是访问器属性。
数据属性:有四个属性描述符,分别为writable,configurable,enumerable和value。
访问器属性:也有四个属性描述符,分别为get,set,configurable,和enumerable。
enumerable是控制属性是否可枚举。
writable是控制属性值是否可改变
configurable是控制属性是否可以被删除,且configurable配置为true的时候,不能修改enumerable和configurable自己的,且不能删除。
value是指定该属性的属性值。
get是属性的 getter 函数,如果没有 getter,则为 undefined
。当访问该属性时,会调用此函数。该函数的返回值会被用作属性的值。也会传入赋值时的this对象,也就是在函数里面可以用this,且this为调用这个get函数的对象。
set是属性的 setter 函数,如果没有 setter,则为 undefined
。当属性值被修改时,会调用此函数。该方法接受一个参数(也就是被赋予的新值),会传入赋值时的 this
对象。
不同方法定义属性的属性描述符初始值的不同之处:
我们通过Object.defineProperty或者是Object.defineProperties定义的属性,如果没有设置enumerable,configurable,writable,那么默认都是false。
而我们通过字面量和new构造函数定义的对象的属性,configurable,writable,enumerable这三个属性的默认值都是true。
let obj_={}
Object.defineProperty(obj_,"age",{
get(){
console.log("hahaha")
return 1
},
set(newValue){
console.log("set a:"+newValue)
}
})
console.log(obj_.age)
obj_.age=99
当访问age属性的时候,先找到obj对象,然后再找到obj的age属性,然后就被get函数劫持了,可以在函数里做一些操作,然后函数的返回值会被用作属性的值。
当设置age属性的时候,也是先找到obj对象,然后找到obj的age属性,然后被set劫持了,可以在函数里做一些操作。
set和get的名字其实是一样的,但是js引擎可以判断,当前是set操作还是set操作,从而进入不同的函数做出不同的逻辑。
1.4.2Object.defineProperties(obj,props)
其实这个方法和上面方法最大的不同就是在于这个方法可以同时定义多个属性一级属性描述符。其他的没有什么区别。
var obj = {};
Object.defineProperties(obj, {
'property1': {
value: true,
writable: true
},
'property2': {
value: 'Hello',
writable: false
}
// etc. etc.
});
1.5属性描述符的获取
1.5.1Object.getOwnPropertyDescriptor(obj, prop)
参数:obj需要查找的目标对象,prop目标对象内属性名称
返回值:如果指定的属性存在于对象上,则返回其属性描述符对象(property descriptor),否则返回值为undefined
- 方法返回指定对象上一个自有属性对应的属性描述符。(自有属性指的是直接赋予该对象的属性,不需要从原型链上进行查找的属性)
o = { bar: 42 };
d = Object.getOwnPropertyDescriptor(o, "bar");
// d {
// configurable: true,
// enumerable: true,
// value: 42,
// writable: true
// }
1.5.2Object.getOwnPropertyDescriptors(obj)
参数:objobj需要查找的目标对象。
返回值:所指定对象的所有自身属性的描述符,如果没有任何自身属性,则返回空对象。
- 此方法用来获取一个对象的所有自身属性描述符。
o = { bar: 42 ,age:13};
d = Object.getOwnPropertyDescriptor(o);
/*
{"bar":{
configurable: true,
enumerable: true,
value: 42,
writable: true},
"bar":{
configurable: true,
enumerable: true,
value: 42,
writable: true
}}
*/
1.6属性名的获取
1.6.1Object.getOwnPropertyNames(obj)
参数:一个对象,其自身的可枚举和不可枚举属性的名称被返回。
返回值:在给定对象上找到的自身属性对应的字符串数组。
Object.getOwnPropertyNames()
方法返回一个由指定对象的所有自身属性的属性名(包括不可枚举属性但不包括 Symbol 值作为名称的属性)组成的数组。
var obj = { 0: "a", 1: "b", 2: "c"};
console.log(Object.getOwnPropertyNames(obj).sort()); // ["0", "1", "2"]
1.6.2Object.getOwnPropertySymbols(obj)
参数:要返回 Symbol 属性的对象。
返回值:在给定对象自身上找到的所有 Symbol 属性的数组。
Object.getOwnPropertySymbols()
方法返回一个给定对象自身的所有 Symbol 属性的数组。
var obj = {};
var a = Symbol("a");
var b = Symbol.for("b");
obj[a] = "localSymbol";
obj[b] = "globalSymbol";
var objectSymbols = Object.getOwnPropertySymbols(obj);
console.log(objectSymbols.length); // 2
console.log(objectSymbols) // [Symbol(a), Symbol(b)]
console.log(objectSymbols[0]) // Symbol(a)
1.7获取/设置对象原型
1.7.1Object.getPrototypeOf(ovject)
参数:要返回其原型的对象
返回值,给定对象的原型。如果没有继承属性,则返回null
Object.getPrototypeOf()
方法返回指定对象的原型(内部[[Prototype]]
属性的值)。
// 一般用法是:
var obj = new Object();
所以:
Object.getPrototypeOf( Object ); // ƒ () { [native code] }
Object.getPrototypeOf( Function ); // ƒ () { [native code] }
Object.getPrototypeOf( Object ) === Function.prototype; // true
Object.getPrototypeOf( Object ) 是把 Object 这一构造函数看作对象,
返回的当然是函数对象的原型,也就是 Function.prototype。
正确的方法是,Object.prototype 是构造出来的对象的原型。
var obj = new Object();
Object.prototype === Object.getPrototypeOf( obj ); // true
Object.prototype === Object.getPrototypeOf( {} ); // true
1.7.2Object.setPrototypeOf(obj,prototype)
参数:obj要设置其原型的对象。prototype该对象的新原型 (一个对象 或 null).
返回值:给定对象obj。所以返回的对象就是这个obj,所以接受到的对象和这个obj是同一个引用。
- 如果对象的 [[Prototype]] 被修改成不可扩展 (通过 Object.isExtensible()查看),就会抛出 TypeError 异常。如果
prototype
参数不是一个对象或者 null (例如,数字,字符串,boolean,或者 undefined),则什么都不做。否则,该方法将obj
的[[Prototype]]
修改为新的值。
let obj___={}
let obj____=Object.setPrototypeOf(obj___,null)
console.log(obj____===obj___)//true
console.log(obj___)
1.8对象自身的存在性判断
1.8.1Object.hasOwn(instance,prop)
参数:instance
要测试的 JavaScript 对象实例。prop
要测试的属性的String名称或Symbol属性。而且也可以检测不可枚举的。就是说可以检测自身身上的属性,而不管你是可枚举还是不可枚举,是普通属性,还是Symbol属性。
返回值:true
如果指定的对象自身直接定义了指定的属性。否则false
- 如果指定的属性是对象的直接属性,则该
Object.hasOwn()
方法返回true
— 即使属性值为null
orundefined
。false
如果属性是继承的,或者根本没有声明,则该方法返回。与in运算符不同,此方法不检查对象原型链中的指定属性。
let example = {};
Object.hasOwn(example, 'prop'); // false = 'prop' has not been defined
example.prop = 'exists';
Object.hasOwn(example, 'prop'); // true - 'prop' has been defined
example.prop = null;
Object.hasOwn(example, 'prop'); // true - own property exists with value of null
example.prop = undefined;
Object.hasOwn(example, 'prop'); // true - own property exists with value of undefined
这个方法就是用来替代Object.prototype.hasOwnProperty(prop),主要是为了解决以下情况,也就是对象可能有一个属性叫做hasOwnProperty方法,然后就会覆盖原型上的hasOwnProperty方法。
let foo = {
hasOwnProperty: function() {
return false;
},
bar: 'Here be dragons'
};
foo.hasOwnProperty('bar'); // reimplementation always returns false
1.7值的判断
Object.is(value1,value2)
参数:value1:被比较的第一个值,value2:被比较的第二个值,
返回值:一个布尔值,表示两个参数是否是同一个值。
Object.is()
判断两个值是否为同一个值,如果以下任一条件满足条件,则为:
跟==运算符不同,在相等性测试之前,不会进行强制类型转换。与===运算符也不同,他们之间的唯一区别在于对符号0和NaN的处理上,===运算符将+0和-0视为相等,此外===认为Number.NaN和NaN是不相等的。
// Case 1: Evaluation result is the same as using ===
Object.is(25, 25); // true
Object.is('foo', 'foo'); // true
Object.is('foo', 'bar'); // false
Object.is(null, null); // true
Object.is(undefined, undefined); // true
Object.is(window, window); // true
Object.is([], []); // false
const foo = { a: 1 };
const bar = { a: 1 };
Object.is(foo, foo); // true
Object.is(foo, bar); // false
// Case 2: Signed zero
Object.is(0, -0); // false
Object.is(+0, -0); // false
Object.is(-0, -0); // true
Object.is(0n, -0n); // true
// Case 3: NaN
Object.is(NaN, 0/0); // true
Object.is(NaN, Number.NaN) // true
2原型方法
2.1转换方法
所有的对象都有三个转换方法。toLocalString(),toString(),valueOf()。
2.1.1Object.prototype.valueOf()
返回值:返回值为该对象的原始值。 每个内置的核心对象都会覆盖此方法以返回适当的值。如果对象没有原始值,则 valueOf
将返回对象本身。
不同类型对象的 valueOf() 方法的返回值如下所示:
对象 | 返回值 |
---|---|
Array | 返回数组对象本身。 |
Boolean | 布尔值。 |
Date | 存储的时间是从 1970 年 1 月 1 日午夜开始计的毫秒数 UTC。 |
Function | 函数本身。 |
Number | 数字值。 |
Object | 对象本身。这是默认情况。 |
String | 字符串值。 |
Math 和 Error 对象没有 valueOf 方法。 |
// Array:返回数组对象本身
var array = ["ABC", true, 12, -5];
console.log(array.valueOf() === array); // true
// Date:当前时间距 1970 年 1 月 1 日午夜的毫秒数
var date = new Date(2013, 7, 18, 23, 11, 59, 230);
console.log(date.valueOf()); // 1376838719230
// Number:返回数字值
var num = 15.26540;
console.log(num.valueOf()); // 15.2654
// 布尔:返回布尔值 true 或 false
var bool = true;
console.log(bool.valueOf() === bool); // true
// new 一个 Boolean 对象
var newBool = new Boolean(true);
// valueOf() 返回的是 true,两者的值相等
console.log(newBool.valueOf() == newBool); // true
// 但是不全等,两者类型不相等,前者是 boolean 类型,后者是 object 类型
console.log(newBool.valueOf() === newBool); // false
// Function:返回函数本身
function foo(){}
console.log( foo.valueOf() === foo ); // true
var foo2 = new Function("x", "y", "return x + y;");
console.log( foo2.valueOf() );
/*
ƒ anonymous(x,y
) {
return x + y;
}
*/
// Object:返回对象本身
var obj = {name: "张三", age: 18};
console.log( obj.valueOf() === obj ); // true
// String:返回字符串值
var str = "http://www.xyz.com";
console.log( str.valueOf() === str ); // true
// new 一个字符串对象
var str2 = new String("http://www.xyz.com");
// 两者的值相等,但不全等,因为类型不同,前者为 string 类型,后者为 object 类型
console.log( str2.valueOf() === str2 ); // false
2.1.2Object.prototype.toString()
返回值:toString()
方法返回一个表示该对象的字符串。
- 默认情况下,
toString()
方法被每个Object
对象继承。如果此方法在自定义对象中未被覆盖,toString()
返回 “[object type]”,其中type
是对象的类型。
var toString = Object.prototype.toString;
toString.call(new Date); // [object Date]
toString.call(new String); // [object String]
toString.call(Math); // [object Math]
//Since JavaScript 1.8.5
toString.call(undefined); // [object Undefined]
toString.call(null); // [object Null]
2.1.3Object.prototype.toLocalString()
返回值:表示对象的字符串,没有覆盖的对象Object toLocaleString
返回调用 toString() 的结果。
toLocaleString()
方法返回一个该对象的字符串表示。此方法被用于派生对象为了特定语言环境的目的(locale-specific purposes)而重载使用。
覆盖了toLocalString()的对象Date,Number,Array这三个方法。
2.2属性相关
2.2.1Object.prototype.propertyIsEnumerable(prop)
参数:需要测试的属性名
返回值:用来指定的属性名是否可枚举的布尔值。
- 每个对象都有一个
propertyIsEnumerable
方法。此方法可以确定对象中指定的属性是否可以被 for…in 循环枚举,但是通过原型链继承的属性除外。如果对象没有指定的属性,则此方法返回false
。
var o = {};
var a = [];
o.prop = 'is enumerable';
a[0] = 'is enumerable';
o.propertyIsEnumerable('prop'); // 返回 true
a.propertyIsEnumerable(0); // 返回 true
var a = ['is enumerable'];
a.propertyIsEnumerable(0); // 返回 true
a.propertyIsEnumerable('length'); // 返回 false
Math.propertyIsEnumerable('random'); // 返回 false
this.propertyIsEnumerable('Math'); // 返回 false
2.1.2Object.prototype.hasOwnProperty(prop)
参数:instance
要测试的 JavaScript 对象实例。prop
要测试的属性的String名称或Symbol属性。就是说可以检测自身身上的属性,而不管你是可枚举还是不可枚举,是普通属性,还是Symbol属性。
返回值:true
如果指定的对象自身直接定义了指定的属性。否则false
- 如果指定的属性是对象的直接属性,则该
Object.prototype.hasOwnProperty()
方法返回true
— 即使属性值为null
orundefined
。false
如果属性是继承的,或者根本没有声明,则该方法返回。与in运算符不同,此方法不检查对象原型链中的指定属性。
其实跟原型上的静态方法hasOwn方法是一样的,就是为了解决实例对象身上如果有的属性名字和这个hasOwnProperty属性名重 冲突了的问题。
2.3对象是否在另一个对象的原型上
2.3.1Object.prototype.isPrototypeOf(object)
参数:在该对象的原型上搜索
返回值:Boolean,表示调用对象是否在另一个对象的原型链上。如果 prototypeObj
为 undefined 或 null,会抛出 TypeError。
isPrototypeOf()
方法允许你检查一个对象是否存在于另一个对象的原型链上。备注:isPrototypeOf()
与 instanceof 运算符不同。在表达式 “object instanceof AFunction
“中,object
的原型链是针对AFunction.prototype
进行检查的,而不是针对AFunction
本身。
以下实例展示Baz.prototype
, Bar.prototype
, Foo.prototype
和 Object.prototype
在 baz
对象的原型链上:
function Foo() {}
function Bar() {}
function Baz() {}
Bar.prototype = Object.create(Foo.prototype);
Baz.prototype = Object.create(Bar.prototype);
var baz = new Baz();
console.log(Baz.prototype.isPrototypeOf(baz)); // true
console.log(Bar.prototype.isPrototypeOf(baz)); // true
console.log(Foo.prototype.isPrototypeOf(baz)); // true
console.log(Object.prototype.isPrototypeOf(baz)); // true
非常感谢您的阅读,欢迎大家提出您的意见,指出相关错误,谢谢!越努力,越幸运!