instanceof

instanceof 运算符用于检测构造函数的 prototype 属性是否出现在某个实例对象的原型链上。

语法

1
object instanceof constructor

参数

object :某个实例对象

constructor :某个构造函数

描述

instanceof 运算符用来检测 constructor.prototype 是否存在于参数 object 的原型链上。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
// 定义构造函数
function C(){}
function D(){}

var o = new C();


o instanceof C; // true,因为 Object.getPrototypeOf(o) === C.prototype


o instanceof D; // false,因为 D.prototype 不在 o 的原型链上

o instanceof Object; // true,因为 Object.prototype.isPrototypeOf(o) 返回 true
C.prototype instanceof Object // true,同上

C.prototype = {};
var o2 = new C();

o2 instanceof C; // true

o instanceof C; // false,C.prototype 指向了一个空对象,这个空对象不在 o 的原型链上.

D.prototype = new C(); // 继承
var o3 = new D();
o3 instanceof D; // true
o3 instanceof C; // true 因为 C.prototype 现在在 o3 的原型链上

需要注意的是,如果表达式 obj instanceof Foo 返回 true,则并不意味着该表达式会永远返回 true,因为 Foo.prototype 属性的值有可能会改变,改变之后的值很有可能不存在于 obj 的原型链上,这时原表达式的值就会成为 false。另外一种情况下,原表达式的值也会改变,就是改变对象 obj 的原型链的情况,虽然在目前的ES规范中,我们只能读取对象的原型而不能改变它,但借助于非标准的 __proto__ 伪属性,是可以实现的。比如执行 obj.__proto__ = {} 之后,obj instanceof Foo 就会返回 false 了。

isPrototypeOf()

isPrototypeOf()instanceof 运算符不同。在表达式 “object instanceof AFunction“中,object 的原型链是针对 AFunction.prototype 进行检查的,而不是针对 AFunction 本身。

isPrototypeOf是用来判断指定对象object1是否存在于另一个对象object2的原型链中,是则返回true,否则返回false。
格式如下:
  object1.isPrototypeOf(object2);
  object1是一个对象的实例;
  object2是另一个将要检查其原型链的对象。
原型链可以用来在同一个对象类型的不同实例之间共享功能。
如果 object2 的原型链中包含object1,那么 isPrototypeOf 方法返回 true。
如果 object2 不是一个对象或者 object1 没有出现在 object2 中的原型链中,isPrototypeOf 方法将返回 false。

示例:
本示例展示了 Baz.prototype, Bar.prototype, Foo.prototype Object.prototypebaz 对象的原型链上:

1
2
3
4
5
6
7
8
9
10
11
12
13
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

hasOwnProperty()

hasOwnProperty() 检查对象自身中是否含有该属性。使用该方法时,只有对象自身中含有属性时才会返回true。

格式如下:
object.hasOwnProperty(proName);
判断proName的名称是不是object对象的一个属性或对象。

1
2
3
4
5
6
var a = {
x: 1
};
console.log(a.hasOwnProperty("x")); //true
console.log(a.hasOwnProperty("y")); //false
console.log(a.hasOwnProperty("toString")); //false toString是继承属性

propertyIsEnumerable()

propertyIsEnumerable()hasOwnProperty()的增强版,只有检侧到是目有属性且这个属性的可枚举性(enumerable attribute)为true时它才返回true.某些内置属性是不可枚举的。通常由JavaScript代码创建的属性都是可枚举的。除非调用``Object.defineProperty() `方法来修改。

propertyIsEnumerable() 方法返回一个布尔值,表示指定的属性是否可枚举。

语法

obj.propertyIsEnumerable(prop)

参数

prop
   需要测试的属性名。

返回值

用来表示指定的属性名是否可枚举的布尔值。

描述

每个对象都有一个 propertyIsEnumerable 方法。此方法可以确定对象中指定的属性是否可以被 for…in
循环枚举,但是通过原型链继承的属性除外。如果对象没有指定的属性,则此方法返回 false。

例子

1
2
3
4
5
6
7
8
9
10
11
12
13
14
const object1 = {};
const array1 = [];
object1.property1 = 42;
array1[0] = 42;

console.log(object1.propertyIsEnumerable('property1'));
// expected output: true

console.log(array1.propertyIsEnumerable(0));
// expected output: true

console.log(array1.propertyIsEnumerable('length'));
// expected output: false

下面的例子演示了用户自定义对象和内置对象上属性可枚举性的区别.

1
2
3
4
5
6
7
var a = ['is enumerable'];

a.propertyIsEnumerable(0); // 返回 true
a.propertyIsEnumerable('length'); // 返回 false

Math.propertyIsEnumerable('random'); // 返回 false
this.propertyIsEnumerable('Math'); // 返回 false


愿你的坚持终有收获。