(原型)继承 | 对象关联

作者: 姚屹晨 | 来源:发表于2017-09-16 08:28 被阅读43次

    该笔记参考自《你不知道的JavaScript上卷》

    一.(原型)继承

    1.检查"类"关系
    • 假设现在有个对象a,如果寻找对象a委托的对象呢?(假设存在)

    ①方法一:instanceof

    function Foo(){}
    var a = new Foo();
    //在a的整条[[Prototype]]链中是否存在Foo.prototype的对象?
    a instanceof Foo;
    >>>true
    
    • 该方法有个局限性:

    只能处理对象(a)和函数(带prototype引用的Foo)之间的关系。

    ②方法二:isPrototypeOf()方法

    function Foo(){}
    var a = new Foo();
    //Foo.prototype是否在a的[[Prototype]]链中
    Foo.prototype.isPrototypeOf(a);
    >>>true
    

    只需要两个对象就可判断它们之间的联系:

    //b是否出现在c的[[Prototype]]链中?
    b.isPrototypeOf(c);
    

    ③方法三:__proto__([bunder]笨蛋proto),在ES6之前并不是标准。

    function Foo(){}
    var a = new Foo();
    a.__proto__ === Foo.prototype;
    >>>true
    
    • __proto__并不存在于你正在使用的对象中(a),实际上,它和其他的常用函数(toSring()isPrototypeOf()等)一样,存在于内置的Object.prototype中。(它们都是不可枚举的)

    ④如何直接获取一个对象的[[Prototype]]链,ES5中的方法:

    function Foo(){}
    var a = new Foo();
    Object.getPrototypeOf(a) === Foo.prototype;
    >>>true
    

    二.对象关联

    1.[[Prototype]]机制就是存在于对象中的一个内部链接。
    2.那这个内部链有什么用?
    • 如果在对象上没有找到需要的属性或者方法引用,引擎就会继续在[[Prototype]]关联的对象上继续查找。
    3.[[Prototype]]机制的意义到底是什么?
    var foo = {
        fun: function(){
            console.log('Tell me something interesting.');
        }
    };
    var bar = Object.create(foo);
    bar.fun();
    >>>Tell me something interesting.
    

    Object.create()方法会创建一个新对象(bar)并把它关联到我们指定的对象(foo),这样以来,我们既可以充分发挥[[Prototype]]的威力(委托),又避免了不必要的麻烦(如:使用new的构造函数调用回生成prototypeconstructor引用)。

    4.Object.create(null);是什么情况?

    Object.create(null)会创建一个拥有空[[Prototype]]链接的对象,这个对象无法委托。由于这个对象没有原型链,所有instanceof操作符无法进行判断,总是返回false。这些特殊的空[[Prototype]]对象通常被称作"字典",它们完全不会受到原型链的干扰,因此非常适合用来储存数据。

    5.Object.create()是在ES5中新增的函数,那么怎么兼容ES5之前的环境?
    • Object.create()polyfill代码
    var foo = {
        fun: function(){
            console.log('Tell me something interesting.');
        }
    };
    Object.create2 = function(o){
        function F(){}
        F.prototype = o;
        return new F();
    };
    var bar = Object.create2(foo);
    bar.fun();
    >>>Tell me something interesting.
    
    6.直接委托和间接委托

    ①直接委托

    var anotherObject = {
        cool: function(){
            console.log('cool!');
        }
    };
    var myObject = Object.create(anotherObject);
    myObject.cool();
    >>>cool!
    

    ②间接委托

    var anotherObject = {
        cool: function(){
            console.log('cool!');
        }
    };
    var myObject = Object.create(anotherObject);
    myObject.doCool = function(){
        //内部委托
        this.cool();
    };
    myObject.doCool();
    >>>cool!
    
    • 间接委托的优点:层次更加清晰,同时仍能发挥[[Prototype]]关联的威力。

    三.小结

    1.如果要访问对象中并不存在的一个属性,[[Get]]操作就会查找对象内部[[Prototype]]关联的对象。这个关联关系实际上定义了一条"原型链",在查找属性时会对它进行遍历。

    2.JavaScript机制中的一个核心:不会复制,对象之间是通过内部的[[Prototype]]链关联的。

    3.对象之间的关系不是复制而是委托

    4.委托行为意味着某些对象在找不到属性或方法引用时,会把这个请求委托给另一个对象。

    相关文章

      网友评论

        本文标题:(原型)继承 | 对象关联

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