js中prototype属性的理解

像C语言,java等面向对象语言都存在类的概念,而js是不存在类的概念的,它不基于类,而是通过构造函数和原型链(prototype chains)来实现的。

ES6 提供了更接近传统语言的写法,引入了 Class(类)这个概念,作为对象的模板。基本上,ES6 的class可以看作只是一个语法糖,它的绝大部分功能,ES5 都可以做到,新的class写法只是让对象原型的写法更加清晰、更像面向对象编程的语法而已。这里不谈这个。

1、构造函数

function Person(name, sex) {
        this.name = name;
        this.sex = sex;
    }
    var person = new Person('小明','男');
    console.log(person.name, person.sex)  //小明 男

从上面的例子看出构造函数的特点:

(1)函数内部用this来指向即将要生成的实例对象

(2)用new来生成实例对象

(3)函数名称首字母要大写。虽然不用大写字母函数是可以运行,但是规则上是使用大写字母,用来区分普通函数。

所有实例对象都可以继承该构造函数的属性和方法。但是同一个对象实例之间是无法共享属性和方法的。

function Person(name, sex) {
        this.name = name;
        this.sex = sex;
        this.age = function () {
            return '20';
        }
    }
    var person1 = new Person('小明','男');
    var person2 = new Person('小红','女');
    console.log(person1.age === person2.age)  //false

从上面的例子可以看出,虽然两个对象都调用了age的方法,但是它们的age方法是不一样的。构造函数生成两个对象实例(person1、person2),并且有两个属性(name、sex)和一个方法(age),但是她们的方法是不一样的,也就是说,每当用new来调用age实例对象的时候,内存都会创建一个age方法。

2、prototype属性的作用

在js上可以使用prototype属性来解决构造函数和对象实例之间共享方法。

这里先讲一下原型和原型链的概念:

(1)原型:js中每个数据类型都是对象(null和undefined除外),而每个对象都继承另一个对象,后者成为“原型”(prototype)对象,null除外,它没有自己的原型对象。

(2)原型链:对象属性和方法,有可能是定义在自身,也有可能是定义在它的原型对象。就是实例对象和原型之间组成的有限链。

    function Person(name, sex) {
        this.name = name;
        this.sex = sex;
    }
    Person.prototype.age = function () {  //在Person的原型上定义一个age方法
        return '20';
    };
    var person1 = new Person('小明', '男');
    var person2 = new Person('小红', '女');
    console.log(person1.name);  //小明
    console.log(person2.name);  //小红
    console.log(person1.age === person2.age)  //true  *此处当person1和peoson2在Person构造函数中寻找age,若没有,则会向Person的原型上找,若还是没有,就继续上它的原型上找,直到到了null上为止。

以上方法的执行过程用以下图表示:

猜你喜欢

转载自blog.csdn.net/aiyawei123/article/details/81508117