美文网首页
对象、原型、原型链、继承

对象、原型、原型链、继承

作者: 黑色的五叶草 | 来源:发表于2018-04-04 18:43 被阅读0次

    一、对象

    1. 对象(object)是某一个类(class)的实例(instance)
    • 类可以理解成模具
    • 对象可以理解成模具开发的产品
    • 对象的另一个特性就是封装:把细节隐藏掉,想要修改对象的属性需要通过它提供的方法去访问
            //用一个构造函数Fn生成了一个对象p; 对象p继承自构造函数Fn()
            function Fn(){
                console.log('name:Ceaser');
            }
            //通过类Fn(),生成属于这个类型的对象p
            //一个函数通过new操作符,可以让一个函数作为构造函数生成一个对象
            var p = new Fn();
            typeof p;  //object
            //所以这个对象p就是这个类的实例
            p instanceof Fn;  //true p是Fn的实例
    
            //p1和p2作为两个不同的新实例(创建了不同的副本),对类(属性的值)做修改互不影响
            function Fn(){
                this.name = 'hunger';
                this.age = 18;
            }
    
            var p1 = new Fn();
            var p2 = new Fn();
            p1.name = 'velley';
            console.log(p2);  //hunger 
    
            //根据参数需要把参数设置为变量
            function Fn(name, age){
                this.name = name;
                this.age = age;
            }
    
            var p1 = new Fn('hunger', 21);
            var p2 = new Fn('velley', 14);
    
            //调用对象的方法
            function Fn(name, age){
                this.name = name;
                this.age = age;
                this.say = function(){
                    console.log(this.name + '说: 我' + this.age + '岁了。');
                }
            }
    
            var p1 = new Fn('hunger', 21);
            var p2 = new Fn('velley', 14);
            p1.say();  //hunger说: 我21岁了。
            p2.say();  //velley说: 我14岁了。
    
            //注意:不使用new,p1为undefined  28.24-31.05
            function Fn(name, age){
                this.name = name;
                this.age = age;
                this.say = function(){
                    console.log(this.name + '说: 我' + this.age + '岁了。');
                }
            }
    
            var p1 = Fn('hunger', 21);
            var p2 = new Fn('velley', 14);
            console.log(p1);  //undefined
    

    二、原型

    • 构造函数Person中存在属性prototype,属性prototype指向原型对象Prototype
      原型对象Propotype包括:构造器constructor(指向构造函数Person) 和 原型属性_ proto_ 以及 自己定义的方法或属性,
      当通过new方法创建构造函数Person的实例后得到对象p1,实例的_ proto_指向它的创造者Person的整个原型Propotype
      此时对象p1包括:name:hunger、age:21、以及继承自p1的原型属性_ proto_
            function Person(name, age){
                this.name = name;
                this.age = age;
                this.say = function(){
                    console.log(this.name + '说: 我' + this.age + '岁了。');
                }
            }
    
            var p1 = new Person('hunger', 21);
    
    • 原型对象是对象实例的公共空间。
      可以通过对象实例访问保存再原型对象中的值,但不能通过对象实例重写原型中的值
            function Person(name, age) {
                this.name = name;
                this.age = age;
                this.say = function () {
                    console.log(this.name + '说: 我' + this.age + '岁了。');
                }
            }
            Person.prototype = {
                friend: 'Cherry'
            }
    
            var p1 = new Person('hunger', 21);
            p1.friend = 'Neco';
            console.log(p1.friend);  //Neco
    
            var p2 = new Person('Danee', 22);
            console.log(p2.friend);  //Cherry
    
    Person对象的_proto_ 与 Prototype原型对象的_proto_ 指向Object对象 原型

    三、原型链

    • 对象实例p1访问属性时先从继承来的在构造函数Person的属性中查找,查找不到时再从构造函数Person的原型对象Prototype中查找


      原型链
    • 调用p2.name,对象实例p2没有name属性,此时要从原型上查找。得到hello
      原型链
    • 深入:

    _ proto_指向构造它的函数的原型对象,prototype指向它自身的函数的原型对象

    任何对象都是被创建出来的,对象内部都存在原型属性_proto_,_proto_保存着构造它的原型对象
    对象Person里面有属性prototype,证明Person本身是一个对象(函数也是一种对象),所以对象Person内部也存在原型属性_proto_
    原型对象Prototype也存在属性_proto_
    

    Object在JS中本身是一个函数function(){ [native code] }new Object才是创建一个对象Object{}
    任何对象都是由Object函数创建的(即new Object方式)
    Object.prototype === Person.prototype._proto_返回true证明原型对象Prototype的创建者是Object。因为原型对象Prototype的原型属性_ proto_指向Object的原型对象Prototype
    由此证明:原型对象Prototype的创建者是构造函数Object

            function Person(name) {
                this.name = name;
            }
            Person.prototype = {
                sayName: function(){
                    console.log('My name is: ' + this.name);
                }
            }
    
            var p1 = new Person('hunger');
            var p2 = new Person('danee');
            p1.sayName();
    
    image.png
    原型对象只有一个 [[prototype]] 正常的是隐藏的 访问不到,浏览器为了让你访问到,弄了个__proto__属性
    任何一个函数都拥有prototype,任何一个对象都拥有_ proto_
    函数中的prototype是创建时就有的
    对象中的_ proto_是对象的创造者(即构造函数中的prototype)
    因为对象都是由Object函数创建的,所以对象的属性_ proto_指向函数的prototype
    上例:
    Person.prototype.__proto__ === Object.prototype
    p1.__proto__ === Person.prototype
    image.png
    image.png
    原型链

    四、基本包装类型

            var str = 'hellow';
            等同于
            var str = new String('hellow');
    
    基本包装类型
    image.png

    四、继承

            function Cake(name, size){
                console.log(this);
                this.name = name;
                this.size = size;
            }
            Cake.prototype.sayName = function(){
                console.log('I am :' + this.name);
            }
            Cake.prototype.saySize = function(){
                console.log('My size is' + this.size);
            }
    
            //在函数MilkCake的作用域里执行Cake函数(此时MilkCake取得了Cake的属性)
            function MilkCake(name, size, taste){
                console.log(this);
                Cake.apply(this, [name, size]);
                this.taste = taste;
            }
    
            //创建一个Cake的对象实例指向 MilkCake的原型对象(此时MilkCake继承了Cake的属性及原型对象)
            MilkCake.prototype = new Cake();
            //将MilkCake原型对象的构造器指向MilkCake函数
            MilkCake.prototype.constructor = MilkCake;
    
            var Cake1 = new MilkCake('牛奶蛋糕', 16, '甜');
            console.log(Cake1);
    

    constructor返回创建实例对象的构造函数的引用,所有对象都会从它的原型对象上继承一个constructor属性

    image.png
    image.png
    • 继承原型函数方法(Es5简便方法)
            function inherit(superType, subType){
                //拷贝一份父函数的原型对象
                var _prototype =  Object.create(superType.prototype);
                //将拷贝原型对象的构造器指向子函数
                _prototype.constructor = subType;
                //将拷贝的原型对象指向子函数的prototype属性
                subType.prototype = _prototype;
            }
            inherit(superType, subType);
    
    image.png

    相关文章

      网友评论

          本文标题:对象、原型、原型链、继承

          本文链接:https://www.haomeiwen.com/subject/jtrlhftx.html