Javascript的原型链与面向对象编程

        js中我们写一个方法,为了后续的代码都能够公用这些方法。我们将这些方法放到原型链上

chrome上有一个专有的属性叫_prop_  可以看到挂载在原型链上的方法:

Javascript的原型链与面向对象编程_第1张图片

比如我们常用的toString,就是挂载在原型链的顶端也就是Obeject.proptype上的方法。


我们要实现继承首先要在父类上的proptype上挂载方法。代码如下:

function Employee () {}

Employee.prototype.firstName = "Abhijit";
Employee.prototype.lastName = "Patel";
Employee.prototype.startDate = new Date();
Employee.prototype.fullName = function () {
console.log (this.firstName + " " + this.lastName); 
};

var abhijit = new Employee () //
console.log(abhijit.fullName()); // Abhijit Patel
console.log(abhijit.lastName); // Patel



这里我们挂载了3个属性   和一个方法。

这样所有new 出来的对象都有了你定义在圆形链上的方法了。


if (typeof Object.create !== 'function') {
    Object.create = function (o) {
        function F() {
        }
        F.prototype = o;
        return new F();
    };
}
Admin.prototype = Object.create(Employee.prototype);
Admin.constructor = Employee;
console.log(Employee.fullName());
console.log(Admin.fullName());


Admin 的proptype也可以挂载方法:

Admin.prototype = {
    constructor: User,
    saveScore:function (theScoreToAdd)  {
        this.quizScores.push(theScoreToAdd)
    },
    showNameAndScores:function ()  {
        var scores = this.quizScores.length > 0 ? this.quizScores.join(",") : "No Scores Yet";
        return this.name + " Scores: " + scores;
    },
    changeEmail:function (newEmail)  {
        this.email = newEmail;
        return "New Email Saved: " + this.email;
    }
}



通过object.create()方法会创建一个新的对象,而不会造成 admin 和 employee的原型相互影响。   

obeject.create方法  是es6加入的方法,目前浏览器支持不是很完善,大家可以通过babel体验这个功能,当然不用babel也没有关系。  通过刚才判断,如果没有create方法,那么我们自己写一个create方法挂载到上面就可以了,代码也简单。

下面是我在chrome上使用object.create()的结果 , 可以清晰的看到创建的对象的结构是怎样的

Javascript的原型链与面向对象编程_第2张图片


根据传入的对象return new construtor();


总之实现继承的方法就是:  

1.原型赋值

2.构造器重写  (如果不重写的话,还是使用Admin构造器  会造成一些问题)

Admin.prototype = Object.create(Employee.prototype);
Admin.constructor = Employee;


最后说一下比较容易混淆的两个概念: proptype  和__propto__


首先来说说prototype属性,不像每个对象都有__proto__属性来标识自己所继承的原型,只有函数才有prototype属性。

为什么只有函数才有prototype属性?ES规范就这么定的。

开玩笑了,其实函数在JS中真的很特殊,是所谓的一等公民。JS不像其它面向对象的语言,它没有类(class,ES6引进了这个关键字,但更多是语法糖)的概念。JS通过函数来模拟类。

当你创建函数时,JS会为这个函数自动添加prototype属性,值是空对象。而一旦你把这个函数当作构造函数(constructor)调用(即通过new关键字调用),那么JS就会帮你创建该构造函数的实例,实例继承构造函数prototype的所有属性和方法(实例通过设置自己的__proto__指向承构造函数的prototype来实现这种继承)。

友情链接:

https://github.com/creeperyang/blog/issues/9

你可能感兴趣的:(JavaScript,oop,原型链,_proto_,proptype)