js中原型的简单认识
原型
前面有提到过可以通过构造函数来创建对象。其实通过原型也是可以创建对象的。那么我们就来比较一下原型和构造函数的一些差别。
var Animal = function () {};
Animal.prototype.name = "动物";
var cat = new Animal();
上面这段代码使用了原型而不是构造函数初始化对象。这样做与直接在构造函数内定义属性有什么不同呢?(引自《Node.js开发指南》)
-
构造函数内定义的属性继承方式与原型不同,子对象需要显式调用父对象才能继承构造函数内定义的属性。
- 构造函数内定义的任何属性,包括函数在内都会被重复创建,同一个构造函数产生的两个对象不共享实例。
- 构造函数内定义的函数有运行时闭包的开销,因为构造函数内的局部变量对其中定义的函数来说也是可见的。
function Foo() {
var innerVar = 'hello';
this.prop1 = 'BYVoid';
this.func1 = function(){
innerVar = '';
};
}
Foo.prototype.prop2 = 'Carbo';
Foo.prototype.func2 = function () {
console.log(this.prop2);
};
var foo1 = new Foo();
var foo2 = new Foo();
console.log(foo1.func1 == foo2.func1); // 输出 false
console.log(foo1.func2 == foo2.func2); // 输出 true
原型链
javascript中有2中特殊的对象:Object和Function。它们都是构造函数。Object.prototype是所有对象的祖先,Function.prototype是所有函数的原型,包括构造函数。
javascript中有3中对象:
- 用户创建的对象:使用字面量法或者new Object显示创建的对象
- 构造函数对象:即借助new 关键字生成的普通对象
- 原型对象:通过构造函数的prototype属性生成的原型对象
这三个对象都有一个__proto__属性,指向该对象的原型。沿着__proto__属性可以一直找到Object.prototype。构造函数有prototype属性,指向其原型对象。通过构造函数创建的对象,该对象的__proto__属性指向了该构造函数的prototype属性。原型对象有一个constructor属性,指向它的构造函数。
function Foo() {
}
Object.prototype.name = 'My Object';
Foo.prototype.name = 'Bar';
var obj = new Object();
var foo = new Foo();
console.log(obj.name); // 输出 My Object
console.log(foo.name); // 输出 Bar
console.log(foo.__proto__.name); // 输出 Bar
console.log(foo.__proto__.__proto__.name); // 输出 My Object
console.log(foo. __proto__.constructor.prototype.name); // 输出 Bar
在 JavaScript 中,继承是依靠一套叫做原型链(prototype chain)的机制实现的。属性继承的本质就是一个对象可以访问到它的原型链上任何一个原型对象的属性。
浙公网安备 33010602011771号