What does 'is an instance of' mean in Javascript?
The answer to this question: What is the initial value of a JavaScript function's prototype property?
has this sentence:
The initial value of prototype on any newly-created Function instance is a new instance of Object
As far as I know, Javascript doesn't开发者_运维百科 have classes and the word 'instance' therefor doesn't make sense in my head. How should one interpret 'instance' in Javascript?
Sorry, I don't have enough rep to put my question in the comment thread on that answer.
You're right that JavaScript doesn't have classes (yet), but it does have constructor functions, an instanceof
operator that defines a relationship between objects and constructors, and a form of inheritance based on prototype chains.
obj instanceof ctor
is true when ctor.prototype
is on obj
's prototype chain.
Modulo the caveat below, you could implement instanceof
in EcmaScript 5 thus
function isInstanceOf(obj, ctor) {
var proto = ctor.prototype;
if (typeof obj === "object" || typeof obj === "function") {
while (obj) {
if (obj === proto) { return true; }
obj = Object.getPrototypeOf(obj);
}
}
return false;
}
Unless you go around reassigning prototypes (o = new MyConstructor(); MyConstructor.prototype = somethingElse
) it should be the case that new MyConstructor() instanceof MyConstructor
.
Section 15.3.5.3 explains this in detail.
15.3.5.3
[[HasInstance]] (V)
Assume F is a Function object.
When the [[HasInstance]] internal method of F is called with value V, the following steps are taken:
If V is not an object, return false.
Let O be the result of calling the [[Get]] internal method of F with property name "prototype".
If Type(O) is not Object, throw a TypeError exception.
Repeat
- Let V be the value of the [[Prototype]] internal property of V.
- If V is null, return false.
- If O and V refer to the same object, return true.
This isn't the whole story because host objects (like DOM nodes) are allowed to implement the [[HasInstance]]
internal method however they like but most browsers implement host objects to behave as closely to native objects as possible.
JavaScript does not have classes, but it does have Types. You can define your own type and create a new instance using the new
keyword:
function Foo(initialValue) {
this.value = initialValue || 0;
}
var foo = new Foo(17);
var fooIsAFoo = foo instanceof Foo; // true!
var fooIsAnObject = foo instanceof Object; // also true! We have inheritance here :)
In JS, a function is an Object. It takes a while to get used to that, but it is true. Throw that around for a bit and the code that you see others using will make sense more. If you have seen Javascript where people are passing a function(){} as a parameter to another function, that is proof that functions are first class objects.
Once you can wrap your head around that (it took me a while) then you need to understand that if you make a function, you can get a New instance of it. See the following code:
function FooName(){
var name;
this.setName = function(n){
this.name = n;
}
this.getName = function(){
return this.name;
}
}
var n1 = new FooName();
var n2 = new FooName();
n1.setName("FOO");
n2.setName("BAR");
At this point you have two instances of the FooName method: n1 and n2. It is kind of a convention in JS to name your instantiable function with an Uppercase first letter, instead of the customer lowercase first letter. In this example, I indication that my function can be instanced by naming it FooName instead of fooName. I hope this makes sense.
In the example above, n1 has three properties. A private name property, a public setName property, and a public getName property. Each time I instantiate a new FooName, a copy of getName and setName are going to be created. That can waste space in memory. Since the getName and setName isn't going to change, I don't need a new copy of it for each FooName instance. This is where prototypes come in.
You can say the following, and then getName and setName will only exist once in memory, thus freeing up memory, which is a good thing.
FooName.prototype.setName = function(n){
this.name = n;
}
FooName.prototype.getName = function(){
return this.name;
}
If you remove the getName and setName from the FooName function, then now you will have a FooName "class" that has two methods, getName and setName.
Play with it. Let me know if you have questions.
In JavaScript functions are first-class objects, that means you can treat them just like any object.
//Define class
function User(name,age)
{
this.Name=name;
this.Age=age
}
//create insatnces
var user1= new User('Demo1','50');
var user2= new User('Demo2','100');
alert(user1.Name);
alert(user2.Name);
http://jsfiddle.net/praveen_prasad/hmUku/
http://en.wikipedia.org/wiki/First-class_function
Javascript doesn't use classical inheritance, it uses prototypal inheritance where everything is an "Object" and inheritance is accomplished by cloning, for example:
var myPrototype = function() {
var privateMember = "I am private";
var publicMember = "I am public";
var publicMethod = function () {
alert(privateMember);
}
return {
publicMember = publicMember,
publicMethod = publicMethod
}
}
var myInstace = new myPrototype();
myInstance.publicMethod();
here myInstance
can be said to be an "instance of" myPrototype
, but in reality what happened is by using the new
keyword you cloned myPrototype
to create myInstance
.
So now I have fabricated a page describing what I think all you guys* are saying: https://docs.google.com/document/d/1VvqqO2LMmilLbIvcU2JHI9ifaoMs-DB-farEzwuVuwM/edit?hl=da
illustrated with nice graphics :)
regards Jon
*and this link: http://trephine.org/t/index.php?title=Understanding_the_JavaScript_new_keyword
Javascript is object-oriented, so it does have classes. There simply isn't an explicit "class" directive, like you would have in other OOP languages.
精彩评论