Javascript中的原型prototype

prototype属性可算是JavaScript与其他面向对象语言的一大不同之处。

简而言之,prototype就是“一个给类的对象添加方法的方法”,使用prototype属性,可以给类动态地添加属性和方法,以便在JavaScript中实现“继承”的效果。 

通过以此函数作为构造函数构造出来的对象都自动的拥有构造函数的prototype对象的成员属性和方法。

其中的要点是:

  1. prototype是函数(function)的一个必备属性(书面一点的说法是"保留属性")(只要是function,就一定有一个prototype属性)
  2. prototype的值是一个对象
  3. 可以任意修改函数的prototype属性的值。
  4. 一个对象会自动拥有这个对象的构造函数的prototype的成员属性和方法。

创建对象:

对于Object对象,可以使用对象字面量(Object literal)来创建,例如:

var foo = {
    x: 10,
    y: 20
};

javascript中的每个对象都隐式含有一个[[prototype]]属性,这是ECMAScript中的记法,目前各大浏览器厂商在实现自己的javascript解释器时,采用的记法是__proto__,也就是说每个对象都隐式包含一个__proto__属性。

当有多个对象时,通过__proto__属性就能够形成一条原型链。看下面的例子:

var a = {
    x: 10,
    calculate: function (z) {
        return this.x + this.y + z;
    }
};
var b = {
    y: 20,
    __proto__: a
};
var c = {
    y: 30,
    __proto__: a
};
// call the inherited method
b.calculate(30); // 60
c.calculate(40); // 80

上面的代码在声明对象b、c时,指明了它们的原型为对象a(a的原型默认指向Object.prototye,Object.prototype这个对象的原型指向null),这几个对象在内存中的结构大致是这样的:
prototype-chain

除了我们这里说的__proto__属性,相信大家平常更常见的是prototype属性。

<!DOCTYPE html>
<html>
<head lang="en">
<meta charset="UTF-8">
<title></title>
<script>
    /*
    javascript的每个对象都有__proto__属性,但是只有函数对象有prototype属性。
        使用对象字面量方式创建的对象的__proto__属性指向Object.prototype(Object.prototype的__proto__属性指向null);
        使用函数字面量创建的对象的__proto__属性指向Function.prototype(Function.prototype对象的__proto__属性指向Object.prototype)。
    */

    //b和c的隐式原型(__proto__)指向了a的隐式原型(__proto__).a.__proto__ ==>object.prototype

    /*
    b.__proto__ ==> a.__proto__()
    c.__proto__ ==> a.__proto__()
    a.__proto__ ==>object.prototype
    >object.prototype.__proto__ ==> null
    */


    var a={
        x:10,
        calculate:function(z){
            return this.x+this.y+z;
        }
    }
    var b={
        y:20,
        __proto__:a
    }
    var c={
        y:30,
        __proto__:a
    }

    console.log(b.calculate(30))
    console.log(c.calculate(40))

    console.log(b.__proto__== a)//true
    console.log(c.__proto__== a)//true
    console.log(b.__proto__== c.__proto__)//true

    /*
    1 __proto__表示该函数对象的原型
    2 prototype表示使用new来执行该函数时(这种函数一般成为构造函数),新创建的对象的原型。
    */

    Array.prototype.sum=function(){
        var result=0;
        for(var i=1;i<=this.length;i++){
            result+=i;
        }
        return result;
    }
    Array.prototype.clear=function(){

    }
    var arr=[1,2,3,4,5];
    console.log(arr.sum())
    console.log(arr.__proto__==Array.prototype) //true


    var arr2=new Array(2,4,6);
    console.log(arr2.__proto__==Array)//false
    console.log(arr2.__proto__==Array.prototype)//true


</script>
</head>
<body>
</body>
</html>
<!DOCTYPE html>
<html>
<head lang="en">
<meta charset="UTF-8">
<title></title>
<script>
    function Foo(y) {
        this.y = y;
    }

    Foo.prototype.x = 10;

    Foo.prototype.calculate = function (z) {
        return this.x + this.y + z;
    };

    var b = new Foo(20);
    var c = new Foo(30);


    b.calculate(30); // 60
    c.calculate(40); // 80


    console.log(
            b.__proto__ === Foo, // false
            b.__proto__ === Foo.prototype, // true
            c.__proto__ === Foo.prototype, // true

            b.constructor === Foo, // true
            c.constructor === Foo, // true
            Foo.prototype.constructor === Foo, // true

    b.calculate === b.__proto__.calculate, // true
    b.__proto__.calculate === Foo.prototype.calculate // true

    );

</script>
</head>
<body>
</body>
</html>

javascript的每个对象都有__proto__属性,但是只有函数对象prototype属性。

那么在函数对象中, 这两个属性的有什么区别呢?

  1. __proto__表示该函数对象的原型
  2. prototype表示使用new来执行该函数时(这种函数一般成为构造函数),新创建的对象的原型。

 
 
原文地址:https://www.cnblogs.com/eaysun/p/4422070.html