什么是原型、原型链、继承?

    xiaoxiao2022-07-06  211

    prototype的概念: 每一个构造函数都有一个prototype属性,这个属性会在生成实例的时候,成为实例对象的原型对象。javascript的每个对象都继承另一个对象,后者称为“原型”(prototype)对象。 一方面,任何一个对象,都可以充当其他对象的原型;另一方面,由于原型对象也是对象,所以它也有自己的原型。null也可以充当原型,区别在于它没有自己的原型对象。 JavaScript 继承机制的设计就是,原型的所有属性和方法,都能被子对象共享。 下面,先看怎么为对象指定原型。 每一个构造函数都有一个prototype属性,这个属性会在生成实例的时候,成为实例对象的原型对象

    function Animal(name){ this.name = name; } Animal.protoype.color = 'white'; var cat1 = new Animal('小猫'); var cat2 = new Animal('大猫'); cat1.color //'white' cat2.color //'white'

    上面代码中,构造函数Animal的prototype对象,就是实例对象cat1和cat2的原型对象。原型对象上添加一个color属性,结果,实例对象都继承了该属性。

    原型对象的属性不是实例对象自身的属性。只要修改原型对象,变动就立刻回体现在所有实例对象上添加一个color属性。结果实例对象继承了还属性。 prototype原型: 大部分面向对象的编程语言,都以“类”(class)为基础,实现对象的继承。JavaScript 语言不是如此,它的对象继承以“原型对象”(prototype)为基础。 JavaScript 通过构造函数生成新对象,因此构造函数可以视为对象的模板。实例对象的属性和方法,可以定义在构造函数内部。

    function Cat(name, color){ this.name = name; this.color = color; this.meow = function () { console.log('喵喵'); }; } var cat1 = new Cat('小猫', '白色'); var cat2 = new Cat('大猫','灰色'); cat1.meow === cat2.meow //false

    上面代码中,Cat函数是一个构造函数,函数内部定义了name属性和color属性,所有实例对象(上例是cat1)都会生成这两个属性,即这两个属性会定义在实例对象上面。 通过构造函数为实例对象定义属性,虽然很方便,但是有一个缺点。同一个构造函数的多个实例之间,无法共享属性,从而造成对系统资源的浪费。 cat1和cat2是同一个构造函数的两个实例,它们都具有meow方法。由于meow方法是生成在每个实例对象上面,所以两个实例就生成了两次。也就是说,每新建一个实例,就会新建一个meow方法。这既没有必要,又浪费系统资源,因为所有meow方法都是同样的行为,完全应该共享。 这个问题的解决方法,就是 JavaScript 的原型对象(prototype)。

    总结原型对象的作用,就是定义所有实例对象共享的属性和方法。这也是它被称为原型对象的原因,而实例对象可以是作为从原型对象衍生出来的子对象

    构造函数继承: 本质是在子类中,调用父类构造函数,从而让子类拥有弗雷的属性和方法 call/apply继承: 原型链继承: 原型链 对象的属性和方法,有可能定义在自身,也有可能定义在它的原型对象。由于原型本身也是对象,又有自己的原型,所以形成了一条原型链(prototype chain)。 “原型链”的作用是,读取对象的某个属性时,JavaScript 引擎先寻找对象本身的属性,如果找不到,就到它的原型去找,如果还是找不到,就到原型的原型去找。如果直到最顶层的Object.prototype还是找不到,则返回undefined。 举例来说,如果让某个函数的prototype属性指向一个数组,就意味着该函数可以当作数组的构造函数,因为它生成的实例对象都可以通过prototype属性调用数组方法

    var MyArray = function () { };//MyArray.prototype = new Array; var mine = new MyArray(); mine.push(1, 2, 3); mine.length//

    上面代码中,mine是构造函数MyArray的实例对象,由于MyArray的prototype属性指向一个数组实例,使得mine可以调用数组方法(这些方法定义在数组实例的prototype对象上面)。

    原型链继承就是利用这个原理 将一个构造函数的原型指向另一个构造函数的实例对象来实现继承。

    function Box() { //Box构造 this.name = 'Lee'; } function Desk() { //Desk构造 this.age = 100; } Desk.prototype = new Box(); //Desc继承了Box,通过原型,形成链条 var desk = new Desk(); alert(desk.age); alert(desk.name); //得到被继承的属性

    混合继承: 结合使用原型链与构造很熟继承

    function Box(age) { this.name = 'Lee' this.age = age; } Box.prototype.run = function () { return this.name + this.age; }; function Desk(age) { Box.call(this, age); //构造函数继承继承了 name 和age 属性 } Desk.prototype = new Box(); //原型链继承 run方法 var desk = new Desk(100); alert(desk.run());
    最新回复(0)