JavaScript中的instanceof运算符是什么?
JavaScript中的instanceof
关键字在第一次遇到时可能会相当混乱,因为人们倾向于认为JavaScript不是面向对象的编程语言。
的instanceof
左手侧(LHS)操作数是正在测试右手侧(RHS)操作数的实际对象,它是一个类的实际构造函数。 基本定义是:
Checks the current object and returns true if the object
is of the specified object type.
这里有一些很好的例子,下面是一个直接来自Mozilla开发者网站的例子:
var color1 = new String("green");
color1 instanceof String; // returns true
var color2 = "coral"; //no type specified
color2 instanceof String; // returns false (color2 is not a String object)
值得一提的是,如果对象继承自classe的原型,那么instanceof
评估为true:
var p = new Person("Jon");
p instanceof Person
因为p
从Person.prototype
继承,所以p
是p instanceof Person
。
根据OP的要求
我已经添加了一些示例代码和解释。
当你声明一个变量时,你给它一个特定的类型。
例如:
int i;
float f;
Customer c;
以上显示了一些变量,即i
, f
和c
。 类型是integer
, float
和用户定义的Customer
数据类型。 上述类型可以用于任何语言,而不仅仅是JavaScript。 但是,使用JavaScript声明变量时,您并未明确定义类型,因此var x
,x可以是数字/字符串/用户定义的数据类型。 那么,什么样的instanceof
会检查对象,看看它是否是上面指定的类型,然后再采用我们可以执行的Customer
对象:
var c = new Customer();
c instanceof Customer; //Returns true as c is just a customer
c instanceof String; //Returns false as c is not a string, it's a customer silly!
上面我们已经看到c
是用Customer
类型声明的。 我们已经新建了它并检查它是否属于Customer
类型。 当然是,它回归真实。 然后仍然使用Customer
对象来检查它是否是String
。 不,绝对不是一个String
我们新建了一个Customer
对象而不是一个String
对象。 在这种情况下,它返回false。
这真的很简单!
到目前为止,任何一个评论都没有涉及instanceof的一个重要方面:继承。 由于原型继承,使用instanceof进行评估的变量可能会为多个“类型”返回true。
例如,让我们定义一个类型和一个子类型:
function Foo(){ //a Foo constructor
//assign some props
return this;
}
function SubFoo(){ //a SubFoo constructor
Foo.call( this ); //inherit static props
//assign some new props
return this;
}
SubFoo.prototype = new Foo(); // Inherit prototype
现在我们有几个“类”,让我们创建一些实例,并找出它们的实例:
var
foo = new Foo()
, subfoo = new SubFoo()
;
alert(
"Q: Is foo an instance of Foo? "
+ "A: " + ( foo instanceof Foo )
); // -> true
alert(
"Q: Is foo an instance of SubFoo? "
+ "A: " + ( foo instanceof SubFoo )
); // -> false
alert(
"Q: Is subfoo an instance of Foo? "
+ "A: " + ( subfoo instanceof Foo )
); // -> true
alert(
"Q: Is subfoo an instance of SubFoo? "
+ "A: " + ( subfoo instanceof SubFoo )
); // -> true
alert(
"Q: Is subfoo an instance of Object? "
+ "A: " + ( subfoo instanceof Object )
); // -> true
看到最后一行? 对一个函数的所有“新”调用都会返回一个从Object继承的对象。 即使在使用对象创建速记时也是如此:
alert(
"Q: Is {} an instance of Object? "
+ "A: " + ( {} instanceof Object )
); // -> true
那么,“类”定义本身呢? 他们是什么样的?
alert(
"Q: Is Foo an instance of Object? "
+ "A:" + ( Foo instanceof Object)
); // -> true
alert(
"Q: Is Foo an instance of Function? "
+ "A:" + ( Foo instanceof Function)
); // -> true
我觉得理解任何对象都可以是一个MULTIPLE类型的实例是很重要的,因为你我(错误地)认为你可以通过使用instanceof
来区分,说和对象以及函数。 最后这个例子清楚地表明函数是一个对象。
如果您使用任何继承模式并且想通过鸭式打字以外的方法来确认对象的后代,这也很重要。
希望能够帮助任何人探索instanceof
。
这里的其他答案是正确的,但他们没有深入了解instanceof
实际工作的方式,这可能会对某些语言律师感兴趣。
JavaScript中的每个对象都有一个原型,可以通过__proto__
属性访问。 函数也有一个prototype
属性,它是由它们创建的任何对象的初始__proto__
。 当一个函数被创建时,它会被赋予一个独特的prototype
对象。 instanceof
操作符使用这个唯一性给你一个答案。 如果您将它作为函数编写,那么以下是instanceof
可能的样子。
function instance_of(V, F) {
var O = F.prototype;
V = V.__proto__;
while (true) {
if (V === null)
return false;
if (O === V)
return true;
V = V.__proto__;
}
}
这基本上解释了ECMA-262第5.1版(也称为ES5),第15.3.5.3节。
请注意,您可以将任何对象重新分配给函数的prototype
属性,并且可以在构造完成后重新分配对象的__proto__
属性。 这会给你一些有趣的结果:
function F() { }
function G() { }
var p = {};
F.prototype = p;
G.prototype = p;
var f = new F();
var g = new G();
f instanceof F; // returns true
f instanceof G; // returns true
g instanceof F; // returns true
g instanceof G; // returns true
F.prototype = {};
f instanceof F; // returns false
g.__proto__ = {};
g instanceof G; // returns false
链接地址: http://www.djcxy.com/p/6977.html