javascript的原型和构造函数

来源:互联网 发布:大数据就业培训 编辑:程序博客网 时间:2024/06/11 17:09

javascript的原型和构造函数

var F=function show(){};var p=F.prototype;var c=p.constructor;alert(c===F);             //truevar f=new F();alert(f.constructor===F);  //true

每个Javascript函数中都自动拥有一个prototype属性,该属性的值是一个对象,这个对象包含唯一一个不可枚举属性constructor,constructor属性的值即是构造函数对象,
继承该类的对象中的constructor属性的值也为该构造函数对象。

再看一例:

function Person(name){      this.name=name;      this.showName=function(){          alert(this.name);      }   };   var one=new Person('js');   alert(one.prototype)//undefined   alert(typeof Person.prototype);//object   alert(Person.prototype.constructor);//function Person(name) {...};  

这是因为function定义的对象有一个prototype属性,而使用new生成的对象就没有prototype属性(其只有__proto__属性,js中的任何对象都有__proto__属性),prototype属性指向了一个prototype对象,prototype对象中有一个constructor属性,这个constructor属性同样指向一个constructor对象,该对象就是function函数本身。

stackoverflow有一个关于prototype的讨论,链接:prototype示例

其中有一个例子:

function Foo() {}Foo.prototype = {    array: [],    func: function() {}}a = new Foo();b = new Foo();a.array.push('bar');console.log(b.array); // prints ["bar"]b.func.bar = 'baz';console.log(a.func.bar); // prints baz

其对prototype的解释如下:

The prototype of an object is just an object. The prototype is shared between all objects that “inherit” from it. No copy of the prototype is made if you create a new instance of a “class” (classes don’t exist anyway in JS).

一个函数的原型只有一份,任何继承它的对象都拥有这些属性,这样就不难理解上面的结果了。

In all these cases you are always working with the same object.

But if you assign a value to a property of the object, the property will be set on the object itself, not its prototype, and hence is not shared:

console.log(a.hasOwnProperty('array')); // prints falsea.array = ['foo'];console.log(a.hasOwnProperty('array')); // prints trueconsole.log(b.array); //prints ["bar"]

这样a就拥有了自己的array属性,当我们console.log(a.array); 其结果就是a自己的array属性,而不是原型的属性了。

If you want to have the array private, you have to declare it in the constructor:

function Foo() {    this.array = [];}

because here, this refers to the new object that is generated when you call new Foo().

The rule of thumb is: Instance-specific data should be assigned to the instance inside the constructor, shared data (like methods) should be assigned to the prototype.

对于类继承和原型继承的不同,链接:Details of the object model

其中说明了原型继承的特点:

A prototype-based language, such as JavaScript, does not make this distinction: it simply has objects. A prototype-based language has the notion of a prototypical object, an object used as a template from which to get the initial properties for a new object. Any object can specify its own properties, either when you create it or at run time. In addition, any object can be associated as the prototype for another object, allowing the second object to share the first object’s properties.

Property lookup in JavaScript looks within an object’s own properties and, if the property name is not found, it looks within the special object property __proto__. This continues recursively; the process is called “lookup in the prototype chain”.

The special property __proto__ is set when an object is constructed; it is set to the value of the constructor’s prototype property. So the expression new Foo() creates an object with __proto__== Foo.prototype. Consequently, changes to the properties of Foo.prototype alters the property lookup for all objects that were created by new Foo().

Every object has a __proto__ object property (except Object); every function has a prototype object property. So objects can be related by ‘prototype inheritance’ to other objects. You can test for inheritance by comparing an object’s __proto__ to a function’s prototype object. JavaScript provides a shortcut: the instanceof operator tests an object against a function and returns true if the object inherits from the function prototype.

1 0