javascript原型详解(转载)

一、原型
原型是 JavaScript 面向对象特性中重要的概念,在绝大多数的面向对象语言中,对象是基于类的(例如 Java 和 C++ ),对象是类实例化的结果。而在JavaScript 语言中,没有类的概念①,对象由对象实例化。打个比方来说,基于类的语言中类就像一个模具,对象由这个模具浇注产生,而基于原型的语言中,原型就好像是一件艺术品的原件,我们通过一台 100% 精确的机器把这个原件复制出很多份。

通过原型构造对象:

function Person() {}
Person.prototype.name = 'BYVoid';
Person.prototype.showName = function () {
    console.log(this.name);
};
var person = new Person();
person.showName();


上面这段代码使用了原型而不是构造函数初始化对象。这样做与直接在构造函数内定义属性有什么不同呢?

  • 构造函数内定义的属性继承方式与原型不同,子对象需要显式调用父对象才能继承构造函数内定义的属性。
  • 构造函数内定义的任何属性,包括函数在内都会被重复创建,同一个构造函数产生的两个对象不共享实例。
  • 构造函数内定义的函数有运行时闭包的开销,因为构造函数内的局部变量对其中定义的函数来说也是可见的。

下面这端代码能够验证以上问题:

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 中有两个特殊的对象, Object 与 Function,它们都是构造函数,用于生成对象。Object.prototype 是所有对象的祖先, Function.prototype 是所有函数的原型,包括构造函数。
我把 JavaScript 中的对象分为三类,一类是用户创建的对象,一类是构造函数对象,一类是原型对象

  • 用户创建的对象,即一般意义上用 new 语句显式构造的对象。
  • 构造函数对象指的是普通的构造函数,即通过 new 调用生成普通对象的函数。
  • 原型对象特指构造函数 prototype 属性指向的对象。这三类对象中每一类都有一个__proto__ 属性,它指向该对象的原型,从任何对象沿着它开始遍历都可以追溯到 Object.prototype。
  • 构造函数对象有prototype 属性,指向一个原型对象,通过该构造函数创建对象时,被创建对象的 proto 属性将会指向构造函数的 prototype 属性。
  • 原型对象constructor属性,指向它对应的构造函数。

让我们通过下面这个例子来理解原型:

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 中,继承是依靠一套叫做原型链(prototype chain)的机制实现的。属性继承的本质就是一个对象可以访问到它的原型链上任何一个原型对象的属性。

转自:
https://www.cnblogs.com/chihaiping/p/6373651.html

参考:
https://www.cnblogs.com/hongqin/p/5998594.html

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章