(原型)继承 | 对象关联

该笔记参考自《你不知道的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.jianshu.com/p/2e822fc8405f
    本文转自网络文章,转载此文章仅为分享知识,如有侵权,请联系博主进行删除。
点赞