原型、原型链、继承

原型

  本文中用到的例子:

function Human( name, age){
// 写在构造函数种的属性都是私有的属性
this.name = name;
this.age = age;
}

  

所有的函数都会有一个默认的属性 prototype 。该属性指向了另外一个对象,叫做原型。


(1)、该对象中有一个 constructor 属性,constructor 属性指向了 本身。

(2)、每个对象中又有一个自带的 __ proto__ 属性,该属性指向了 当前实例所属类的原型。如,当前Human原型上的 __ proto__ 属性就指向了 Object 。

  两句话总结:

var person = new Human( 'ace', 18);

Human.prototype.constructor == Human;
person.__proto__ = Human .prototype;

  但是这样写在构造函数中的属性都是私有属性,要想实现公有属性,可以将属性定义在原型上面。如下:


Human.prototype. eat = function(){}

  这样写的话,每当 new 出一个新的实例时,就会带着 eat 这个方法了。

原型链

    每一个对象都会在内部初始化一个属性,就是 prototype ,当我们访问一个对象的属性的时候,如果这个对象的内部不存在这个属性,那么就回去 prototype 里面去找这个属性,如果 prototype 上还是没有这个属性,就会往上去自己的 prototype 上找这个属性,然后一直找下去,这条路径就是我们所说的原型链

继承

父类:


function Parent() {}

子类:


function Child() {}



总共有 6 种继承方法:

(1)、原型继承

 =>   子类的原型指向父类的实例。    


Child.prototype = new Parent()

父类的 公有属性 和 私有属性 都是子类的 公有属性。

(2)、call继承

=>   在子类的构造函数中执行  Parent.call(this)

function Child() {
Parent. call( this);
}
父类的 私有属性 变成子类的 私有属性。

(3)、冒充对象继承

=>    在子类的构造函数中遍历父类的每一个实例,并把所有遍历出的属性和方法分别添加给子类的实例。

function Child() {
var parent = new Parent();
for( var key in parent){
this[key] = parent[key];
}
}
父类的 私有属性 都是子类的 私有属性。

(4)、组合继承:原型继承 + call继承

function Child() {
Parent. call( this);
}
Child.prototype = new Parent()
父类的 公有属性 和 私有属性 都是子类的 公有属性。父类的 私有属性 变成子类的 私有属性。

(5)、中间件继承

=>   子类原型上的 __proto__ 指向父类的原型


Child.prototype.__proto__ = Parent.prototype

父类的 公有属性 都是子类的 公有属性。

(6)、Object.create(obj)


Child.prototype = Object. create( Parent.prototype);

PS: Object.create() 创建一个对象。

有两个参数,第一个参数是一个对象,表示要继承的对象。第二个参数也是一个对象,表示对创建的新的对象进行怎样的初始化。

但是要考虑该方法的兼容性:

if( typeof Object.create != 'function'){
Object. create = function( obj) {
function Class() {}
Class.prototype = obj;
return new Class();
}
}

你可能感兴趣的:(js,js,原型)